首先我們應該清楚的是JDK1.6和JDK1.7中String類的intern方法還是有差別的:
JDK1.6中的intern:
調用intern方法的時候首先會去常量池中查看是否存在與當前String值相同的值,如果存在的話,則直接返回常量池中這個String值的引用;如果不存在的話,則會將原先堆中的該字符串拷貝一份到常量池中。
JDK1.7中的intern:
調用intern方法的時候首先會去常量池中查看是否存在與當前String值相同的值,如果存在的話,則直接返回常量池中這個String值的引用;如果不存在的話,則只會將原先堆中該字符串的引用放置在常量池中,并不會將拷貝整個字符串到常量池中。
這也就說明,JDK1.6和JDK1.7對于常量池中不存在此字符串的情況處理不同。
下面通過實例來進行驗證和解釋:
實例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static void main(String[] args) { String str = "str" + new String( "01" );① str.intern();② String str1 = "str01" ;③ System.out.println(str == str1); String str2 = new String( "str01" );④ str2.intern();⑤ String str3 = "str01" ;⑥ System.out.println(str2 == str3); String str4 = "str01" ;⑦ String str5 = new String( "str" )+ new String( "01" );⑧ str5.intern();⑨ System.out.println(str4 == str5); |
在JDK1.6下輸出結果是:
false
false
false
解釋:
①執行時會在堆內存創建一個值為"str01"的字符串對象str,同時在常量池創建一個"str"以及"01"常量;
②執行時會首先去常量池中查看是否存在一個值為"str01"的常量,發現不存在,JDK1.6的做法就是將該字符串"str01"在常量池中也生成一份;
③執行時會在常量池中創建一個"str01"對象,發現已經存在,因而不會新建;
第一個輸出false的原因是:str指向的是堆內存的"str01",而str1指向的是常量池中的"str01";
④執行時會在堆內存創建一個值為"str01"的字符串對象str2,同時在常量池中創建一個值為"str01"的常量;
⑤執行時會首先去常量池中查看是否存在值為"str01"的常量,發現存在,則直接返回這個常量引用;
⑥執行時會在常量池中創建一個值為"str01"的常量,如果發現已經存在,則不會創建;
第二個輸出false的原因是:str2指向的是堆內存的"str01",而str3指向的是常量池中的"str01";
⑦執行時會在常量池創建一個值為"str01"的常量;
⑧執行時會在堆內存創建一個值為"str01"的字符串對象str5,同時在常量池創建一個"str"以及"01"常量;
⑨執行時會去常量池查看是否存在值為"str01"的常量,發現存在則直接返回這個常量引用;
第三個輸出false的原因是:str5指向的是堆內存的"str01",而str4指向的是常量池中的"str01";
在JDK1.7下輸出結果是:
true
false
false
解釋:
發現只有第一個輸出結果不一樣,所以我們只解釋第一個的原因:
①執行時會在堆內存創建一個值為"str01"的字符串對象str,同時在常量池創建一個"str"以及"01"常量;(這點和JDK1.6沒什么區別)
②執行時會首先去常量池中查看是否存在一個值為"str01"的常量,發現不存在,JDK1.7的做法就是將堆內存中"str01"的引用復制到了常量池中;
③執行時會在常量池中創建一個"str01"對象,發現已經存在,因而不會新建;
那么此時的str和str1都將指向的是堆內存中的"str01"的值,所以兩者相等;
以上就是對JDK1.6和JDK1.7中String類的intern方法的對比,是有差別的,有需要的朋友可以參考下。