在Java开发中,经常会比较两个对象的是否相等,如
int i1 = 1;
int i2 = 2;
if(i1 == i2){
//do something
}
String s1 = new String("hello");
String s2 = new String("hello");
if(s1.equals(s2)){
//do something
}
但是为什么基本数据类型要使用==,而引用类型要使用equals方法呢?
这是因为==在比较基本数据类型时,比较的是数值,而在比较引用类型时,比较的是引用类型指向对象的内存地址。所以基本类型不论怎么赋值,使用==比较的都是基本类型的值
一般而言,当一个类中的所有属性都相同时,比较的期望结果是这两个对象是相等的。比如:
package demo;
//省略setter、getter、全参数构造函数
public class Person {
String name;//姓名
String sex;//性别
Integer age;//年龄
public static void main(String[] args) {
Person p1 = new Person("小明", "男", 10);
Person p2 = new Person("小明", "男", 10);
System.out.println("p1 == p2 " + (p1 == p2));
System.out.println(p1);
System.out.println(p2);
}
}
//运行结果:
//p1 == p2 false
//demo.Person@1b6d3586
//demo.Person@4554617c
p1 == p2期望的执行结果是true,而实际运行后发现结果是false。继续观察后续输出可以发现,两个对象的内存地址是不一致的,所以比较不同的内存地址必然会输出false
接着尝试使用equals方法
public static void main(String[] args) {
Person p1 = new Person("小明", "男", 10);
Person p2 = new Person("小明", "男", 10);
System.out.println("p1.equals(p2) " + p1.equals(p2));
}
//运行结果:
//p1.equals(p2) false
可以发现,equals并没有输出我们所期望的true
equals方法存在于java.lang.Object中,Object类是所有Java类的父类,也就是说如果没有重写equals方法,调用的将会是Object中的equals。而查看Object类源码可以发现类中的equals的默认实现是==
//Object类中equals方法的实现
public boolean equals(Object obj) {
return (this == obj);
}
所以上面的Person类如果没有重写equals的话,p1.equals(p2)与p1 == p2是没有区别的
想要p1.equals(p2)返回我们所期望的true,必须重写equals方法
package demo;
//省略setter、getter、全参数构造函数
public class Person {
String name;//姓名
String sex;//性别
Integer age;//年龄
}
@Override
public boolean equals(Object obj) {
//1.判断是否都是Person类的对象
if(!(obj instanceof Person)) {
return false;
}
Person person = (Person) obj;
//2.判断对象内存地址是否相等。如果相等,可以认为两个对象相等
if (this == person) {
return true;
}
//3.按照我们制定的规则返回结果
//这里制定的规则是只要姓名、性别、年龄相同,就认为两个对象相同
//由于String类与Integer类也分别实现了自己的equals方法,所以可以直接使用
if(!person.getName().equals(this.name) ){
return false;
}
if(!(person.getSex().equals(this.sex))){
return false;
}
if(!(person.getAge().equals(this.age))){
return false;
}
return true;
}
最后再运行一遍
System.out.println("p1.equals(p2) " + p1.equals(p2));
System.out.println("p1 == p2 " + (p1 == p2));
//运行结果
//p1.equals(p2) true
//p1 == p2 false
结论:
==用于判断基本数据类型的值是否相等,如果作用于引用类型,则是判断引用类型所指向的对象的内存地址是否相等
equals用于重写了equals方法的类的对象的判等操作,具体判等逻辑由该类自己制定,如果该类没有重写equals,则默认执行==