==运算符来比较字符串

时间:2015-10-10 18:58:22

标签: java string

我写了以下代码:

String s="Rahul";
String s2=s.concat(" Shukla");
String s3="Rahul Shukla";
System.out.println(s2==s3);

我期望s2 == s3的输出为true,但它变为false。因为我认为s2和s3指向字符串常量池中的同一个对象,所以s2 == s3应该计算为true。谁能告诉我这里到底发生了什么?

5 个答案:

答案 0 :(得分:3)

首先,除非您关心JVM内部和不可靠的“保证”,否则请不要使用==。只是不要。

其次,当使用“Shukla”调用concat时,结果是常量池中的RahulShulka是,但它们的连接是堆上的新String:

  

在运行时通过串联计算的字符串是新创建的,因此是不同的。

+作为运算符是不同的,因为它不是方法调用,在它的两个操作数都是常量的情况下(通过字符串文字):

  

由常量表达式计算的字符串(第15.28节)在编译时计算,然后将其视为文字。

     

同一个包(第7节(包))中同一个类(第8节(类))中的文字字符串表示对同一个String对象的引用(§4.3.1)。

所有引号均来自JLS, Version 8, section 10.3.5

答案 1 :(得分:0)

如果你使用新的String(somestring).intern()创建了每个字符串,那么你可以使用==运算符来比较两个字符串,否则只能使用equals()或compareTo方法。 equals()方法存在于java.lang.Object类中,它应该检查对象状态的等价性。

点击此链接:How do I compare strings in Java?

答案 2 :(得分:0)

由于String是不可变的concat()方法,因此将创建新的字符串对象。但s3将引用字符串池中的对象。所以s2==s3它将返回false

答案 3 :(得分:0)

s3变量在池中创建,而s2在堆中创建,因为==比较了不相等的引用,这给了你错误。

String s3="Rahul Shukla";  

是否可以在编译时确定s3值中的创建者

String s2=s.concat(" Shukla");

是在堆中创建的,因为如果您看到concat()的源代码,则会返回new String()

答案 4 :(得分:0)

有趣的是,VirtualProtect()的规范在Java 7和Java 8之间发生了变化。

Java 7 Specification说:

  

如果参数字符串的长度为0,则返回此String对象。否则,将创建新的String对象 ...

Java 8 Specification说:

  

如果参数字符串的长度为0,则返回此String对象。否则,返回一个String对象,该对象表示一个字符序列,该字符序列是由此String对象表示的字符序列和由参数字符串表示的字符序列的串联。

但是,实施似乎没有改变。这是代码。

concat

这意味着,如果您使用public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); } ==的结果与s.concat(" Shukla")进行比较,则会得到s3,但严格来说,规范并未保证这一点。

然而,正如其他人所指出的那样,你不需要关心这一点。您应该使用false比较字符串,并忘记详细信息。