7
String s1 = "BloodParrot is the man";  
String s2 = "BloodParrot is the man";  
String s3 = new String("BloodParrot is the man");  

System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1.equals(s3));

// 输出
true
true
false
true

如果所有三个字符串都具有相同的内容,为什么不是所有字符串在内存中都具有相同的位置?

4

6 回答 6

15

Java 只会自动实习字符串文字。默认情况下,新的 String 对象(使用new关键字创建)不被实习。您可以使用String.intern()方法来实习现有的 String 对象。调用intern将检查现有字符串池中是否存在匹配对象,如果存在则返回它,如果不匹配则添加它。

如果您添加该行

s3 = s3.intern();

在您创建后立即添加到您的代码s3,您将看到输出的差异。

查看更多示例和更详细的说明

这当然引出了一个非常重要的话题,即何时使用 == 以及何时使用equalsJava 中的方法。equals在处理对象引用时,您几乎总是想使用。== 运算符比较参考值,这几乎不是您要比较的意思。了解差异有助于您决定何时使用 == 或equals.

于 2009-02-27T12:54:36.877 回答
3

您为 s3 显式调用 new ,这将为您留下一个新的字符串实例。

于 2009-02-27T12:48:26.097 回答
2

创建一个String实际上是一个快速的过程。尝试查找以前创建的任何String内容都会慢得多。

考虑一下你需要做什么才能让所有人都String被实习。您需要搜索一组所有先前构造String的 s。请注意,这必须以线程安全的方式完成,这会增加开销。因为您不希望它泄漏,所以您需要使用某种形式的(线程安全的)非强引用。

当然,您不能像这样实现 Java,因为不幸的是该库公开了Strings 和大多数其他不可变值对象的构造函数。

于 2009-02-27T12:55:31.303 回答
1

new 关键字总是生成一个新字符串。

更多细节在这里

于 2009-02-27T12:50:06.013 回答
1

如果所有三个字符串都具有相同的内容,为什么不是所有字符串在内存中都具有相同的位置?

因为它们是具有相同内容的不同字符串!

于 2009-02-27T12:50:48.070 回答
1

有一种称为 String.intern 的方法,本质上,它获取所有相同的字符串并将它们放入哈希表中(我有点撒谎,但对此重要的是概念,而不是现实)。

String s1 = "BloodParrot is the man";  
String s2 = "BloodParrot is the man";  
String s3 = new String("BloodParrot is the man").intern();  

System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1.equals(s3));

应该让它们都是“真实的”。这是因为(我又在这里撒了一点谎,但它仍然只对概念而不是现实很重要) String s1 = "BloodParrot is the man"; 做了类似 String s1 = "BloodParrot is the man".intern();

于 2009-02-27T15:14:21.313 回答