有一些java字符串的问题

时间:2015-12-02 15:13:17

标签: 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

为什么结果如此,有人可以向我解释一下吗? 据我所知,他们俩都应该是真的。

2 个答案:

答案 0 :(得分:-1)

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

您有几种选择:

  • 等于
  • equalsIgnoreCase
  • 匹配(正则表达式)

在您的示例中,您定义了两个字符串。两者都将存在于不同的存储位置。 ==只比较对该位置的引用,并发现它不相同,因为您在两个不同的字符串上调用它。

第二个比较是正确的,因为java只向内存添加了一个“ab”,因此它将指向相同的位置。请参阅:java string pool

答案 1 :(得分:-1)

StringObject,因此s1和所有其他字符串类型变量的值实际上是对实际值的引用。

==比较按值这意味着引用会相互比较,而不是String本身。此比较:System.out.println(s3 == "ab");由于编译器和JVM的多次优化而简单地计算为true。首先,编译器将String s3 = "a" + "b";优化为String s3 = "ab";。 JVM本身有一个字符串池,存储为常量(这可以完成,因为字符串在java中是不可变的)。然后将该字符串文字用于比较和初始化“ab”。因此,当我们用相应的引用替换变量/常量时,比较看起来会像这样:

if(0xA54B == 0xA54B)...
另一方面,由于s2的使用,

s1将无法以相同的方式进行优化,从而导致falses2只能在运行时生成(理论上它可以优化,但java不会这样做),因为它需要s1的值,因此不是常量。 s2不会存储在运行时字符串池中的值中/与之比较,而是简单地放在字符串池之外的堆上。这是由于默认的java实现。关于字符串的隐式和显式实习,有很多文章,所以我不会发布链接。熟化:s2将不会针对字符串池进行检查,因此将引用另一个字符串对象,而不是s3,它指向池中的字符串对象。

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