初始化考慮下面的代碼:字符串在Java中
- 是如何
str1
對象,而無需使用new String()
產生的? - 爲什麼
str1
和str2
對象引用相同的內存位置?
String str1 = "hello";
String str2 = "hello";
初始化考慮下面的代碼:字符串在Java中
str1
對象,而無需使用new String()
產生的?str1
和str2
對象引用相同的內存位置?String str1 = "hello";
String str2 = "hello";
它在java語言規範的所有描述。
每個字符串文字是類字符串(§4.3.3)的一個實例(第4.3.1節, §12.5)的參考(§4.3)。字符串對象具有一個常數值。 使用String.intern方法將字符串文字(或更一般地說是值爲 常量表達式(§15.28))的字符串「插入」以便共享唯一的 實例。
「hello」是Java中的字符串文字。 Java創建一個字符串文字池,因爲字符串是不可變且可重用的。通過new String("hello")
您將創建一個額外的字符串對象,即使等效文字已經存在於池中。
在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文字池中創建的。
作爲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;
你怎麼知道'str1'和'str2'指向同一個內存位置?你測試過了嗎? – paislee 2012-01-18 00:49:33
@paislee是的,我測試了它。 – invariant 2012-01-18 00:56:07