2012-01-18 32 views
0

初始化考慮下面的代碼:字符串在Java中

  1. 是如何str1對象,而無需使用new String()產生的?
  2. 爲什麼str1str2對象引用相同的內存位置?

String str1 = "hello"; 
String str2 = "hello"; 
+0

你怎麼知道'str1'和'str2'指向同一個內存位置?你測試過了嗎? – paislee 2012-01-18 00:49:33

+0

@paislee是的,我測試了它。 – invariant 2012-01-18 00:56:07

回答

5

它在java語言規範的所有描述。

參見3.10.5 String Literals

每個字符串文字是類字符串(§4.3.3)的一個實例(第4.3.1節, §12.5)的參考(§4.3)。字符串對象具有一個常數值。 使用String.intern方法將字符串文字(或更一般地說是值爲 常量表達式(§15.28))的字符串「插入」以便共享唯一的 實例。

1

「hello」是Java中的字符串文字。 Java創建一個字符串文字池,因爲字符串是不可變且可重用的。通過new String("hello")您將創建一個額外的字符串對象,即使等效文字已經存在於池中。

3

在java中,您可以在不調用新運算符的情況下創建String對象。因此,String str1 = "hello"相當於String str1 = new String("hello")。這樣做是爲了使字符串聲明與基本數據類型相似。關於爲什麼他們指的是同一個內存位置

,在Java中的String literal pool。要減少在JVM中創建的String對象的數量概念,String類保持串池。每次您的代碼創建字符串文字時,JVM都會首先檢查字符串文字池。如果該字符串已存在於池中,則對池實例的引用將返回。如果字符串不存在於池中,則新的String對象實例化,然後放入池中。

String str1 = "Hello"; 
String str2 = "Hello"; 
System.out.print(str1 == str2); 

打印True

如果你這樣做:

String str1 = "Hello"; 
String str2 = new String("Hello"); 
System.out.print(str1 == str2); 

打印False

因爲String對象是在String文字池中創建的。

0

作爲string javadoc表明

String str1 = "hello"; 

相當於

char data[] = {'h', 'e', 'l', 'l', 'o'}; 
String str = new String(data); 

和As Java Language Specification表明常數字符串(在這種情況下"hello")是String.intern編這意味着它們共享相同的存儲器,並且是指相同的參考。所有INTEREND字符串存儲在一個字符串常量池(看到這個帖子的細節Identify library file/Source that contains native method implementation

字符串是常量表達式(§15.28)-are 「實習」,以便分享獨特的實例值,使用該方法

但是如果你不與new String()自己創建它,新的內存將被分配

String str = "hello"; 
String str1 = new String(str); 
String str2 = new String(str); 
assert: str1 != str2; 
//Force strings into constant pool 
String str3 = str1.intern(); 
String str4 = str2.intern(); 
assert: str == str3; 
assert: str3 == str4;