Java中的字符串:equals vs ==

And*_*anu 5 java string reference

可能重复:
如何比较Java中的字符串?

  String s1 = "andrei";
  String s2 = "andrei";

  String s3 = s2.toString();

  System.out.println((s1==s2) + " " + (s2==s3));
Run Code Online (Sandbox Code Playgroud)

给出以下代码为什么第二个比较s2 == s3为真?实际上s2.toString()返回的是什么?实际位于何处(s2.toString())

Rob*_*anu 7

首先String.toString是无操作:

/**
 * This object (which is already a string!) is itself returned.
 *
 * @return  the string itself.
 */
public String toString() {
    return this;
}
Run Code Online (Sandbox Code Playgroud)

其次,字符串常量被实现,因此s1和s2在后台更改为相同的String实例.

  • 不应该是"字符串常量被实习"?我怀疑来自文件或用户输入的字符串是否被实习. (3认同)

mdm*_*dma 7

该方法的String.intern()可以被用来确保等于串具有相等的引用.字符串常量intern编,所以s1s2将引用相同的字符串.String.toString()简单地返回自己,即a.toString()当a是String时返回a.所以,s2也== s3.

通常,字符串不应该通过引用相等来比较,而是通过值相等来使用equals().原因是很容易得到两个相同但不同引用的字符串.例如,在创建子字符串时.此规则的一个例外是,如果您intern事先知道两个字符串已被编辑(或者您将它们作为比较的一部分实习).

要回答有关堆或堆栈的隐含问题,请在堆上分配字符串.即使它们被分配在堆栈上,例如即将进行的转义分析和堆栈分配,程序的语义也不会改变,并且您将获得堆和堆栈分配相同的结果.


pca*_*cao 7

基本上当你使用时,你new String("something")强迫Java创建一个全新的对象.

分配给字符串文字时="something",该字符串存储在常量池中,由JVM完成优化.因此,当您为同一个常量指定另一个引用时,存储在常量池中的Object将被重用,基本上,它是同一个对象.

  • 注意:您不应该依赖此功能,它只是实现细节.总是比较使用`"foo".equals(otherString);` (2认同)