1)加入.intern()方法
intern()方法的目的是当执行此方法的时候会在常量池创建此String的值,当另一个String定义的时候可以节省内存。
String s = new String("1");
s.intern();
String s1 = "1";
System.out.println(s == s1);
此时返回的是false:
定义s的时候会在堆中建s的引用并在常量池中新建值为“1”的常量,所以此时执行s.intern();其实是没有起作用的,当s1定义的时候指向常量池中的“1”,所以s的地址是堆中的,s1是常量池的,所以两者的引用地址不同。
2)特别说明的是这种情况
String s = new String("11") + new String("11");
s.intern();
String s1 = "1111";
System.out.println(s == s1);
此时返回的是true:
当定义s的时候是在堆中建立一个值为“1111”的引用而在常量池中新建的是“11”的常量,在执行intern()方法后在jdk1.7中为了节省内存,像s这种定义在常量池中存的是:s在堆中的引用地址值为“1111”的常量,所以当s1定义后去常量池中找到“1111”的时候地址是s的引用地址,所以s==s1为true,因为两者的引用地址是相同的。
(所以在进行String的判断时要使用.equals()方法哟
解释:第二张图,它是两个new string相加,这样它的对象的引用和常量池中的对象就不一样了,一个是“1111”,一个是“11”,所以为了节省空间,这种情况下常量池的“11”就不会存储,而是直接存储对“1111”的引用,而后面s1创建的时候还是直接拿已有的“1111”,所以二者就相等了,此时二者拿的都是对对象的引用,而上一张图一个是常量池对象,一个是对对象的引用,那就不同了,所以这是特殊情况。