Java中逻辑运算符的字符串比较
当比较两个字符串时,我被告知不应该使用逻辑运算符(=)。我们应该使用String.equals(String)进行比较。但是,我看到以下代码符合最新的JDK(1.6_23)并打印“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"){
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");
}
}
}