有一些关于java字符串的问题

有一些关于java字符串的问题,java,string,Java,String,我在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 为什么结果是这样,有人能给我解释一下吗? 据我所知,这两种说法都是正确的 我们不使用==来比较java中的字符串。它将对象引用与系统内存进行比较 您有几个选择: 相等

我在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
为什么结果是这样,有人能给我解释一下吗?
据我所知,这两种说法都是正确的

我们不使用
==
来比较java中的字符串。它将对象引用与系统内存进行比较

您有几个选择:

  • 相等于
  • 等信号盒
  • 匹配项(正则表达式)
在您的示例中,您定义了两个字符串。两者都将位于不同的内存位置
=
只比较对该位置的引用,并且会发现它不相同,因为您在两个不同的字符串上调用它


第二个比较是正确的,因为java只向内存添加了一个“ab”,因此它将指向相同的位置。请参阅:java字符串池是一个
对象,因此
s1
和所有其他字符串类型变量的值实际上是对实际值的引用

=
通过值比较这意味着引用是相互比较的,而不是字符串本身。这个比较:
System.out.println(s3==“ab”)的计算结果仅为
true
。首先,编译器优化
字符串s3=“a”+“b”
字符串s3=“ab”。JVM本身有一个字符串池,这些字符串作为常量存储在那里(这是可以做到的,因为字符串在java中是不可变的)。该字符串文字随后用于比较和“ab”的初始化。因此,当我们用各自的引用替换变量/常量时,比较看起来有点像这样:

if(0xA54B == 0xA54B)...
另一方面,由于使用了
s1
,因此
s2
不会以同样的方式得到优化,从而导致
false
s2
只能在运行时生成(理论上可以对其进行优化,但java不这样做),因为它需要
s1
的值,因此不是常量<代码>s2
在运行时不会存储在字符串池中,也不会与字符串池中的值进行比较,而只会放在字符串池之外的堆中。这是由于默认的java实现。有很多关于字符串隐式和显式内部处理的文章,所以我不会发布链接。熟记:
s2
不会根据字符串池进行检查,因此将引用除
s3
之外的另一个字符串对象,该对象指向池中的字符串对象


使用
someString.equals(otherString)
(词典学比较)可以正确比较字符串。

我知道我们可以使用equals方法,但我想了解为什么结果与我在问题中所写的结果相同。
String s3=“a”+“b”被编译为
字符串s3=“ab”
因此它使用了与您比较的同一个文本字符串
“ab”
。第二个示例打印
true
,因为两者都指向同一个字符串。您能解释更多关于第一个表达式打印false的原因吗?@Coinnigh我编辑了这篇文章以更好地解释它(希望如此)