2010-09-11 51 views
9

可能重复:
What makes reference comparison (==) work for some strings in Java?使用 '==',而不是.equals为Java字符串

我知道这已经asked before,但尽管如此建议使用.equals()代替==比较运算符,我发现==始终工作:

String s1 = "Hello"; 
String s2 = "Hello"; 
System.out.println(s1 == s2); // true 

任何人都可以给我一个==运营商失败的例子吗?

+0

Marcos在您链接的问题的答案中提供了一个[很好的示例](http://stackoverflow.com/questions/767372/java-string-equals-versus/1251721#1251721)。 – 2010-09-11 23:00:45

+0

相关:http://stackoverflow.com/questions/9698260/what-makes-reference-comparison-work-for-some-strings-in-java/9698305#9698305 – berry120 2012-11-20 13:24:15

回答

37

这是因为你是幸运的。 Java中的==运算符检查引用相等性:如果指针相同,则返回true。它不检查内容是否相等。在编译时找到的相同字符串折叠为一个String实例,因此它与String文字一起使用,但不适用于运行时生成的字符串。

例如,"Foo" == "Foo"可能工作,但"Foo" == new String("Foo")不会,因为new String("Foo")创建一个新的String实例,并打破任何可能的指针相等。

更重要的是,大多数Strings你在一个真实世界的程序中处理运行时生成。文本框中的用户输入是运行时生成的。通过套接字接收的消息是运行时生成的。从文件读取的东西是运行时生成的。因此,如果要检查内容是否相等,则使用equals方法而非==运算符非常重要。

+3

有一点需要注意的是,“foo”==“foo”的原因实际上起作用,是因为所有文字字符串都被实施了http:// download .oracle.com/javase/1.4.2/docs/api/java/lang/String.html#intern() – 2010-09-11 06:25:00

9

任何人都可以给我一个==运算符失败的例子吗?

例1:

String s1 = new String("Hello"); 
String s2 = new String("Hello"); 
System.out.println(s1 == s2); // false 

例2:

Integer a=1000,b=1000; 
System.out.println(a == b); // false 
+1

猜猜这会工作。但是,不是不可变的字符串吗?因此,他们不应该被拘留吗? – Aillyn 2010-09-11 05:45:24

+0

字符串被拦截。 – 2010-09-11 05:46:35

+1

“你好”==“你好”==>真。但是,新的String(“Hello”)将为对象分配一些内存,并且同样的事情会再次为另一个对象分配更多的内存。由于“==”运算符比较引用,它将返回false。 – 2010-09-11 05:47:42

4

当你这样做,你实际上是创建字符串字面

String s1 = "Hello"; 
String s2 = "Hello"; 

编译器中找到相同的字符串文字,然后在堆中保持一个实例,使所有的变量在堆栈点优化到它。因此,执行==将返回true,因为它们指向相同的内存地址。

当你这样做,你正在创建String对象

String s1 = new String("Hello"); 
String s2 = new String("Hello"); 

实例化将在堆中的每个这些和堆栈变量创建独特的空间将指向这些单独的位置。因此,使用.equals()时这些值相等,因为它们的值相同,但使用==时它们不会相等,因为它们是堆内存空间中的不同对象。

4

经验丰富的Java开发人员很少使用new String(String),但在其他情况下也会出现问题。例如:在现实世界的应用

String hello = "Hello" 
String hell = hello.substring(0, 4); 
System.err.println("Hell" == hell); // should print "false". 

(大多数String实例要么采取其他一些字符串的子串,或从字符数组构造它形成的极少数应用程序将只使用String实例。创建为文字。)

+1

使用“y = new String(x)”(其中x是一个字符串)的一个原因是允许垃圾收集,当x是一个非常大的字符串的子字符串。如果你只是使用“y = x”,那么只要y被引用,非常大的字符串就不能被垃圾收集。如果使用“new String(x)”,则会创建一个不引用原始大字符串的新字符串。 – 2010-09-11 11:04:19

+4

这是真的,但根据我的经验,这是很少有必要的。如果没有必要,那实际上是一种反优化。 – 2010-09-11 13:14:55

相关问题