惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
雷峰网
雷峰网
L
LINUX DO - 最新话题
N
News and Events Feed by Topic
月光博客
月光博客
T
The Blog of Author Tim Ferriss
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
Schneier on Security
Schneier on Security
S
Security @ Cisco Blogs
W
WeLiveSecurity
C
CXSECURITY Database RSS Feed - CXSecurity.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园_首页
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Latest news
Latest news
C
CERT Recently Published Vulnerability Notes
V
Vulnerabilities – Threatpost
F
Full Disclosure
博客园 - 司徒正美
AI
AI
MongoDB | Blog
MongoDB | Blog
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Cloudflare Blog
博客园 - 三生石上(FineUI控件)
T
Tenable Blog
H
Help Net Security
J
Java Code Geeks
H
Heimdal Security Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Project Zero
Project Zero
P
Privacy International News Feed
Forbes - Security
Forbes - Security
阮一峰的网络日志
阮一峰的网络日志
H
Hackread – Cybersecurity News, Data Breaches, AI and More
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
A
About on SuperTechFans
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
T
Troy Hunt's Blog
P
Proofpoint News Feed
Scott Helme
Scott Helme
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

Java技术经验分享

生产故障处理SOP分享 | Java技术经验分享 系统稳定性建设实践总结【转载】 | Java技术经验分享 valine访问leancloud国际版异常,评论失效修复 | Java技术经验分享 匆匆忙忙的2021 | Java技术经验分享 聊一下换工作 | Java技术经验分享 IoT系列(2):WIFI设备常见配网方案介绍 | Java技术经验分享 IoT系列(1):什么是物联网 | Java技术经验分享 Java8特性2 - StreamApi | Java技术经验分享 Java8特性1 - lambda表达式&函数式接口 | Java技术经验分享 设计模式(5)-适配器模式 | Java技术经验分享 设计模式(4)-建造者模式 | Java技术经验分享 设计模式(3)-原型模式与浅拷贝和深拷贝 | Java技术经验分享 设计模式(2)-工厂模式图文介绍 | Java技术经验分享 设计模式(1)-带你了解3类8种单例模式 | Java技术经验分享 Java时间处理5---Java8中时区相关类库介绍 | Java技术经验分享 Java时间处理4---Java8中LocalDate、LocalTime、LocalDateTime介绍 | Java技术经验分享 Java时间处理3---Java8中Instant、Duration、Period、Clock介绍 | Java技术经验分享 一些有意思的问答 | Java技术经验分享 Nacos系列博客说明 | Java技术经验分享 菜鸡程序员的2019年度总结 | Java技术经验分享 Java中“附近的人”实现方案讨论及代码实现 | Java技术经验分享 Java时间处理2----时区TimeZone类方法探究(Java8以前) | Java技术经验分享 Java时间处理1----Date和Calendar方法探究(Java8以前) | Java技术经验分享 FastJson中JSONString、JavaBean、JSONObject、JSONArray的转换关系及API示例 | Java技术经验分享 2019.11软考软件设计师归来心得体会及复习备考指南 | Java技术经验分享 你还没用过“约定式提交”吗?那你赶紧来补补知识吧 | Java技术经验分享 教你如何看懂UML中的类图及类图中的关系 | Java技术经验分享 设计模式总览 | Java技术经验分享 萌新入门Github请看这里,学不会远程教 | Java技术经验分享 Hexo的工作原理探究 | Java技术经验分享 Hexo-theme-butterfly修改调整记录教程 | Java技术经验分享 排序8:基数排序 | Java技术经验分享 排序7:归并排序 | Java技术经验分享 排序6:快速排序 | Java技术经验分享 排序5:冒泡排序 | Java技术经验分享 排序4:堆排序 | Java技术经验分享 排序3:选择排序 | Java技术经验分享 排序2:希尔排序 | Java技术经验分享 排序1:直接插入排序 | Java技术经验分享 推荐一款博客一文多发的良心工具OpenWrite | Java技术经验分享 近期学习计划 | Java技术经验分享 Nacos(九):Nacos集群部署和遇到的问题 | Java技术经验分享 Nacos(八):Nacos持久化 | Java技术经验分享 Nacos(七):Nacos共享配置 | Java技术经验分享 Nacos(六):多环境下如何“管理”及“隔离”配置和服务 | Java技术经验分享 Nacos(五):多环境下如何“读取”Nacos中相应的配置 | Java技术经验分享 Nacos(四):SpringCloud项目中接入Nacos作为配置中心 | Java技术经验分享 Nacos(三):Nacos与OpenFeign的对接使用 | Java技术经验分享 Nacos(二):SpringCloud项目中接入Nacos作为注册中心 | Java技术经验分享 Nacos(一):Nacos介绍 | Java技术经验分享 20190719小组分享 | Java技术经验分享 Java中equals和HashCode方法的分析 | Java技术经验分享 Java中的自动拆装箱、装箱缓存 | Java技术经验分享 About-blog | Java技术经验分享 Java中的编译、反编译和反编译工具全家桶分享 | Java技术经验分享 finalize()的生命周期(执行过程) | Java技术经验分享 Java关键字之final、finally与finalize方法 | Java技术经验分享 Java中重写、重载 | Java技术经验分享 Java中面向对象的三大特征:继承、封装、多态 | Java技术经验分享 DockerFile介绍 | Java技术经验分享 Docker环境下安装Gitlab | Java技术经验分享 Docker中私有仓库的搭建流程 | Java技术经验分享 Centos7下两种方式安装Docker-CE | Java技术经验分享 Vert.x创建一个Http服务 | Java技术经验分享 Vert.x创建TCP服务端及客户端 | Java技术经验分享 Vert.x Core(二)- Event Bus(事件总线) | Java技术经验分享 Vert.x-Core(一)- 基础篇 | Java技术经验分享 SpringBoot项目中实现国际化 | Java技术经验分享 Vert.x介绍 | Java技术经验分享 毕设选题项目本地运行环境搭建教程 | Java技术经验分享 Jupyter Notebooks的安装和使用介绍 | Java技术经验分享 算法笔试题:1元,5元,10元,20元,50元、100元面值人民币组合给定x元的问题 | Java技术经验分享 Quartz学习总结 | Java技术经验分享 SpringBoot2.x集成Redis | Java技术经验分享 SpringBoot2.x集成MongoDB | Java技术经验分享 [SpringCloud学习] - 浅谈微服务架构 | Java技术经验分享 基于hexo和coding免费搭建个人博客网站 | Java技术经验分享 Hello World | Java技术经验分享
Java中==和equals方法的分析 | Java技术经验分享
文章作者: LarsCheng · 2019-06-17 · via Java技术经验分享

前言

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

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

联系:

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

区别:

  • ==既可以比较基本数据类型,亦可用在对象之间。equals()只能比较对象间的关系
  基本数据类型 对象类型
== 比较值是否相同 比较引用地址是否相同
equals - equals()未被重写时比较对象的引用地址是否相同
equals()被重写后根据equals()实现逻辑而定

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

两者的联系

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

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

Object类中的equals()实现

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

但是仔细分析,

  • ==的操作数是有类型区分的(基本数据类型,对象类型),所以不同的操作数会有不同的计算逻辑。
  • 而equals()是Object一个方法,既然是基类方法那么就可以被子类重写,所以实际的比较逻辑还是要根据重写内容来判断

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

Date类中被重写的equals()

==的使用

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

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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";
String s2 = "A";
String s3 = new String("A");
String s4 = new String("A");
System.out.println("s1==s2:"+(s1==s2));
System.out.println("s1==s3:"+(s1==s3));
System.out.println("s3==s4:"+(s3==s4));
}
}

运行结果如下:

1
2
3
4
a==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()

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

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

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

String类对equals()的实现

可见,String类的equals方法中,先判断两个对象是否内存地址相同,如果内存地址不同,则判断值是否相同
修改之前的代码测试如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class Demo {
public static void main(String[] args) {

String s1 = "A";
String s2 = "A";
String s3 = new String("A");
String s4 = new String("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)));
}
}

运行结果如下:

1
2
3
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()方法。