== :
1.本质:比较的的是地址,栈内存中存放的对象的内存地址。
2.判断引用所指的对象是否是同一个。
3.两边的操作数必须是同一类型的(可父子类)才能编译通过。
4.值类型(int,char,long,boolean等)都是用==判断相等性。
equals:
1. 本质:比较的是两个对象之间的内容
2. equals是Object的成员函数,有一些类覆盖(override)了这个方法,用于判断对象的等价性。如果没有进行覆盖的话,调用的就是Object类中的方法,查看Object源码:
public boolean equals(Object obj) {
return (this == obj);
}
可知,如果不重写equals方法的话,其作用与 == 完全相同。
但是,有一些类会覆盖重写Object中的equals方法,如:像String、Integer等类,对equals进行了重写
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
对equals重写需要注意五点:
1 自反性:对任意引用值X,x.equals(x)的返回值一定为true;
2 对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
3 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true ;
4 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变;
5 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false 。
String类,两个引用所指向的String都是”abc”,但可能出现他们实际对应的对象并不是同一个(和jvm实现方式有关),因此用==判断他们可能不相等(因为所创建的对象可能地址不同),但用equals判断一定是相等的(因为他们所表示的内容是一样的)。
public class test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
if (aa == bb) // true
System.out.println("aa==bb");
if (a == b) // false,非同一对象
System.out.println("a==b");
if (a.equals(b)) // true
System.out.println("aEQb");
if (42 == 42.0) { // true
System.out.println("true");
}
}
}