Java中的字符串初始化

Java中的字符串初始化,java,string,Java,String,考虑到以下准则: 如何在不使用新字符串的情况下创建str1对象? 为什么str1和str2对象引用相同的内存位置? 所有这些都在java语言规范中描述 见: 每个字符串文字都是对实例§4.3.1的引用§4.3, 类别字符串§4.3.3的§12.5。字符串对象具有常量值。 字符串文字,或者更一般地说,是 常量表达式§15.28-被扣留,以便共享唯一的 实例,使用String.intern方法 hello是Java中的字符串文字。Java创建了一个字符串文本池,因为字符串是不可变和可重用的。通过ne

考虑到以下准则:

如何在不使用新字符串的情况下创建str1对象? 为什么str1和str2对象引用相同的内存位置?
所有这些都在java语言规范中描述

见:

每个字符串文字都是对实例§4.3.1的引用§4.3, 类别字符串§4.3.3的§12.5。字符串对象具有常量值。 字符串文字,或者更一般地说,是 常量表达式§15.28-被扣留,以便共享唯一的 实例,使用String.intern方法


hello是Java中的字符串文字。Java创建了一个字符串文本池,因为字符串是不可变和可重用的。通过new Stringhello,您将创建一个额外的字符串对象,即使池中已经存在等效的文本。

在java中,您可以创建字符串对象,而无需调用新运算符。因此,string str1=hello相当于string str1=new Stringhello。这样做是为了使字符串声明类似于原始数据类型

关于它们为什么指向相同的内存位置:

在java中有一个概念。为了减少JVM中创建的字符串对象的数量,String类保留了一个字符串池。每次代码创建字符串文字时,JVM都会首先检查字符串文字池。如果该字符串已存在于池中,则返回对池实例的引用。如果池中不存在该字符串,则会实例化一个新的字符串对象,然后将其放入池中

这是真的

如果您这样做:

String str1 = "Hello";  
String str2 = new String("Hello");
System.out.print(str1 == str2);
打印错误

因为,字符串对象是从字符串文本池中创建的。

如图所示

相当于

char data[] = {'h', 'e', 'l', 'l', 'o'};
String str = new String(data);
正如所建议的,在本例中,常量字符串hello是ed,这意味着它们共享相同的内存并引用相同的引用。所有端间字符串都存储在字符串常量池中。有关详细信息,请参阅本文

作为常量表达式§15.28-1值的字符串为 interned,以便使用该方法共享唯一实例

但是,如果您自己使用新字符串创建它,将分配新内存

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指向同一个内存位置?你测试过这个吗?
String str1 = "hello";
char data[] = {'h', 'e', 'l', 'l', 'o'};
String str = new String(data);
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;