2

我始終認爲,在Java這樣的表達式:是「someString」相當於新的String(「someString」)?在Java中

String tmp = "someString"; 

只是一些對

String tmp = new String("someString"); 

正如我最近反編譯我的Java應用程序類型的「語法糖」,我看到了所有用法的

public static final String SOME_IDENTIFIER = "SOME_VALUE"; 

在代碼中被替換的值只是靜態最終變量被剝離。

每次想要訪問靜態final時,是否不會實例化這個新的String?這怎麼可以被認爲是「編譯優化」?

+1

最可能的原因是國際。 –

回答

9

Java源文件中的字符串文字是interned,這意味着所有具有相同文本的文字將會解析爲相同的實例。

換句話說,"A" == "A"將是正確的。

創建一個新的String實例將繞過這個; "A" == new String("A")將不會成立。

+2

但是在兩種情況下equals()都會返回true。 (不要混淆初學者) – Puce

4
String tmp1 = "someString"; 
String tmp2 = new String("someString"); 
String tmp3 = "someString"; 

if(tmp1 == tmp2)/* will return false as both are different objects 
        stored at differnt location in heap */ 

if(tmp1.equals(tmp2))/* will return true as it will compare the values 
         not object reference */ 

if(tmp1 == tmp3)/* will return true. see string literals and they are interned. 
        brief about them is they are stored in pool in permgen till 
        java 6.They are stored as part of heap only in java 7 
        Every time u create string literal with same value , 
        it will refer from same location in pool instead of creating 
        object each time */ 
+0

使用/ *多行註釋*/:) –

+0

AFAIK字符串不再存儲在permgen中(Oracle Java SE 7),並且permgen將在Oracle Java SE 8中完全刪除。 – Puce

+0

@Puce你是對的。我在更新中提到過它 –

1

Java源代碼中的字符串存儲在.class文件的常量表中。加載類文件時,常量表中的所有字符串都將被禁用;唯一字符串被轉換爲對象實例。對它們的引用指的是實例化的實例,所以其他引用不會生成其他對象。

相關問題