String s4 = new String("Hello"); // String object
String s5 = new String("Hello"); // String object
System.out.println("s1==s2:"+(s1==s2));
System.out.println("s1==s4:"+(s1==s4));
System.out.println("s3==s4:"+(s3==s4));
System.out.println("s4==s5:"+(s4==s5));
结果为:
s1==s2:true
s1==s4:false
s3==s4:false
s4==s5:false
s4==s5:false
这个结果好理解,s3与s4指向内存中的两个不同的对象(虽然对象的内容是相同的)
s1==s3:false
s1==s2:true
s3==s4:false
这三个结果与String的特殊之处有关。
请看下图:
上图已经一目了然了,s1、s2、s3、s4、s5这五个引用所指对象的内容虽然都为"Hello",但在内存中的位置是不一样的。
s1、s2、s3指向常量池中的"Hello"字符串,而s4、s5指向堆中的两个对象。
java中的常量池技术是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),
则在需要重复重复创建相等变量时节省了很多时间。
常量池其实也就是一个内存空间,不同于使用new关键字创建的对象所在的堆空间。
java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。
下一篇将深入分析equals()与hashcode()的关系。
摘自 JieTouLangRen的专栏