将两个字符串与“==”进行比较:它何时起作用?

时间:2011-09-20 02:12:20

标签: java string object equals

假设你有三个字符串,

String s1 = "string one";
String s2 = new String("string one");
String s3 = "string one";

我知道s1 == s2 false属于s1 == s3,但我读到的地方true是{{1}}。它是否正确?为什么或为什么不呢?

3 个答案:

答案 0 :(得分:22)

字符串文字自动实现。因此s1 == s3为真。字符串可以在字符串常量池中创建,也可以在堆空间中创建。如果您实际在堆中创建了一个字符串,则该字符串将位于字符串常量池中。

创建字符串文字(String s1 =“string one”)时,字符串将在字符串常量池中创建。此外,字符串常量池不存储重复项。所以,当你说,

String s1 = "string one";
String s3 = "string one";

s1和s3都将指向字符串常量池中字符串的同一实例。所以s1.equals(s3)将是真的。并且s1 == s3也是如此;因为两个指针都是一样的。

但是,使用“new”构造函数

实例化字符串时
String s2 = new String("string one");

然后在堆空间中创建s2。堆空间是与字符串常量池

不同的内存区域

因此,当s1.equals(s2)为真时,s1 == s2为假;因为他们将指向不同的记忆区域。

但是,您可以转换使用“new”构造函数创建的字符串,以通过调用intern()函数将其移动到字符串常量池。所以s2.intern()将在字符串常量池中返回一个字符串;虽然s2最初是在堆中创建的。

答案 1 :(得分:4)

是的,这是事实,因为字符串文字都是实体。有关详细信息,请阅读String.intern()的文档。

因此,这些都是相同的对象(并且将与==进行比较):

s1
s3
s1.intern()
s2.intern()
s3.intern()

答案 2 :(得分:1)

以上是如何。

你应该知道原因。

A)在编译时声明的字符串变量ref常量池中的常量

B)字符串变量结果由方法引用堆空间中的Object。

这一切都是因为JVM规范和它的内存设计。

A)因为字符串是不可变的。当java编译类和jvm加载类时,jvm找到了一个由你的编码时间声明的String变量。因为它是常量,jvm将常量放到“Runtime Constant Pool”内存区域。并且,常数是唯一的。

B)是简单的。因为jvm运行时变量使用堆空间。