2012-01-18 22 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;