可能重复:
How do I compare strings in Java?
Demonstrating string comparison with Java
我对这里的基础知识感到困惑。自从我开始使用java以来,我总是被告知“不要使用==进行字符串比较;总是使用等于”。现在我开始学习OCJP,并遇到了一些令人困惑的问题。
1)
String s1 = "Monday";
String s2 = "Monday";
s1 == s2返回true;
2)假设有一个如下定义的类:
class Friend {
String name;
Friend(String n){
this.name = n;
}
public boolean equals(Object o){
return ((Friend) o).name == this.name;
}
}
我创建了两个对象的实例:
Friend f1 = new Friend("1");
Friend f2 = new Friend("1");
f1.equals(f2)
将返回true
3)最后,我定义了主要方法的MyClass:
public static void main(String[] args) {
System.out.println(args[0] == "x");
}
调用java MyClass x
之后将打印出来。
1,2和3有什么区别?为什么在情况1和2中没有返回false,当两个字符串显然指向不同的对象时?
答案 0 :(得分:2)
根据Java语言规范的3.10.5部分,字符串文字被“实例化”(存储并引用一个可共享值)以共享实例。
每个字符串文字都是类String(第4.3.3节)的实例(第4.3.1节,第12.5节)的引用(第4.3节)。 String对象具有常量值。字符串文字 - 或者更一般地说,是作为常量表达式的值的字符串(第15.28节) - 使用String.intern方法“实现”以便共享唯一的实例。
这意味着两个字符串文字引用相同的内部对象,因此在使用==
进行比较时相同,如示例1和2中所示。但是,示例3中的args[0]
字符串不是文字,但是如果你比较它的实习值,就像下面那样,表达式就是真的。
System.out.println(args[0].intern() == "x"); //prints true
同样,如果您没有实例1或2中的其中一个字符串,则相关表达式将为false。
String s1 = "Monday";
String s2 = new String("Monday");
System.out.println(s1 == s2); //prints false
答案 1 :(得分:1)
简短的回答是:字符串池。你可以在这里找到一个简短的解释:
还有更长的时间:
http://www.dreamincode.net/forums/topic/187631-the-string-pool/
答案 2 :(得分:1)
尝试使用hashCode()方法进行调试
s1.hashCode() must be equal to s2.hashCode()
但是
args[0].hashCode() is not equal to "x".hashCode()
答案 3 :(得分:0)
使用#1方法初始化String
值会使两个变量在内存中引用相同的String
,因此这就是==
返回true的原因。
但是,最终以其他方式创建的String
值几乎总是会引用内存中的不同位置,因此==
将返回false。这就是为什么equals是检查String
平等的最佳方式。