先来看这么一段代码
String str1 = "123";
String str2 = "123";
System.out.println(str1 == str2);
String str3 = new String("123");
System.out.println(str1 == str3);
str3 = str3.intern();
System.out.println(str1 == str3);
输出的是true,false,true。
当使用String str = "abc" 的形式创建对象的时候,会首先在字符串池中寻找是否存在abc,如果存在则返回它的引用;如果没有,则将abc添加到字符串池中,然后返回引用。
但当用new创建对象的时候则是直接创建新的对象,不去检查字符串池,所以str1与str3两者指向内存地址不同。
如果要主动扩充字符串池,可以使用String.intern(),该方法会在字符串池中查找与调用该方法的字符串有相同Unicode码的字符串,如果有,则返回其引用;如果没有,则将该字符串添加到字符串池中,并返回其引用。代码中的最后两行就是将str3添加到字符串常量中,并赋给str3,所以str1与str3又指向相同对象了。
再来看下面代码
Integer a = 12;
Integer b = a;
a= 3;
System.out.println(a);
System.out.println(b);
最后输出的是 3,12。
执行完 b = a ,是将a的引用传给了b。我原本以为当执行了 a = 3 后,b中的值也会发生改变,但并不是如此。
在这里,有一个IntegerCache缓存类,它提前缓存好了-127 到 128,所以当你 Integer a = 12; 其实在这之前就已经存在12的实例了,只是将它的引用赋给了 a,所以下面一句 a = 3 只是改变了a 的引用,所当然不会影响到 b 咯。