2011-08-31 66 views
2

比较引用可能重复:
String comparison and String interning in Java==操作符不适合字符串

我明白字符串是如何的equals()方法的工作,但被一些成果,我与字符串惊讶==运算符。

我会期待==比较引用,因为它为其他对象。

但是,不同的String对象(具有相同的内容)==返回true,甚至对于静态字符串对象(具有相同的内容),这显然不是相同的内存地址。

我猜==已被定义一样等于以防止其滥用

+3

这里有一些问题,因为'=='肯定比较引用而不是对象。 “不同的字符串对象”是什么意思?一种可能性是你在做''你好!' ==“Hello!”,它实际上保证工作,因为所有具有相同内容的字符串文字都由相同的'String'对象表示。 – templatetypedef

+0

看看这篇关于字符串实习的文章http://javatechniques.com/blog/string-equality-and-interning/ –

+0

==不会比较参考。字符串引用仅由JVM以特殊方式处理。尝试这些比较,“一个字符串”==“一个字符串”返回true; “一个字符串”==新的字符串(“字符串”)返回false。 – Nate

回答

12

没有,==只是比较引用。然而,我怀疑你被编译时常量所愚弄 - 所以两个文字最终会引用相同的字符串对象。例如:

String x = "xyz"; 
String y = "xyz"; 
System.out.println(x == y); // Guaranteed to print true 

StringBuilder builder = new StringBuilder(); 
String z = builder.append("x").append("yz").toString(); 

System.out.printn(x == z); // Will print false 

section 3.10.5 of the Java language specification

字符串文字,或者更一般地,字符串是“实习”,以便共享独特实例常量表达式(§15.28)-are的值,使用方法String.intern。

+0

是的,我相信String的编译器优化一定是原因。和上面的例子一样,静态字符串n =“xyz”也返回== true。 –

+0

@彼得:是的 - 再次,你有一个字符串文字。这与'=='操作符本身的行为不同;你刚刚得到相同的参考。 –

+0

也'z =“x”+“yz”; x == z; //是真的' –

5

返回相同的原因是因为内存优化的(也并不总是保证发生)具有相同内容的字符串将指向相同的内存区域以节省空间。在静态对象的情况下,它们总是指向相同的东西(因为static关键字只有一个)。再次不要依赖上述并使用Equals()来代替。

从Jon Skeet中我应该指出的一件事情是它始终保证编译时常量。但是再次使用equals(),因为它更清晰。

0

我猜==已被定义一样等于以防止其滥用

错误。这里发生的事情是,当编译器发现你在两个不同的地方使用同一个字符串时,它只会将它存储在程序的数据部分中一次。读入字符串或从较小的字符串中创建,然后进行比较。

编辑:请注意,当我说上面的“相同的字符串”,我只指的是字符串文字,编译器在运行时知道。

3

==运算符始终会对Java中的引用进行比较,并且永远不会对内容进行比较。可以发生的是,一旦你声明了一个字符串文字,这个对象就会被发送到JVM的字符串池,如果你重复使用相同的文字,相同的对象将被放置在那里。针对此行为一个简单的测试可以在下面的代码段中可以看出:

String a = "a string"; 
String b = "a string"; 
System.out.println(a == b); // will print true 

String c = "other string"; 
String d = new String("other string"); 
System.out.println(c == d); // will print false 

第二壳体打印假,因为变量d用直接创建字符串对象初始化,而不是一个常量,因此它不会转到字符串池。

字符串池不是java规范的一部分,不建议信任它的行为。你应该总是使用equals来比较对象。