与Java中的逻辑运算符的字符串比较

时间:2011-01-20 08:40:27

标签: java string-comparison

比较两个字符串时,我被告知我们不应该使用逻辑运算符(==)。我们应该使用String.equals(String)进行比较。但是,我看到以下代码符合并使用最新的JDK(1.6_23)打印“Hello Friend”。我试着四处寻找,找不到任何参考。这是什么时候发生的?

public class StringComp{
public static void main(String args[]){
        String s = "hello";
        if(s=="hello"){
                System.out.println("Hello Friend");
        }else{
                System.out.println("No Hello");
        }
    }
}

7 个答案:

答案 0 :(得分:11)

你不应该使用==,因为它会做你想的其他事情。

在这种情况下,保存“你好”(在字符串实习中阅读),所以它与你的搅拌一样“巧合”。

==检查两件事情是否完全相同,而不是内容相同。这是一个非常大的差异,一些偶然的(虽然可以解释)“虚假的可能性”并不是使用这种方法的理由。

只需使用equals进行字符串比较。

从这个网站上的一个例子: http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/

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

返回false,而以下代码返回true。

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

答案 1 :(得分:4)

魔术被称为实习

Java 实习生字符串文字,因此评估为true的概率很高:

String a = "hello";       // "hello" is assigned *and* interned
String b = "hello";       // b gets a reference to the interned literal
if (a == b)
   System.out.println("internd.");

String c = "hello" + Math.abs(1.0);   // result String is not interned
String d = "hello" + Math.abs(1.0);   // result String is not interned
System.out.println(c==d);             // prints "false"

c = c.intern();
System.out.println(c==d);             // prints "false"

d = d.intern();
System.out.println(c==d);             // prints "true"

答案 2 :(得分:2)

==运算符用于在.equals比较值时检查两者是否都是对同一String对象的引用。

答案 3 :(得分:2)

它适用于您的情况(和AFAIK一样,它在早期的JVM中也是如此)因为s引用了字符串文字"hello"。用文字初始化的字符串引用引用文字(它是背景中的全局对象),而不是单独创建的新对象。正如其他人所提到的那样,这个术语是实习。因此,示例中的s"hello"引用相同的物理对象。考虑

String s1 = "hello";
String s2 = "hello";
String s3 = "hello";

所有这些字符串都引用相同的物理对象,因此在这些字符串之间进行'=='比较,或者在其中任何字符串和"hello"之间进行比较,返回true

然而

String s4 = new String ("hello");

创建一个新对象,因此s4 == "hello"会产生false

答案 4 :(得分:0)

“Java虚拟机维护一个内部字符串的引用内部列表(唯一字符串池),以避免堆内存中重复的String对象。每当JVM从类文件加载String文字并执行时,它会检查该字符串是否存在于如果它已经存在于列表中,那么它不会创建新的String并且它使用对现有String对象的引用.JVM在内部对String字符进行检查,但不对它创建的String对象进行检查。通过'new'关键字。您可以显式强制JVM对使用String.intern()方法通过'new'关键字创建的String对象执行此类检查。这会强制JVM检查内部列表并使用现有的String对象如果它已经存在。

结论是,JVM在内部为String文字维护唯一的String对象。程序员不必担心String文字,但他们应该打扰使用'new'关键字创建的String对象,他们应该使用intern()方法来避免堆内存中的重复String对象,从而提高java性能。有关详细信息,请参阅以下部分。“

参考:PreciseJava.com - Optimization techniques in Strings and StringBuffer (How the JVM works with Strings)

答案 5 :(得分:0)

==比较对象引用

您可以通过观察以下代码中的输出来理解它:

public class StringComp{
    public static void main(String args[]){
        String s = new String("hello");
        if(s=="hello"){
                System.out.println("Hello Friend");
        }else{
                System.out.println("No Hello");
        }
    }
}

此程序将打印No hello

因为在此代码中,变量s引用了新的String Object,而后者又引用String池中的字符串文字“hello”。

答案 6 :(得分:-1)

==比较对象引用,equals()比较字符串的值。

在您的情况下,您将分配两个值为“hello”的String对象,然后将它们与==进行比较。编译器可能决定优化并使用相同的对象引用,给出一个真实的结果,就像你得到的结果一样。但是,这不是保证行为 - 使用equals()进行值比较会更安全。