无意中网上面试题中看到该问题,虽然自己自学的时候已经遇到过,但是大概没有投入合理的时间,此时我已经忘了他们的区别,以此文记录加深一下记忆:
1、这个两个方法来源于哪里?
- “==”这算于java的运算符中的关系运算符,不管是新手学习还或者使用,最常见的就是if(3 == 4)或者if(num1 = num2)类似的比较,所以你会认为"=="就是比较数值的大小,下面以java in think中的代码演示举例:
public class Equivalence{
public static void main(String[] args){
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
}
}
输出:
false
true
原因:如果对"=="没有进一步理解的话,有可能得出与上面相反的结果,造成这种原因,因为受到基本数据类型使用==比较影响,造成先入为主的思想,以为是比较大小值,其实这里需要强调的是:对象使用==是比较对象的引用,也就是对象内存地址,所以产生了上面的结果。
- 接着谈谈equals,通过java的API文档中查询可以知道它是Object类提供的方法,而关于方法的描述有一段话“
Object
类的equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值x
和y
,当且仅当x
和y
引用同一个对象时,此方法才返回true
(x == y
具有值true
)。 ”,说白了Object的equals默认比较也是对象的引用,与==是一样的,需要注意的是基本数据类型不能使用equals,它是针对对象的方法。
2、如果equals和==功能相同,为什么提供equals功能?
实例1:
public class EqualsMethod {
public static void main(String[] args){
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1.equals(n2));
}
}
结果:
true
原因:封装类Boolean完成了对equals的复写,比较的是数值的大小,可以参考相关源码。
实例2:
public class StringEquals{
public static void main(String[] args){
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
String s3 = new String("efg");
String s4 = new String("efg");
System.out.println(s3 == s4);
System.out.println(s3.equals(s4));
}
}
结果:
true
true
false
true
原因:同上,唯一你可能觉的意外的就是第一个结果,s1和s2理论上应该是两个对象,但实际上这涉及到字符串的常量池的机制,就是字符串在创建后会放置在一个常量池中,每一次创建都会在池中判断是否存在该字符串常量,如果有直接拿来使用。
3、自己根据需要复写equals。
如果我们在自己定义类中不对equals进行复写,默认调用Object中默认比较对象内存地址,但如果我有其它需求,比如想比较人,认为名字和年龄都相同就是同一个人,写法如下:
代码实例:
public class Equals{
public static void main(String[] args){
Person p1 = new Person("jack",18);
Person p2 = new Person("jack",18);
if(p1.equals(p2)){
System.out.println("同一人");
}
}
}
class Person{
private String name;
private int age;
Person(String name,int age) {
this.name = name ;
this.age = age;
}
public boolean equals(Object obj) {
if(obj instanceof Person){
Person p = (Person)obj;
return (name == p.name && age == p.age);
}else{
return false;
}
}
}
结果:
同一人
4、总结:"=="对于对象来说是比较的内存地址,而Object类中默认equlas也是同样的功能,但是需要注意的是API中的部分类对它进行了复写,比如常用的String,比较的是字符串内容是否相同。