我在eclipse中编写了以下JAVA代码,
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
输出
false
true
为什么结果如此,有人可以向我解释一下吗? 据我所知,他们俩都应该是真的。
答案 0 :(得分:-1)
我们不使用==
来比较java中的字符串。它会将对象引用与系统内存进行比较。
您有几种选择:
在您的示例中,您定义了两个字符串。两者都将存在于不同的存储位置。 ==
只比较对该位置的引用,并发现它不相同,因为您在两个不同的字符串上调用它。
第二个比较是正确的,因为java只向内存添加了一个“ab”,因此它将指向相同的位置。请参阅:java string pool
答案 1 :(得分:-1)
String
是Object
,因此s1
和所有其他字符串类型变量的值实际上是对实际值的引用。
==
比较按值这意味着引用会相互比较,而不是String
本身。此比较:System.out.println(s3 == "ab");
由于编译器和JVM的多次优化而简单地计算为true
。首先,编译器将String s3 = "a" + "b";
优化为String s3 = "ab";
。 JVM本身有一个字符串池,存储为常量(这可以完成,因为字符串在java中是不可变的)。然后将该字符串文字用于比较和初始化“ab”。因此,当我们用相应的引用替换变量/常量时,比较看起来会像这样:
if(0xA54B == 0xA54B)...
另一方面,由于s2
的使用, s1
将无法以相同的方式进行优化,从而导致false
。 s2
只能在运行时生成(理论上它可以优化,但java不会这样做),因为它需要s1
的值,因此不是常量。 s2
不会存储在运行时字符串池中的值中/与之比较,而是简单地放在字符串池之外的堆上。这是由于默认的java实现。关于字符串的隐式和显式实习,有很多文章,所以我不会发布链接。熟化:s2
将不会针对字符串池进行检查,因此将引用另一个字符串对象,而不是s3
,它指向池中的字符串对象。
使用someString.equals(otherString)
(词典比较)正确比较字符串。