什么是==?
== 等于比较运算符,如果进行比较的两个操作数都是数值类型,即使他们的数据类型不相同,只要他们的值相等,也都将返回true.如果两个操作数都是引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象,才会返回true.(在这里我们可以理解成==比较的是两个变量的内存地址)
什么是equals()?
equals()方法是Object类的方法,在Object类中的equals()方法体内实际上返回的就是使用==进行比较的结果.但是我们知道所有的类都继承Object,而且Object中的equals()方法没有使用final关键字修饰,那么当我们使用equal()方法进行比较的时候,我们需要关注的就是这个类有没有重写Object中的equals()方法.
区别
== 是java提供的等于比较运算符,用来比较两个变量指向的内存地址是否相同.而equals()是Object提供的一个方法.Object中equals()方法的默认实现就是返回两个对象==的比较结果.但是equals()可以被重写,所以我们在具体使用的时候需要关注equals()方法有没有被重写.
坑
int 和 Integer
public static void main(String[] args) {
//-128 ~ +127 之间
Integer a = 5;
int b = 5;
Integer c = new Integer(5);
Integer d = 5;
System.out.println(a.equals(b));
System.out.println(a == b);
System.out.println(a.equals(c));
System.out.println(a == c);
System.out.println(a == d);
//-128 ~ +127 之外
a = 128;
b = 128;
c = new Integer(128);
d = 128;
System.out.println(a.equals(b));
System.out.println(a == b);
System.out.println(a.equals(c));
System.out.println(a == c);
System.out.println(a == d);
}
结果:
重点:
System.out.println(a == d); 同样的表达式,不同的值为什么结果不同
System.out.println(a == c); 与 System.out.println(a == d); 同样的对象类型,为什么复制方式不一样,比较结果不一样
System.out.println(a == c); 与 System.out.println(a.equals©); 不同的比较方式,结果为什么不同
解析思路:
首先我们看a,c,d三个变量的赋值方式,其中a和d的赋值方式都是直接赋值,没有调用new关键字,只有d的赋值方式调用了new关键字.然后我们在看赋值的具体数值,一组是5在-128 ~ +127 之间,另一组是128在/-128 ~ +127 之外.我们可以通过已知的不同点去阅读源码.(其中不同的比较方式为什么结果不同,这个可以猜出一定是Integer重写了equals()方法.)
结论:
赋值方式中如果调用了new关键字,一定会在内存中给你分配一个新的地址
给Integer类型赋值的时候,如果没有调用new关键字,并且值在-128与+127之间,包括-128和+127,那么指向的都是同一个内存位置.
Integer类中重写了equals()方法,使用equals()方法进行比较的时候,实际上比较的内存中最终指向的值的内存位置,不是直接比较变量的内存位置.
重写的equals()方法public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
小结:
本来想接着写下String的一些所谓的坑,但是感觉和文章的标题就有点不配了,实际上关于== 和equals已经说过了.包括int和Integer这个坑也不算是坑了.之所以产生不同的结果,只有一个重写equals()方法与本文标题有关,其它的应该是属于Integer类的初始化赋值范围了.我们需要记住的就是==比较的是世界的内存地址,是java提供的比较运算符,而equals()方法是Object中提供的方法,是可以被重写的,你也可以自己重写,所以在使用equals()方法时应该看看此类是如何重写的,仅此而已.