![](/img/trans.png)
[英]Why does new String() + new String() return different results under JDK8
[英]Why does String.intern() return different results under JDK8 and JDK9?
以下代碼在JDK8和JDK9下具有不同的結果。
public static void main(String[] args) {
String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2);
String s3 = new String("1") + new String("1");
//String s3 = "1" + "1";
s3.intern();
String s4 = "11";
System.out.println(s3 == s4);
System.out.println(s3.equals(s4));
}
在JDK8(“1.8.0_172”版本)下,代碼返回:
false true true
但在JDK9(“9.0.1”版本)下,代碼返回:
false false true
我檢查了兩個JDK版本,它們是正確的。為什么代碼有不同的結果? 我的程序有什么問題嗎?
結果取決於在調用s3.intern()
之前String“11”是否已經在String池中。
如果不是, s3.intern()
會將s3
添加到池中並返回s3
。 在那種情況下, s4
也將被賦予規范表示“11”,因為它是用字符串文字初始化的。 因此s3==s4
將是true
。
如果是, s3.intern()
將返回規范表示“11”,這與s3
不是同一個實例。 因此s3==s4
將是false
。
我沒有JDK9版本來測試你的代碼,但是如果這是你得到的輸出,它暗示JDK9源代碼中某處在你的main
之前執行,出現了“11” String
文字,它增加了池中的String
。
JDK8中的情況並非如此。
在兩種情況下,使用“1” String
測試都會給出false
,因為在將String
“1”傳遞給new String("1")
的String
構造函數時,會將String
“1”添加到池中。 因此, s.intern()
不會將s
引用的String
添加到池中,並且String s2 = "1";
是一個與s
不同的例子。
當試圖理解這種行為時, intern
的Javadoc很方便:
String java.lang.String.intern()
返回字符串對象的規范表示。
最初為空的字符串池由String類私有維護。
調用實習方法時, 如果池已經包含等於此字符串對象的字符串(由equals(Object)方法確定),則返回池中的字符串。 否則,將此String對象添加到池中,並返回對此String對象的引用。
...
所有文字字符串和字符串值常量表達式都是實體。
伊蘭的答案很接近。 正如他所確定的那樣, 當字符串文字被實習時的關鍵問題。
我有一個很好的權限,一些最近的JVM懶惰地執行String文字的實習,它發生在第一次運行時使用文字之前。 告訴此事的人說這是/是新行為。
所以實際的解釋似乎是Java 9是在引入這種新的“懶惰”行為時,這解釋了OP觀察到的Java 8和Java 9之間的區別。
(我將試着看看OpenJDK源代碼中發生了什么......)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.