簡體   English   中英

為什么Java編譯器不對數組進行實習?

[英]Why java compiler does not interns arrays?

考慮下面的代碼

String s1 = "testString";
String s2 = "testString";
if(s1 == s2)System.out.println("equals!");

它輸出等於!,(我知道編譯器對String進行了interning)

String[] s1 = {"testString","teststring2"};
String[] s2 = {"testString","teststring2"};
if(s1 == s2)System.out.println("equals!");

但是上面的代碼不起作用,為什么Java編譯器不對字符串數組進行實習?

原因是String是不可變的。 您必須創建新實例才能更改它。 因此,盡可能使用相同的實例來匹配字符串是安全的。 字符串是常量; 它們的值創建后無法更改。

數組有何不同? 您可以更改一個數組,只需將一個新值分配給其中一個字段即可。

s1[0] = "testString3"

如果編譯器對s1s2使用相同的實例,則將自動更改兩個數組。 那可能不是您想要做的。 這就是為什么數組沒有被實習的原因。

另請注意,字符串實習可能會受到限制,具體取決於編譯器,並且編譯器可能會選擇不對某些字符串進行實習,具體取決於存在的字符串數或字符串的長度。 有一個內部字符串表,該表由JVM選項+XX:StringTableSize=n控制,該選項確定用於存儲內部字符串的字符串表的大小。

當比較字符串時,最好使用equals函數。 無論如何,大多數實現都會先執行參考相等性檢查,然后再執行更昂貴的檢查。

編輯:

因此,實際上我聲稱內部存儲字符串已滿的說法似乎是錯誤的。 String.intern()方法的文檔表明,此函數將確保將字符串添加到唯一字符串池中。 意味着該池將無法充滿。 @Holger寫道,內部實現使用類似於某種結構的哈希圖。 這支持了這一主張。

因此,JVM將根據JLS§3.10.5將所有常量字符串存儲在內部哈希表中。

字符串文字始終引用類String的相同實例。 這是因為使用String.intern方法,對字符串文字(或更廣泛地說,是常量表達式值…的字符串)進行了“ interned”,以便共享唯一的實例。

話雖如此,請仍然習慣於字符串類的equals方法來檢查字符串是否相等。 該方法將利用以下事實:在執行更昂貴的長度和字符檢查之前,字符串可能是相同的引用,並且在這種情況下非常快速地完成。 始終最好使用此方法。 在將來的Java版本中,如何處理字符串的方式可能會也可能不會改變。 使用equals方法,您會很安全。

您不能僅將String數組與==進行比較,例如String。 實習生僅適用於String。 如果要比較字符串數組,請嘗試使用此Java,如何比較字符串和字符串數組

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM