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

Java中逻辑运算符的字符串比较,java,string-comparison,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"){

当比较两个字符串时,我被告知不应该使用逻辑运算符(=)。我们应该使用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");
        }
    }
}

你不应该使用
==
,因为它做的事情比你想象的要多

在本例中,“hello”被保存(在字符串实习时读取),因此它与您的stirng是相同的,这是“巧合”

=
检查两个事物是否完全相同,而不是它们是否具有相同的内容。这是一个很大的区别,一些偶然的(虽然可以解释)“假可能性”并不是使用这种方法的理由

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

本网站提供了一个示例:

它返回false,而下面的代码返回true

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

=
操作符用于检查两者是否都是对同一字符串对象的引用,而
.equals
则比较值。

它在您的情况下起作用(当然,它也像早期JVM中一样起作用),因为
s
指的是字符串文字
“hello”
。用文字初始化的字符串引用引用文字(在后台是全局对象),而不是单独创建的新对象。正如其他人所提到的,这个术语是“实习”。因此,在您的示例中,
s
“hello”
引用相同的物理对象。考虑

String s1 = "hello";
String s2 = "hello";
String s3 = "hello";
所有这些字符串都引用同一个物理对象,因此它们之间的任何一对或它们与
之间的任何一对之间的“==”比较“hello”
返回
true

然而

String s4 = new String ("hello");
创建一个新的对象,因此
s4==“hello”
产生
false

这种魔力被称为interning

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"

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

在本例中,分配两个字符串对象,两个对象的值均为“hello”,然后将它们与==进行比较。编译器可能会决定优化并使用相同的对象引用,从而给出与您得到的结果类似的真实结果。但是,这并不能保证行为的正确性—使用equals()进行值比较要安全得多。

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

因此,结论是,JVM在内部为字符串文本维护唯一的字符串对象。程序员不必为字符串文本操心,但他们应该为使用“new”关键字创建的字符串对象操心,他们应该使用intern()方法避免堆内存中重复的字符串对象,从而提高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");
        }
    }
}
此程序将打印
无hello


因为在这段代码中,变量
s
指的是新的字符串对象,而新的字符串对象又指的是字符串池中的字符串文字“hello”。

另请参见(公认的答案指的是interning),我不认为这是重复。这个问题是问“为什么它有时工作”而不是“为什么它通常不工作”,这在Java中是最常见的问题。我建议你提高搜索技能1700万hitsI搜索了相同的和其他一些。没有一篇文章提到“字符串实习”。我知道这不是比较两个字符串的方法。我只是感到惊讶,这是工作。我花了很长时间才敢问这个问题。谢谢。如果加上“实习”,我就忘了这个词;)“编译器可能决定优化”-这是不准确的。字符串文本总是被实习的。谢谢你的详细回答。s2==“hello”返回true。s4==“hello”返回false,对吗???@Sundeep,是的,这是一个拼写错误,现在已修复:-)感谢您的详细解释。
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");
        }
    }
}