关于java:字符串相等与位置相等

String equality vs equality of location

1
2
3
4
5
6
7
8
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));

/ /输出 威胁 威胁 褶皱 威胁

你为什么不把所有的字符串存储在相同的位置,如果所有三有相同的内容吗?


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

如果你加一行

1
s3 = s3.intern();

在创建s3之后,您将看到输出中的差异。

请参阅更多示例和更详细的解释。

这当然提出了何时使用==何时使用Java中的EDCOX1 OR 3方法的一个非常重要的主题。在处理对象引用时,您几乎总是希望使用equals。==运算符比较引用值,这几乎不是您要比较的内容。了解差异有助于您决定何时使用==或equals


您显式地为S3调用new,这会给您留下一个新的字符串实例。


创建一个String实际上是一个快速的过程。试图找到任何以前创建的String将会慢得多。

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

当然,您不能像这样实现Java,因为库很不幸地暴露了EDCOX1、6、s和大多数其他不可变的值对象的构造函数。


有一个叫做string.intern的方法,从本质上讲,它获取所有相同的字符串,并将它们放入哈希表中(我有点撒谎,但对于这一点,重要的是概念,而不是现实)。

1
2
3
4
5
6
7
8
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="血鹦鹉是人";做了类似strings1="血鹦鹉是人"。intern();


Why don't all the strings have the same location in memory if all three have the same contents?

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


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

这里有更多细节。