初始化考虑下面的代码:字符串在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