看看下面程式碼的輸出是什麼:
public class MemoeryManager { public static void main(String[] args){ String a="a"; String b="b"; String ab="ab"; final String af="a"; String plus=a+"b"; String result=af+"b"; System.out.println((a+b)==ab); System.out.println("a"+"b"==ab); System.out.println(result==ab); System.out.println(plus==ab); System.out.println(plus.intern()==ab); } }
輸出是:
false
true
true
false
true
解釋:
- (a+b)==ab
a+b是兩個變數相加,需要到執行時才能確定其值,到執行時後JVM會為兩者相加後產生一個新的物件,因此a+b==ab的結果為false。
● (“a”+”b”)==ab
“a”+”b”是常量,在編譯時JVM已經將其變為”ab”字串了,而ab=”ab”也是常量,這兩者在常量池即為同一地址,因此(“a”+”b”)==ab為true。
● result==ab
result=afinal+”b”,afinal是個final的變數, result在編譯時也已經被轉變為了”ab”,和”ab”在常量池中同樣為同一地址,因此result==ab為true。
● plus=ab
plus和a+b的情況是相同的,因此plus==ab為false。
● plus.intern()==ab
這裡的不同點在於呼叫了plus.intern()方法,這個方法的作用是獲取plus指向的常量池地址,因此plus.intern()==ab為true。
String的intern()方法是一個本地方法,定義為public native String intern(); intern()方法的價值在於讓開發者能將注意力集中到String池上。當呼叫 intern 方法時,如果池已經包含一個等於此 String 物件的字串(該物件由 equals(Object) 方法確定),則返回池中的字串。否則,將此 String 物件新增到池中,並且返回此 String 物件的引用。
(也就說,一個String物件可能是指向堆的,也可能是指向池的,並且在執行時生成的String,貌似都指向堆?這個不能肯定,以後確定。)