首先笼统的来讲 “java中equals()方法和“==”运算符” 都是比较的地址,那为什么我们在使用中总会出现混淆的情况呢老是弄错呢,这是因为“重写equals()方法”和一些
“特殊情况”的存在
- 由于java中的所有的类都是默认的继承自Object类的,那我们看一下Object类中equals方式是怎么定义的:
public boolean equals(Object obj) {
return (this == obj);
}
发现了吧,Object类中equals方法 就等于 “==”,比较的是对象的地址是否是一样的。(周所众知 “==”运算符如果操作的是原子类型的话比较的是值,操作的是对象的话则是对象的地址)
2. 但是在实际的使用中 equals方法和“==”运算符的执行结果却不尽相同 这是为什么呢?举个例子:
String a=new String("abc");
String b=new String("abc");
a.equals(b) ;//结果是true
a==b;//结果却是false
这是为什么呢? 不是1中说了equals方法和“==”比较结果是一致的么,由于在这里a和b都是String对象,在1中说过了 所有的类都继承自Object类,那么在String类中那么也应该有一个equals方法,那么我们就去看一下他的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;
}
看到这里相信大伙儿明白了吧,原来String类重写了Object类的equals方法,重新定义了equals方法的比较规则,首先判断两个对象的地址是否是一样的, 是一样的话那肯定”相等“ 否则的话就一个一个的比较String里面的每一个字符,总的起来说String类的equals方法比较的就是字符串的”值“。而“==”运算法比较的是对象的地址,显然a和b是两个不同的对象,比较结果当然是false了。
3. 在说一个特殊情况,比较原子类型的时候 java的“==”运算符比较的是 原子类型的值(且只能用“==”运算符来比较,为什么不能用equals方法来比较请看1中在Object类中equals方法的定义(注意方法的参数类型是Object,显然原子类型不是Object的子类)) 举例如下:
int a=1;
int b=1;
a==b//true
4. 综上所述如果我们自定义类型时如果需要比较这个类型的对象是否相等那就应该重新定义继承自Object类的equals方法,例如
class Cat{
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if(null==obj)return false;
if(obj==this)return true;
if(getClass()!=obj.getClass())return false;
else{
Cat c=(Cat)obj;
return name.equals(c.name)&& (age==c.age);
}
}
}
可以像上面这样来写,当然了,关键得看自己怎么定义“相等”这个概念了