2010-12-06 69 views
0

的例子根據這篇文章ScjpTipLine-StringsLiterally我編碼一些例子,如:Understading字符串文字池

public static void main(String[] args) { 
    String literalString1 = "someString"; 
    String literalString2 = "someString"; 
    String string1 = new String("someString"); 
    System.out.println(literalString1 == literalString2); 
    System.out.println(literalString1 == string1); 
    try { 
     Field stringValue = String.class.getDeclaredField("value"); 
     stringValue.setAccessible(true); 
     char[] charValue = "someString".toCharArray(); 
     Arrays.fill(charValue, 'a'); 
     stringValue.set(literalString1, charValue); 
    } catch (Exception e) {} 

    System.out.println(literalString1); 
    System.out.println(literalString2); 
    System.out.println(string1); 
} 

的輸出中是預期:

true 
false 
aaaaaaaaaa 
aaaaaaaaaa 
someString 

,但如果更改略高於代碼更換線

char[] charValue = "someString".toCharArray(); 

char[] charValue = (char[]) stringValue.get(literalString1); 

true 
false 
aaaaaaaaaa 
aaaaaaaaaa 
aaaaaaaaaa 

這是自新的String意想不到的輸出( 「someString」); JVM有義務在運行時在堆上創建新的String對象,而不是使用字符串文字池中的literalString1literalString2

預先感謝

回答

1

這是因爲新的字符串( 「someString」)意想不到的輸出; JVM必須在運行時在堆上創建一個新的String對象

它有義務創建一個新的String對象,是的。

但是,一個String對象通常只是一個帶有幾個字段的頭文件和一個指向backing數組的指針。 JVM可以自由重用該支持陣列。

字符串應該是不可變的,如果你做了很多事情來嘗試和違反這種不變性,你不能保證它們將如何行爲。