欢迎选择我的课程,让我们一起见证您的进步~~
上面的程式碼, 我用 JDK6 和 JDK7 分別運行了一下, 結果如下:
JDK6: false, false JDK7: false, false
沒有如題主所說的是 true, false. 我想究其原因, 主要有兩點:
字串 "java" 比較特殊, 它在常數池中固定存在的
因此代碼
String str1 = new StringBuilder("ja").append("va").toString(); System.out.println(str1.intern() == str1);
str1.intern() 回傳的是常數池中的物件, 於是和堆上的 str1 就不是同一個物件了.
"python" 字串已經在程式碼中出現了, 因此會加入到常數池中.
第二部分的程式碼中, 因為出現了字面常數 "python", 因此它會添加到常數池中.而:
String str2 = new StringBuilder("python").append("").toString(); System.out.println(str2.intern() == str2);
為字串 "python" 新增了空字串 "", 因此相當於沒有新增的字串常數, 進而 str2.intern() 傳回的還是常數池中的物件.
其實上面的題目可以引申一下, 例如:
// 1 String str1 = new StringBuilder("ja").append("va1").toString(); System.out.println(str1.intern() == str1); // true // 2 String str2 = new StringBuilder("python").append("").toString(); System.out.println(str2.intern() == str2); // false
我只把第一部分的程式碼"StringBuilder("ja").append("va")" 改為"StringBuilder("ja").append("va1")". 這樣改動會有什麼不同的結果嗎?我們來看看在JDK6 和JDK7 下運行的結果吧:
JDK6: false, false JDK7: true, false
為什麼 JDK6 和 JDK7 的運行結果不一樣呢?其實這涉及到了不同的 JDK 對 intern() 方法的不同實現:在 JDK6 及以前的 JDK 中:
intern() 方法会把首次遇到的字符串实例 **复制** 到永久代中, 然后返回永久代中的实例.
而對於 JDK7 以及之上的JDK:
当遇到第一次出现的字符串时, intern() **不再复制实例**, 而是在常量池中记录首次出现的实例的引用, 并且 intern() 返回的是此实例引用.
根據 JDK6 和 JDK7 的 intern() 方法的區別, 我們就知道了例子:
在不同的JDK 回傳不同結果的原因了:在JDK6 中, "java1" 是第一次出現的字串常數, 因此會被複製到常數池中, intern() 方法傳回的是常數池中的物件, 因此與堆上的str1 就不等了.而在JDK7 中, "java1" 是第一次出現的字串常數, 但是intern() 方法僅僅是將這個物件的引用添加到常數池中,並沒有像JDK6 一樣拷貝一個新物件到常數池, 因此intern() 方法返回的引用其實還是和原來的str1 相等.
上面的程式碼, 我用 JDK6 和 JDK7 分別運行了一下, 結果如下:
沒有如題主所說的是 true, false. 我想究其原因, 主要有兩點:
字串 "java" 比較特殊, 它在常數池中固定存在的
因此代碼
str1.intern() 回傳的是常數池中的物件, 於是和堆上的 str1 就不是同一個物件了.
"python" 字串已經在程式碼中出現了, 因此會加入到常數池中.
第二部分的程式碼中, 因為出現了字面常數 "python", 因此它會添加到常數池中.
而:
為字串 "python" 新增了空字串 "", 因此相當於沒有新增的字串常數, 進而 str2.intern() 傳回的還是常數池中的物件.
其實上面的題目可以引申一下, 例如:
我只把第一部分的程式碼"StringBuilder("ja").append("va")" 改為"StringBuilder("ja").append("va1")". 這樣改動會有什麼不同的結果嗎?
我們來看看在JDK6 和JDK7 下運行的結果吧:
為什麼 JDK6 和 JDK7 的運行結果不一樣呢?
其實這涉及到了不同的 JDK 對 intern() 方法的不同實現:
在 JDK6 及以前的 JDK 中:
而對於 JDK7 以及之上的JDK:
根據 JDK6 和 JDK7 的 intern() 方法的區別, 我們就知道了例子:
在不同的JDK 回傳不同結果的原因了:
在JDK6 中, "java1" 是第一次出現的字串常數, 因此會被複製到常數池中, intern() 方法傳回的是常數池中的物件, 因此與堆上的str1 就不等了.
而在JDK7 中, "java1" 是第一次出現的字串常數, 但是intern() 方法僅僅是將這個物件的引用添加到常數池中,並沒有像JDK6 一樣拷貝一個新物件到常數池, 因此intern() 方法返回的引用其實還是和原來的str1 相等.