什么使得引用比较(==)在Java中适用于某些字符串?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

我有以下几行代码来比较字符串。str1不等于str2,这是可以理解的,因为它比较了对象引用。但为什么s1等于s2?

String s1 = "abc";
String s2 = "abc";

String str1 = new String("abc");
String str2 = new String("abc");

if (s1==s2)
    System.out.println("s1==s2");           
else
    System.out.println("s1!=s2");

if (str1==str2)
    System.out.println("str1==str2");           
else
    System.out.println("str1!=str2");

if (s1==str1)
    System.out.println("str1==s1");         
else
    System.out.println("str1!=s1");

输出:

  s1==s2
  str1!=str2
  str1!=s1 
提问于
用户回答回答于

字符串常量池本质上将缓存所有字符串文本,因此它们是下面相同的对象,这就是为什么您会看到您所做的输出s1==s2。它本质上是VM中的一种优化,以避免每次声明文字时创建新的字符串对象,这可能会非常快速地变得非常昂贵!用你的str1==str2例子,你明确地告诉VM创建新的字符串对象,因此它是错误的。

顺便说一下,intern()在任何字符串上调用该方法都会将其添加到常量池中(并返回它添加到池中的字符串)。但是,除非确定要处理的情况,否则不一定是好主意那些肯定会被用作常量的字符串,否则你可能最终难以追踪内存泄漏。

用户回答回答于

s1和s2是字符串文字。当您创建新的字符串文字时,编译器首先检查是否有任何代表相同的文字出现在字符串池中。如果有一个存在,编译器将返回该文字,否则编译器将创建一个新的文字。

当您创建String时s2,编译器将返回s1来自池的字符串,因为它之前已经创建。这就是为什么s1s2相同的原因。这种行为称为实习。

扫码关注云+社区