面试说说:== 和 equals 能说多少说多少

简介: 面试就离不开面试题,如果我是面试者能立马想到的一个面试题就是上面说的这个了,所以今天就以我这个 1 年工作经验的菜鸡,分享我对本题的见解。


1、==


先来聊聊双等号int a = 10;int b = 20;int c = 10;// falseSystem.out.println(a == b);// trueSystem.out.println(a == c);

它是 Java 程序语言中的运算符,隶属于比较运算符,其用于判断两个变量或者常量的大小,比较的结果是一个布尔值(true 或 false)。


比较时会出现两种情况:


  1. 基本类型比较
  2. 引用类型比较


基本类型比较:对于基本类型,那比较的就是值了。

int a = 10;
int b = 20;
int c = 10;
// false
System.out.println(a == b);
// true
System.out.println(a == c);


上述代码结果表明,用 == 比较基本类型变量时,只有变量的值相同时,才返回 true。


引用类型比较:引用类型,比较的是引用所指向的地址。


User user01 = new User();
User user02 = new User();
User user03 = user01;
// false
System.out.println(user01 == user02);
// true
System.out.println(user01 == user03);
// 地址
// cn.baiqi.myjava.methods.User@dfd3711
System.out.println(user01);
// cn.baiqi.myjava.methods.User@42d3bd8b
System.out.println(user02);
// cn.baiqi.myjava.methods.User@dfd3711
System.out.println(user03);


上述代码结果表明,user01 和 user03 的引用地址相同,所以 == 比较才返回 true,user01 和 user02 引用地址不同,所以才返回 false。


对于双等号比较引用类型还有一个特例,看下面代码。

// 定义三个引用类型变量
Integer integer01 = 10;
Integer integer02 = 100;
Integer integer03 = 10;
// false
System.out.println(integer01 == integer02);
// true
System.out.println(integer01 == integer03);
// 打印出变量地址
// java.lang.Integer@a
System.out.println(integer01.getClass().getName() + '@' + Integer.toHexString(integer01.hashCode()));
// java.lang.Integer@64
System.out.println(integer02.getClass().getName() + '@' + Integer.toHexString(integer02.hashCode()));
// java.lang.Integer@a
System.out.println(integer03.getClass().getName() + '@' + Integer.toHexString(integer03.hashCode()));


结果和上一个案例又有点不一样了,好像对于这种引用类型,双等号比较的是值,而不是其所指向的引用地址一样。


其实其内部还是比较的地址,只不过 Integer 类型内部有一个缓存数组,它会缓存 -128 - 127 之间的数值。如果创建的 Integer 类型变量值符合其区间,那么引用变量所指向的地址都是该区间的值,不会另外创建。


Integer 内部缓存数值的代码。


image.png


2、equals


再来聊聊 equals。equals 是 Object 类中的一个方法,又因为 Object 是一个超类,所以任何对象都是可以调用该方法。在不重写该方法的情况下,其功能是比较两个对象的引用是否相等。


Object 类中 equals 方法源码。


image.png


很明显其底层比较的是两个引用类型所指向的地址是否相等,案例如下。


User user01 = new User();
User user02 = new User();
User user03 = user01;
// false
System.out.println(user01.equals(user02));
// true
System.out.println(user01.equals(user03));
// 地址
// cn.baiqi.myjava.methods.User@dfd3711
System.out.println(user01);
// cn.baiqi.myjava.methods.User@42d3bd8b
System.out.println(user02);
// cn.baiqi.myjava.methods.User@dfd3711
System.out.println(user03);


在 Java 中,String 和 Integer 类型内部重写了 equals 方法,其调用 equals 方法比较的就是值是否相等,源码如图:


image.png


示例代码如下。

String str01 = "J3-西行";
String str02 = "混迹互联网圈子的程序员";
String str03 = new String("J3-西行");
// false
System.out.println(str01.equals(str02));
// true
System.out.println(str01.equals(str03));


结果表明,String 类型重写 equals 方法后,只会比较值是否相等与内存地址无关。


通常,我们自己在重写 equals 方法时也是要遵循一定条件的,如下:


  • 自反性:对任意 x ,x.equals( x ) 一定返回 true。
  • 对称性:对任意 x 和 y ,如果 y.equals( x ) 返回 true ,则 x.equals( y ) 也返回 true
  • 传递性:对任意的 x,y,z,如果 x.equals( y ) 返回 true,y.equals( z ) 返回 true 则 x.equals( z ) 一定返回 true。
  • 一致性:对任意 x 和 y ,如果对象中用于等价比较的信息没有改变,那么无论调用 x.equals( y ) 多少次,返回的结果应该保持一致,要么一直是 true,要么一直是 false。
  • 非空性:对任何不是 null 的 x,x.equals( null ) 一定返回 false。


3、两者对比


根据上面 1、2 节的内容,我们归纳对比出如下结果:


两者都是返回布尔类型结果(true 或 false)。

== 是 Java 提供的操作符,equals 是 Object 超类的一个方法。

== 在比较引用类型和基本数据类型时,功能不一样(一个比较地址,一个比较值)。

equals 在未重写的情况下是用来比较两个对象地址是否相等,本质上和 == 比较引用类型效果一样。


4、我的面试答案


面试官你好,我先说一下我对 == 的理解:


== 是 Java 程序语言定义的一个运算符,用于比较两者是否相等,返回一个布尔类型值(true 或 false)。如果 == 两边比较的是基本数据类型的话,则比较变量的值,两者相等返回 true 反之返回 false;如果两边比较的引用类型,则比较的是引用变量所指的是否是同一个内存地址,是则返回 true 反之 false。


对于 equals 的理解是:


equals 是 Object 超类的一个方法,其功能是比较两个对象内存地址是否相等。


Java中包装类型都重写了 equals 方法,将其实现成值比较,而不是地址比较,因为对于包装类型我们对值的比较实用性大于对地址的比较。


在重写 equals 方法时我们也应该遵循其自反性、对称性、传递性、一致性和为空性,才能说是一个合格的 equals 方法。


最后在说一下两者最大的一个区别可以说是一个为运算符,一个为方法,并且 == 既可以比较引用类型对象也可以比较基本类型,而 equals 只能比较引用类型对象。


到这里,内心窃喜,没有被难道。


今天的内容到这里就结束了,关注我,我们下期见

目录
相关文章
|
7月前
|
存储 Java
【面试题精讲】为什么重写equals时必须重写hashCode方法?
【面试题精讲】为什么重写equals时必须重写hashCode方法?
关于==和equals的区别和联系,面试这么回答就可以
关于==和equals的区别和联系,面试这么回答就可以
|
10月前
|
存储 IDE Java
【java面试题】- 为什么重写 equals() 时必须重写 hashCode() 方法?
为什么重写 equals() 时必须重写 hashCode() 方法?
76 0
|
10月前
|
存储 Java 对象存储
【Java面试】为什么重写equals方法必须同时重写HashCode方法?
【Java面试】为什么重写equals方法必须同时重写HashCode方法?
41 0
|
11月前
|
Java
【Java面试宝典】常用类中的方法重写|equals方法与逻辑运算符==的区别
【Java面试宝典】常用类中的方法重写|equals方法与逻辑运算符==的区别
70 0
|
Java
Java 最常见的面试题:两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
138 0
|
存储 Java
LruCache使用,基本数据类型 & 引用类型,面试==和equals的区别 本质,onCreate 和onResume 区别,
LruCache使用,基本数据类型 & 引用类型,面试==和equals的区别 本质,onCreate 和onResume 区别,
62 0
|
存储 Java 程序员
面试点:Java 中 hashCode() 和 equals() 的关系
面试点:Java 中 hashCode() 和 equals() 的关系
162 0
|
存储 Java 程序员
面试点:Java 中 hashCode() 和 equals() 的关系
面试点:Java 中 hashCode() 和 equals() 的关系
122 0