前言
“==”是关系运算符,equals()是方法,同时他们的结果都返回布尔值;
“==”使用情况如下:
- 基本类型,比较的是值
- 引用类型,比较的是地址
- 不能比较没有父子关系的两个对象
equals()方法使用如下: - 系统类一般已经覆盖了equals(),比较的是内容。
- 用户自定义类如果没有覆盖equals(),将调用父类的equals (比如是Object),而Object的equals的比较是地址(return (this == obj);)
- 用户自定义类需要覆盖父类的equals()
一、理论补充
==比较的是计算机存储的是否相同,对于值由于二进制转换问题,可能出现错误,比如相减为0,但计算机算出一个极小数,或者对于接近0的,计算机理解为等于0.
而equals是方法,实际是人为定义的(当然前者也是人为定义的,但这里的人为定义是指程序员可查看,可修改的),是根据实际开发需要,比较对象的内容。
下面看几段源码理解一下。
Object.java
public boolean equals(Object obj) {
return (this == obj);
}
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;
}
AbstractList.java
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator<?> e2 = ((List<?>) o).listIterator();
while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
可以发现,对于Object这个终极父类而言,它的equals其实与==是等价的。而后续一些类中的equals其实相当于是重写了父类的方法,使其满足“判断内容是否相等”这一开发需求。
二、实例理解
String a = "1";
String b = "1";
String c = new String("1");
System.out.println(a==b);//true
System.out.println(a==c);//false
System.out.println(a.equals(b));//true
System.out.println(a.equals(c));//true
Object d =new Object();
System.out.println(d==a);//false
System.out.println(d.equals(a));//false
LinkedList<Integer> e = new LinkedList<>();
System.out.println(e==a);//error
System.out.println(e.equals(a));//false
System.out.println(null==null);//true
System.out.println(null.equals(null));//error
- ==对于引用类型比较的是地址
- 对于没有父子关系的两个对象,是不能用==来进行比较的。
- null.equals是无意义的,因为null显然没有equals这个方法,所以要比较要另寻出路。
总结
一句话理解:==比较的是计算机理解的内容,equals比较的是程序员理解的内容。