标签:栈内存 类重写 图片 lse ber https ext 开始 lin
原文引用https://www.dazhuanlan.com/2019/08/26/5d62fa816b34b/
== 和 equals是经久不衰的面试题,记得刚毕业的时候我也被问到过很多次,从最开始的一脸懵逼到最后的从容回答,本文我们就来分析下这两者之间的区别和联系。
为避免阅读疲劳,我这里先放上结论:
联系:
区别:
? | 基本数据类型 | 对象类型 |
---|---|---|
== | 比较值是否相同 | 比较引用地址是否相同 |
equals | - | equals()未被重写时比较对象的引用地址是否相同 equals()被重写后根据equals()实现逻辑而定 |
下面我们对以上的结论进行验证.
==:关系操作符,计算两个操作数之间的关系,返回一个boolean类型的结果
equals:Object类的一个方法,用来比较两个对象之间的关系,返回一个boolean类型的结果
从Object类中的equals()实现来看他们两个都是用来进行==的逻辑比较,并且都返回一个boolean值
但是仔细分析,
类型区分
的(基本数据类型,对象类型),所以不同的操作数会有不同的计算逻辑。子类重写
,所以实际的比较逻辑还是要根据重写内容来判断栗子:Date类的equals()被重写,实际判断的是时间戳的值是否相等
== 是一个关系操作符,他有两个操作数,操作数则分为两个大类:基本数据类型、引用数据类型。
直接上代码:
1 |
public class { |
运行结果如下:
1
2
3
4a==b:true
s1==s2:true
s1==s3:false
s3==s4:false
具体分析下输出的结果
a==b:操作数a、b是基本数据类型,使用==直接比较ab在栈内存中的值是否相等,故结果为true
s1==s2:操作数s1、s2为对象类型,String s1 = "A"
执行时,堆内存的常量池中会开辟空间存放A对象,栈内存中的引用变量s1会指向该对象的内存地址,s2创建时同样会指向常量池中的A,s1和s2指向的是同一个对象所以结果为true
s1==s3:s2是通过new()来创建对象,堆内存中会开辟空间存放对象,显然s1和s3的内存地址是不同的,s1指向常量池中的”A”,s2指向堆内存中的new String(“A”),所以结果为false
s3==s4:s3、s4是通过new()的方式创建的两个不同的对象,他们的内存地址不同,结果必然为false
总结:
==作为关系操作符,当操作数为基本数据类型时,直接判断值是否相同,
当操作数为对象类型时,判断两对象的内存地址是否相同
equals()方法时Object类的方法之一,这意味着所有Java类都继承了这一方法,并可以对他进行重写,比如String、Date、Integer…..
在上文我们通过Object类中equals()方法的源码可知,在未被重写时,equals()内部其实是调用了==进行判断。
下面我们看下String类对equals()的实现:
可见,String类的equals方法中,先判断两个对象是否内存地址相同,如果内存地址不同,则判断值是否相同
修改之前的代码测试如下:
1 |
public class Demo { |
运行结果如下:
1
2
3s1.equals(s2):true
s1.equals(s3):true
s3.equals(s4):true
具体分析下输出的结果
s1.equals(s2):相同的内存地址直接返回true
s1.equals(s3):内存地址不同,开始判断值是否相同,值都为”A”,返回true
s3.equals(s4):内存地址不同,开始判断值是否相同,值都为”A”,返回true
通过上面的栗子,发现了一种现象:内存地址相同的对象其值必定相同,而内存地址不同的对象,其值关系不确定
总结:
标签:栈内存 类重写 图片 lse ber https ext 开始 lin
原文地址:https://www.cnblogs.com/petewell/p/11410442.html