先來(lái)看這么一段代碼
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。
當(dāng)使用String str = "abc" 的形式創(chuàng)建對(duì)象的時(shí)候,會(huì)首先在字符串池中尋找是否存在abc,如果存在則返回它的引用;如果沒有,則將abc添加到字符串池中,然后返回引用。
但當(dāng)用new創(chuàng)建對(duì)象的時(shí)候則是直接創(chuàng)建新的對(duì)象,不去檢查字符串池,所以str1與str3兩者指向內(nèi)存地址不同。
如果要主動(dòng)擴(kuò)充字符串池,可以使用String.intern(),該方法會(huì)在字符串池中查找與調(diào)用該方法的字符串有相同Unicode碼的字符串,如果有,則返回其引用;如果沒有,則將該字符串添加到字符串池中,并返回其引用。代碼中的最后兩行就是將str3添加到字符串常量中,并賦給str3,所以str1與str3又指向相同對(duì)象了。
再來(lái)看下面代碼
Integer a = 12;
Integer b = a;
a= 3;
System.out.println(a);
System.out.println(b);
最后輸出的是 3,12。
執(zhí)行完 b = a ,是將a的引用傳給了b。我原本以為當(dāng)執(zhí)行了 a = 3 后,b中的值也會(huì)發(fā)生改變,但并不是如此。
在這里,有一個(gè)IntegerCache緩存類,它提前緩存好了-127 到 128,所以當(dāng)你 Integer a = 12; 其實(shí)在這之前就已經(jīng)存在12的實(shí)例了,只是將它的引用賦給了 a,所以下面一句 a = 3 只是改變了a 的引用,所當(dāng)然不會(huì)影響到 b 咯。