2015-10-03 34 views
-3

我有以下代码:为什么DOES ==有时适用于Java中的字符串?

Circle c1 = new Circle(); 
Circle c2 = new Circle(); 
System.out.println(c1 == c2); 

,输出False,符合市场预期。这是因为c1c2是引用类型,“==”检查它们是否指向相同类型(它们不这样做)。

不过,我最近尝试这样的:

String a = "hello"; 
String b = "hello"; 
System.out.println(a == b); 

由于某种原因输出True。为什么是这样?字符串是参考类型,ab指的是不同的存储位置。我总是被教导,你需要使用.equals()这个工作,这不是!

请参见:https://ideone.com/CyjE49

UPDATE 这岂不是重复的! 我知道正确的方式来比较字符串使用.eqauls()

更新2 这个问题可能有一个答案:How do I compare strings in Java?,但问题也没有问什么,我问,答案就在更多的去详细比需要。

因此,使用相同的问题进行搜索(在Google或其他平台上)意味着用户不会被发送到该问题,或者可能由于问题的标题而将其完全消除。因此,为了其他用户的利益而保持这一点可能是一个好主意!

+1

我同意OP-这不是这些问题中的任何一个的重复。这是要求_why_引用相等不返回两个完全相同的字符串文字。 – davmac

+2

你会在这里找到答案http://stackoverflow.com/questions/2486191/what-is-the-java-string-pool-and-how-is-s-different-from-new-strings。 – yorlin

+0

是的,这个问题可能在那里有答案,但是那里的问题并没有这么问。因此,用同样的问题搜索,不会发送到那里。因此,为了其他用户的利益,这可能是一个想法。 –

回答

2

String interning。由于ab都是具有相同值的常量,因此编译器利用字符串的不变性使两个变量都引用相同的字符串,从而节省空间。因此==返回True,因为它们实际上是相同的对象。

+0

他们是同一个对象。 “有效”是没有必要的。 – davmac

+0

最初的印象是它们不一样。或者,这可能只是一种糟糕的写作习惯。 – Kyte

1

在这种情况下,“hello”被视为分配给a和b的常量。所以这里==实际上返回true。如果你这样做:

String a = new String("hello"); 
String b = new String("hello"); 
System.out.println(a == b); 

你会得到false

5

由于字符串文字是intern'd,相同的文字指的是同一个对象。因此,检查它们之间的引用相等性必然会返回true。

从Java语言规范(3.10.5):

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

实际上,编译器会将字符串文字“早期”汇集起来,并只将一个副本存储在已编译的.class文件中。然而,来自不同类文件的相同字符串文字仍然会使用==进行比较,因为文字在加载类时仍然是intern'd。

如果,另一方面,我们正确地应用与圆为String的例子中,我们将有:

String a = new String("hello"); 
String b = new String("hello"); 
System.out.println(a == b); // will print false! 

在这种情况下,我们明确地创建新的对象,所以他们不能等于引用。

通过非文字或其他常量字符串表达式构造的任何字符串也不一定会将reference-equal与相同的字符串进行比较。例如:

String a = "hello"; 
String b = "hello"; 
System.out.println(a.substring(0,3) == b.substring(0,3)); // may print false! 
相关问题