2012-04-12 51 views
2

可能重复:
Difference Between Equals and ==
In JDK 1.6, can String equals operation can be replaced with ==?
How do I compare strings in Java?意外的结果,比较两个Java的字符串与 “==” 当

虽然与Java的字符串玩耍,我没想到以下结果:

public class Sandbox { 
    public static void main(String[] args) { 
     String a = "hello"; 
     String b = "hello"; 

     System.out.println(a == b);    //true  Why?, a and b both are seperate Objects 
     System.out.println(a == "hello");  //true  Why? 
     System.out.println(a == new String(b)); //false  As expected 
    } 
} 

我期望所有的都是错误的,因为“==”比较引用。为什么会有这个结果

当我更改String b = "world"时,System.out.println(a == b);返回false。看起来好像字符串对象的内容正在被比较。

由于Java 7可以比较switch-case-Statements中的字符串,我认为它可能与Java版本有关。但是如here所述,在比较Switch-Case中的字符串时会调用equals-Methode。

+0

请阅读[this](http://stackoverflow.com/questions/971954/difference-between-equals-and)。 – mre 2012-04-12 11:42:43

+0

总之,一些字符串被实现(即缓存)并引用同一个对象,这就解释了为什么==可以工作。但是你不能依赖这种机制,而应该使用equals。 – assylias 2012-04-12 11:45:07

+0

底线是,因为字符串仍然是对象,所以在绝大多数情况下,您应该使用“equals”方法。 – 2012-04-12 11:49:04

回答

2

JVM执行some trickery,同时实例化字符串文字以提高性能并降低内存开销。为了减少在JVM中创建的String对象的数量,String类保留了一个字符串池。每次您的代码创建字符串文字时,JVM都会首先检查字符串文字池。如果该字符串已存在于池中,则对池实例的引用将返回。如果字符串不存在于池中,则新的String对象实例化,然后放入池中。 Java可以进行这种优化,因为字符串是不可变的,可以共享而不用担心数据损坏。

+3

它被称为*字符串interning *,在大多数现代语言中很常见 - http://en.wikipedia.org/wiki/String_interning – 2012-04-12 11:47:37

+0

是的,它已在其他评论中进行了解释。有些诡计可能会模糊。 – Anonymous 2012-04-12 11:48:03

3

Java始终(从版本1.0开始)interned字符串文字。这意味着常量字符串被添加到池中并且重复引用相同的对象。

final String a = "hello"; 
final String b = "hell"; 
System.out.println(a == b + 'o'); 

这将打印true,因为编译器可以内联并简化表达b + 'o'至是相同的“你好”。