关于对象等价性:
Integer n1 = new Integer(10);
Integer n2 = new Integer(10);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
输出:false
true
原因:==和!= 比较的是对象的引用;而n1和n2虽然内容相同,但却是两个不同的对象的引用,所以对象的引用是不同的。
那么如果想比较两个对象的实际内容是否相同,必须使用所有对象都适用的特殊方法equals()
看下面例子:
Integer n1 = new Integer(10);
Integer n2 = new Integer(10);
System.out.println(n1.equals(n2));
输出:true
再看下面自定义类的例子:
class Test{
int i;
}
Test t1 = new Test();
Test t2 = new Test();
System.out.println(t1.equals(t2));
输出:false
结果又变成false了!!
原因:
看equals在Object中的源码:
public boolean equals(Object obj) {
return (this == obj);
}
由equals源码可看出equals默认行为是比较引用,所以,除非在自己的新类中覆盖equals方法,否则就是一场灾难!
改写自定义类Test,覆盖equals方法:
class Test{
int i;
public boolean equals(Object obj) {
if (obj instanceof Test) {
return this.i == ((Test)obj).i;
}
return false;
}
}
在运行输出变为:true,得到我们想要的结果。
但我们需注意String的表现:
String s1 = new String("123");
String s2 = new String("123");
String s3 = "456";
String s4 = "456";
System.out.println(s1.equals(s2));
System.out.println(s3.equals(s4));
System.out.println(s1 == s2);
System.out.println(s3 == s4);
输出:
true
true
false
true
s3和s4定义的常量,指向的是同一块地址内存,所以对象的引用和内容均相同。
而s1和s2只是内容相同,对象引用是不同的。