
应该会有不少初学的小伙伴上来就说:==比较的是地址值,equals比较的是值。这样回答对吗?
下面详细说下两者的区别。
==运算符
- 对于基本数据类型来说,比较的是数值
- 对于引用数据类型来说,比较的是地址值
下面代码示例了使用==来判断两种类型变量是否相等的结果。
public class EqualTest {
// ==
// 对于基本数据类型,比较的是值
public static void main(String[] args) {
int a = 65;
double b = 65.0;
char c = 'A';
String str1 = new String("helloworld");
String str2 = new String("helloworld");
System.out.println(a == b); //true
System.out.println(c == a); // true
// 因为str1和str2是2个对象,地址值不一样,输出false
System.out.println(str1 == str2);
}
}
equals方法
首先应该明确,equals是一个方法,只有对象才能调用,基本数据类型不能使用equals方法。其次,equals方法是定义在java.lang.Object类中的,Object类是所有类的超级父类,所以,每个对象都默认有一个继承自Object类的equals方法。
我们来看下Object类中的equals方法定义:
public boolean equals(Object obj) {
return (this == obj);
}
可以看到,equals方法底层也是使用==来进行比较的。
假设有一个自定义的User类,它有一个name成员变量,有一个初始化name成员变量的构造器。现在我们新建两个这样的User对象,其name属性都初始化为TOM,然后通过继承自Object类的equals方法,进行两个对象的比较。代码如下:
User user1 = new User("TOM");
User user2 = new User("TOM");
System.out.println(order1.equals(order2));
刚才说到,equals方法比较的是引用数据类型变量的地址值,由于user1和user2是两个不同的对象,其地址值不一样,所以上面代码会输出false。
继续看下面代码:
String str1 = new String("程序员技术之瞳");
String str2 = new String("程序员技术之瞳");
System.out.println(str1.equals(str2));
这次我们比较的是两个字符串,字符串的比较大家肯定很熟悉了,显然,上面代码会输出true。
那么,问题来了。String和我们自定义的Order类都是引用类型,为什么两者通过equals方法进行比较,输出结果不一样呢?
答案是:String重写了Object的equals方法,在重写的equals方法中,比较的是字符串的字符序列是否相等。上述str1和str2的字符序列都是“程序员技术之瞳”,所以会输出为true。
总结
下次面试官再问这个问题,可以这样回答:
- ==:当比较的是基本数据类型时,比较的是值;当比较的是引用数据类型时,比较的是地址值。
- equals:equals不能用于基本数据类型的比较;当比较的是引用数据类型时,默认也是比较地址值,只不过像
String、Date、File、包装类等都重写了Object类中的equals方法,重写后比较的不再是两个对象的地址值,而是自定义的相等标准(可以是某一个或某几个属性值相等)。在实际项目开发中,常常需要重写equals方法,相等条件由业务决定。
