2013-07-15 27 views

回答

1

Java字符串包含一個不可變的Unicode字符序列。與C/C++不同,其中字符串只是一個char數組,而Java String是類java.lang的一個對象。然而,Java String是特殊的。與普通類不同:

字符串與雙引號文本(如「Hello,world!」)形式的字符串字面值相關聯。您可以將字符串直接分配給String變量,而不是調用構造函數來創建String實例。

String s1 = "Hello";    // String literal 
String s2 = "Hello";    // String literal 
String s3 = s1;     // same reference 
String s4 = new String("Hello"); // String object 
String s5 = new String("Hello"); // String object 

How can a string be initialized using " "?

+0

你能告訴我們如何「你好」將在字符串池中實習?將不會調用構造函數嗎? – NINCOMPOOP

+2

這是關於如何初始化字符串變量的討論,而不是如何在運行時將字符串文字轉換爲字符串實例,正如我所想,這是此問題的意圖。 – SpaceTrucker

11

當JVM加載包含文字

String str = "hello"; 

字符串,讀取字符串從類文件中文字以UTF-8編碼,並從它

創建字符數組的一類
char[] a = {'h', 'e', 'l', 'l', 'o'}; 

th烯它使用字符串從這個字符數組創建一個字符串對象(CHAR [])構造

new String(a) 

然後JVM放在字符串池中的字符串對象,並在參考該字符串對象分配給str變量。

+0

+1很好,你在哪裏找到這個信息。我應該刪除我的答案,因爲我錯了沒有構造函數被調用。 –

+0

不過,人們會認爲JVM可以使用更高效的私有構造函數,而不必製作數組的副本。 – Thilo

+0

+1這是正確的答案。 – NINCOMPOOP

3

由於每JVM 5.1 spec

爲了得到一個字符串字面量,Java虛擬機檢查由CONSTANT_String_info結構給定的代碼點序列。

  1. 如果的String.intern先前已經呼籲含有的Unicode代碼點相同,由CONSTANT_String_info結構給定的序列類String的實例的方法中,然後字符串文字導出的結果是到參考類String的相同實例。

  2. 否則,將創建一個包含由CONSTANT_String_info結構給出的Unicode代碼點序列的類String的新實例;對該類實例的引用是字符串文字派生的結果。最後,調用新的String實例的intern方法。

因此從這一點我們可以推斷的構造可以是:

String(int[] codePoints, int offset, int count)

分配一個包含從Unicode代碼點陣列參數的一個子字符的新字符串。 offset參數是子數組的第一個代碼點的索引,count參數指定子數組的長度。子數組的內容被轉換爲字符;隨後對int數組的修改不會影響新創建的字符串。

甚至可以在私有構造

// Package private constructor which shares value array for speed. 
String(int offset, int count, char value[]) { 
this.value = value; 
this.offset = offset; 
this.count = count; 
} 
+0

我們如何推斷這個構造函數被調用?它是公共和低效的(必須複製數組)。人們會認爲JVM可以使用更高效的私有構造函數。 – Thilo

+0

@Thilo很好的觀察,但我沒有在'String'中看到任何'private'構造函數,這個構造函數更接近於doc所說的內容。 – NINCOMPOOP

+1

http://hg.openjdk.java.net/jdk7/build-gate/jdk/file/tip/src/share/classes/java/lang/String.java上有一行645行 – Thilo

相關問題