看到==、equals()就认为比较简单,随便看了一眼就过了,其实你并没有深入去了解二者的区别。这个问题在面试的时候出现的频率比较高,而且据统计有85%的人理直气壮的答错。所以理解==与equals()的区别很有必要。
二、==运算符==可以使用在基本数据类型变量和引用数据类型变量中。
1、基本数据类型:比较两个变量是否相等(不比较数据类型,只看值,因为会类型自动提升)
2、引用数据类型:比较两个对象的地址值是否相等。
public class Test {
public static void main(String[] args) {
int a=10;
int b=10;
double c=10.00;
System.out.println(a==b);//true
System.out.println(a==c);//true
String str1="123";
String str2="123";
System.out.println(str1==str2);//true
String str3=new String("123");
String str4=new String("123");
System.out.println(str3==str4);//false
}
}
对于8种基本数据类型(byte,short,int,long,float,double,char,boolean)的值而言,它们都是存储在常量池中,而str1、str2的字符串 "123" 也同样在常量池中,而一个常量只会对应一个地址,因此不管是再多的数据都只会存储一个地址,所以所有他们的引用都是指向的同一块地址,因此基本数据类型和String常量是可以直接通过==来直接比较的。
而str3、str4分别在堆内存中创建的两个对象,地址值自然就不相同了。
三、equals()方法Object类定义的equals()方法:equals()是一个方法,不是数据类型,所以他只适用于引用数据类型,该方法主要用于比较两个对象的内容是否相等。
在Object类型的equals方法是直接通过==来比较的,和==是没有任何区别的。
那为什么又要说equlas和==的区别呢,是因为所有的类都直接或间接地继承自java.lang.Object类。像String、Date、Math、File、包装类等大部分类都重写了Object的equals()方法。重写以后,就不是比较两个对象的地址值是否相同了,而是比较两个对象里面的内容是否相等。
重写equlas方法
String类重写的equals()方法:* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
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;
}
可以看到重写的方法内用char[] 数组进行一个一个的比较,并不是用==进行比较。
我们在重写equals()方法时必须要遵循如下几个规则:
- 自反性:x.equals(x)必须返回是true。
- 对称性:如果x.equals(y),返回时true,那么y.equals(x)也必定返回为true。
- 传递性:如果x.equals(y)返回的true,而且y.equals(z)返回是true,那么z.equals(x)返回的也是true。
- 一致性:如果x.equals(y)返回是true,只要x和y的内容一直不变,不管重复x.equals(y)多少次,返回都是true
- 任何情况下,x.equals(null),永远返回是false,x.equals(与x是不同类型的对象),也永远返回是false。
对于上面几个规则,我们在使用的过程中最好遵守,避免出现意想不到的错误。
四、小结1、==比较的数值是否相等和对象地址是否相等。
2、equals()方法比较的对象内容是否相等(前提是重写了父类的方法)。
3、一般除了自定义的类除外,大部分类都重写了equals()方法。



