2014-11-01 54 views
2

在我们继续前进: 我知道我们应该使用.equals()来比较内容。我现在只是在谈论如果实际的参考是以下情形一样...字符串比较困惑

假设我们有以下几点:

String str1 = "str"; 
String str2 = "string"; 
String str3 = "ing"; 
String str4 = str1 + str3; 
str1 = str4; 
String str5 = "string"; 
System.out.println(str1==str2);//false 

我认为这应该是真实的,因为在字符串池,对“字符串”的引用应该是相同的,因为str1和str2现在都是“字符串”。这应该是真的,但最终结果为false

System.out.println(str1.intern()==str2.intern());//true 

我尝试这样做,它返回一个真正这个时候。 然后我尝试:

System.out.println(str1==str5);//false 
System.out.println(str2==str5);//true 

而且 的System.out.println( “STR” + “ing” 的== “字符串”); //真

是不应该来从字符串池? 有人可以帮忙解释一下吗?

+0

'System.out.println(str1.intern()== str2.intern());'不应该返回true ...文本是不同的。 – Pokechu22 2014-11-01 21:22:32

+1

'String'是'final',这意味着它是不可变的。改变文字,创建一个新的对象。 – 2014-11-01 21:22:38

+0

可能的重复[是不错的做法使用java.lang.String.intern()?](http://stackoverflow.com/questions/1091045/is-it-good-practice-to-use-java-lang -string-intern) – kraskevich 2014-11-01 21:22:55

回答

6

只有字符串文字和常量表达式保证汇集。由于str1 + str2不是文字,因此无论结果是否被执行都取决于JVM。你可以通过调用intern()来强制它,因为你已经发现了。

这在§ 3.10.5 of the Java Language Specification定义:

字符串文字是String类的实例的引用(第4.3.1节,§4.3.3)。

此外,字符串常量指的是类String的同一个实例。这是因为使用方法String.intern将字符串文字(或更一般地说是常量表达式的值(§15.28))的字符串“interned”以共享唯一实例。

你的第二个例子,"str" + "ing",是一个常量表达式,所以它是保证被实施的。请参阅the JavaDoc for String.intern

这是试图解释发生了什么。写得好的代码应该不会依赖于此,但始终使用equals方法。任何合理的JRE会像

if (this == other) 
    return true; 

非常接近String.equals所以性能明智的,它不应该的问题上进行检查。

+0

我认为这是答案,但你有任何来源支持这一点 – 2014-11-01 21:26:32

+0

感谢你。我了解使用.equals()。我只想弄清楚这种情况下的参考问题。 – 2014-11-01 21:28:42

0

总是使用equals方法比较字符串。实习生的麻烦在于每个版本的JDK都会有所不同,所以我不会指望这一点,除非你想每次都在实习生中调用实习生。