java equals 中文_Java 中==与equals()的分析-Go语言中文社区

前言

== 和 equals是经久不衰的面试题,记得刚毕业的时候我也被问到过很多次,从最开始的一脸懵逼到最后的从容回答,本文我们就来分析下这两者之间的区别和联系。

为避免阅读疲劳,我这里先放上结论:

联系:

两者都被用来进行比较操作

当equals()未被重写时,两者的用途和比较的内容相同,即都是比较对象的引用地址是否相同

区别:

==既可以比较基本数据类型,亦可用在对象之间。equals()只能比较对象间的关系基本数据类型

对象类型==

比较值是否相同

比较引用地址是否相同

equals

-

equals()未被重写时比较对象的引用地址是否相同

equals()被重写后根据equals()实现逻辑而定

下面我们对以上的结论进行验证.

两者的联系

==:关系操作符,计算两个操作数之间的关系,返回一个boolean类型的结果

equals:Object类的一个方法,用来比较两个对象之间的关系,返回一个boolean类型的结果

8fd11c7aaff7f3669cf9529bb01c85d0.png

从Object类中的equals()实现来看他们两个都是用来进行==的逻辑比较,并且都返回一个boolean值

但是仔细分析,

==的操作数是有类型区分的(基本数据类型,对象类型),所以不同的操作数会有不同的计算逻辑。

而equals()是Object一个方法,既然是基类方法那么就可以被子类重写,所以实际的比较逻辑还是要根据重写内容来判断

栗子:Date类的equals()被重写,实际判断的是时间戳的值是否相等

79c1b645416e4b97bb0264e4f47c8d79.png

==的使用

== 是一个关系操作符,他有两个操作数,操作数则分为两个大类:基本数据类型、引用数据类型。

直接上代码:

public class Demo {

public static void main(String[] args) {

int a = 10;

int b = 10;

System.out.println("a==b:"+(a==b));

String s1 = "A";//栈内存中对象引用变量s1指向常量池中的A

String s2 = "A";//栈内存中对象引用s2指向常量池中的A

String s3 = new String("A");//栈内存中对象引用s3指向堆内存中的A对象

String s4 = new String("A");//栈内存中对象引用s4指向堆内存中的另一个A对象

System.out.println("s1==s2:"+(s1==s2));

System.out.println("s1==s3:"+(s1==s3));

System.out.println("s3==s4:"+(s3==s4));

}

}

运行结果如下:

a==b:true

s1==s2:true

s1==s3:false

s3==s4:false

具体分析下输出的结果

1229e241fdba005fabb0a6d049757749.png

a==b:操作数a、b是基本数据类型,使用==直接比较ab在栈内存中的值是否相等,故结果为true

s1==s2:操作数s1、s2为对象类型,String s1 = "A"执行时,堆内存的常量池中会开辟空间存放A对象,栈内存中的引用变量s1会指向该对象的内存地址,s2创建时同样会指向常量池中的A,s1和s2指向的是同一个对象所以结果为true

s1==s3:s3是通过new()来创建对象,堆内存中会开辟空间存放对象,显然s1和s3的内存地址是不同的,s1指向常量池中的"A",s3指向堆内存中的new String(“A”),所以结果为false

s3==s4:s3、s4是通过new()的方式创建的两个不同的对象,他们的内存地址不同,结果必然为false

总结:

==作为关系操作符,当操作数为基本数据类型时,直接判断值是否相同,

当操作数为对象类型时,判断两对象的内存地址是否相同

equals()

equals()方法时Object类的方法之一,这意味着所有Java类都继承了这一方法,并可以对他进行重写,比如String、Date、Integer…

在上文我们通过Object类中equals()方法的源码可知,在未被重写时,equals()内部其实是调用了==进行判断。

下面我们看下String类对equals()的实现:

7ecd3b69f7e5f5db39c1dbb1e23c82a4.png

可见,String类的equals方法中,先判断两个对象是否内存地址相同,如果内存地址不同,则判断值是否相同

修改之前的代码测试如下:

public class Demo {

public static void main(String[] args) {

String s1 = "A";//栈内存中对象引用变量s1指向常量池中的A

String s2 = "A";//栈内存中对象引用s2指向常量池中的A

String s3 = new String("A");//栈内存中对象引用s3指向堆内存中的A对象

String s4 = new String("A");//栈内存中对象引用s4指向堆内存中的另一个A对象

System.out.println("s1.equals(s2):"+(s1.equals(s2)));

System.out.println("s1.equals(s3):"+(s1.equals(s3)));

System.out.println("s3.equals(s4):"+(s3.equals(s4)));

}

}

运行结果如下:

s1.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

通过上面的栗子,发现了一种现象:内存地址相同的对象其值必定相同,而内存地址不同的对象,其值关系不确定

总结:

equals()方法在Object类中作用于==相同,但是大部分的类都对equals()进行了重写,所以要找到equals真正的判断逻辑就得看他的方法实现。同样的我们自己创建的实体类或者其他对象都可以自定义equals()方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值