Java 中關於常量池與快取類的一點理解
阿新 • • 發佈:2019-02-07
先來看這麼一段程式碼
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 咯。
最後謝謝論壇大佬們的幫助。