在Java中与逻辑运算符进行字符串比较
比较两个字符串时,我被教导不应该使用逻辑运算符(==)。我们应该使用String.equals(String)进行比较。但是,我发现下面的代码符合并使用最新的JDK(1.6_23)打印“Hello Friend
”。我试着四处搜寻,找不到任何参考。从何时发生?在Java中与逻辑运算符进行字符串比较
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");
}
}
}
您不应该使用==
,因为它做了其他的事情,那么你认为。
在这种情况下,“hello”被保存(在字符串实习中读取),所以与您的结果相同的是“巧合”。
==
检查两件事情是完全相同的事情,而不是如果他们有相同的内容。这是一个非常大的差异,一些偶然的(虽然可以解释的)“错误的possitives”没有理由使用这种方法。
只需使用等于字符串比较。
从这个网站的例子: 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));
的==
操作者用于检查如果两者都同时.equals
比较的值,以相同的字符串对象的引用。
它适用于您的情况(并且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
。
这个魔术叫做实习。
爪哇实习生字符串文字等有其评估为真高概率:
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"
==比较对象引用,等于()比较字符串的值。
在你的情况你分配两个值为“你好”的字符串对象,然后将它们与==比较。编译器可能会决定优化和使用相同的对象引用,从而得到如你所得到的真实结果。然而这不是保证的行为 - 使用equals()进行值比较要安全得多。
“Java虚拟机维护一个内部字符串(唯一字符串池)引用的内部列表,以避免堆内存中出现重复的字符串对象。每当JVM从类文件加载字符串字符串并执行时,它会检查该字符串是否存在在内部列表中,如果它已经存在于列表中,那么它不会创建一个新的String,它会使用对现有String对象的引用。JVM在内部为String类型进行这种类型的检查,通过'new'关键字创建你可以显式强制JVM对String对象进行这种类型的检查,这是通过使用String.intern()方法通过'new'关键字创建的,这迫使JVM检查内部列表并使用现有的String对象,如果它已经存在。
因此得出的结论是,JVM在内部为String字面值维护唯一的String对象。程序员不需要关心字符串文字,但是他们应该为使用'new'关键字创建的String对象而烦恼,他们应该使用intern()方法来避免堆内存中重复的String对象,从而提高Java性能。请参阅以下部分以获取更多信息“
==
比较对象引用
您可以通过观察下面的代码输出明白:
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
因为在此代码中,vari能够s
引用新的字符串对象,它反过来引用字符串池中的字符串字符串“hello”。
http://*.com/questions/767372/java-string-equals-versus – 2011-01-20 08:43:24
另请参阅http://*.com/questions/513832/how-do-i-compare-strings-in-java (接受的答案是指实习) – finnw 2011-01-20 08:53:50
我不认为这是一个骗局。这个问题是问“为什么它有时会工作”而不是“为什么它通常不起作用” – finnw 2011-01-20 08:56:09