一、String类的equals()与StringBuffer的equals()
在学习Java字符串String的时候我们就了解过,字符串的比较要使用String 对象中的equals()方法而不能单纯地像比较其他基本类型一样用==。原因?可能一些基础教程中会谈及到equals()比较的是对象中的内容,==比较的是对象的内存地址。但是这种回答并不完全正确。
两个相同字符串内容的String对象,使用equals方法,返回的是true,使用==返回的则是false。而使用StringBuffer创建的内容相同的对象,调用equals也会比较其内容而返回true吗?看下面的例子:
@Test
public void testEquals(){
String s1 = new String("abc");
String s2 = new String("abc");
StringBuffer sb1 = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(s1.equals(s2));
System.out.println(sb1.equals(sb2));
}
运行结果:
true
false
Object.java
public boolean equals(Object obj) {
return (this == obj);
}
从上面的代码可见,Object中的equals()方法实际上就是使用==进行了比较,效果与==等价,比较的事对象的地址,而不是对象的内容。所以,对于所有未重写equals()方法的类来说,用==与equals()是没有差别的。而String类正是因为重写了equals()方法,使之比较字符串内容值,才能用于比较两个字符串内容的异同,StringBuffer并没有对equals()进行重写,我们在调用时候仍然使用了Object的equals()方法,所以返回的是地址值比较的结果。
String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
二、equals重写规则
在JDK的API文档中对类重写equals()方法有以下规则。
- 自反性。:对于任何非空引用值x,x.equals(x)应该返回true。
- 对称性。对于任何非空引用值x和y,x.equals(y),y.equals(x)应该返回true。
- 传递性。对于任何非空引用值x、y和z,如果x . equals(y)返回true,y. equals(z)返回true,那么x . equals(z)应该返回true。
- 一致性。对于任何非空引用值x和y,如果比较信息没有修改的情况下,多次调用x. equals(y)始终返回true或始终返回false。
- 对于任何非空引用值x,x.equals(null)应返回false。
参考内容:JDK在线文档