Java基础系列-深入理解==和equals的区别(一)
一、前言
说到==和equals的问题,面试的时候可能经常被问题到,有时候如果你真的没有搞清楚里边的原因,被面试官一顿绕就懵了,所以今天我们也来彻底了解一下这个知识点。
二、==和equals的作用
2.1 ==的作用
在java中我们用==来判断两个变量是否相等,但是会根据数据类型有所区别:
1.对于8种基础数据类型(byte、short、int、long、double、float、boolean、char)来说==是判断变量的数值是否相等。
byte y1 = 1, y2 = 1;
short s1 = 1, s2 = 1;
int i1 = 1, i2 = 1;
long l1 = 1, l2 = 1;
double d1 = 1, d2 = 1;
float f1 = 1, f2 = 1;
boolean b1 = true, b2 = true;
char c1 = 1, c2 = 1;
System.out.println("byte:y1==y2 " + (y1 == y2));
System.out.println("short:s1==s2 " + (s1 == s2));
System.out.println("int:i1==i2 " + (i1 == i2));
System.out.println("long:l1==l2 " + (l1 == l2));
System.out.println("double:d1==d2 " + (d1 == d2));
System.out.println("float:f1==f2 " + (f1 == f2));
System.out.println("boolean:b1==b2 " + (b1 == b2));
System.out.println("char:c1==c2 " + (c1 == c2));
对于引用类型,==比较的是引用的地址是否相等:
Object o1 = new Object();
Object o2 = o1;
Object o3 = new Object();
System.out.println("Object:o1 == o2 " + (o1 == o2));
System.out.println("Object:o1.equals(o2) " + (o1.equals(o2)));
System.out.println("Object:o1 == o3 " + (o1 == o3));
System.out.println("Object:o1.equals(o3) " + (o1.equals(o3)));
接下来我们来看看equals里的内部实现,其实还是调用的==:
总结:所以说对于==,当数据类型是8大基础类型时,比较的是(栈中)数值是否相等,当数据类型是引用类型时,比较的是对象的引用地址是否相等。这是通过jvm来自动判断的。
2.2 equals的作用
equals是object类中的一个方法,也就是说使用equals必须是对象类型,所以equals比较的是对象是否相当,默认情况上边已经说过了使用的就是==,但是别忘了equals是基类中的方法,是可以重写的,当我们重写的时候就可以实现不同的功能了。
那么对于字符串,也是一种引用类型,我们先来看看下面这个例子:
String str1 = "123",str2 = "123";
String str3 = new String("123");
String str4 = new String("123");
System.out.println("String:str1 == str2 " + (str1 == str2));
System.out.println("Object:str1.equals(str2) " + (str1.equals(str2)));
System.out.println("Object:str1 == str3 " + (str1 == str3));
System.out.println("Object:str1.equals(str3) " + (str1.equals(str3)));
System.out.println("Object:str3 == str4 " + (str3 == str4));
System.out.println("Object:str3.equals(str4) " + (str3.equals(str4)));
这里我们介绍一个概念,叫做字符串拘留池:由于字符串这种东西在我们的程序中非常的常用,每一个字符串都要创建对象,花费开销,但是通常字符串一般的我们只关心它的值是什么,所以jvm在这里做了一个优化,当字符串在拘留池(一块存储字符串的地方)里出现的时候,如果下次我们又用到了这个字符串,就直接返回池子里字符串的地址,因为值都是一样的,减少了开销,如果没有,就放进池子里,以备后来有用到的时候,相当于一个缓存了。
所以当我们执行String str1 = "123",str2 = "123"; 实际上两个变量指向的是同一个地址,所以自然的str1 == str2和str1.equals(str2)是一样的,都为true,没毛病。
当我们使用String str3 = new String("123");很明显示开辟了一块新的内存地址,只不过存储的值是123是一样的,所以str1 == str3是false,没毛病,但是按理说str1.equals(str3)也应该是false啊,之前不是说内部也是用的==吗,我们可以看一下字符串类中equals的实现:
很明显,在实现判断了地址是否相同以后,这里边又做了判断,字符串的值是否相等,如果相等就返回true,到这里为止,我们已经真相大白了,原来String类重写equals方法,判断的是字符串的值是否相等,而不仅仅是地址。所以自然的我们的str1.equals(str3) 是true了。
那么由此可知,str3 == str4 比较的是地址,明显不一样,因为是new了两个对象,所以返回false,str3.equals(str4)比较的是字符串的值,所以返回true,也没毛病。
总结:因为我们在对字符串比较的时候,往往关注的就是值一样不一样,所以java这样重写也是 很有必要的,所以我们一直推荐判断字符串相等用equals方法,而不是用==来判断。equals方法具体产生什么样的效果,完全看子类是怎么重写的,比如Date类,重写了equals方法,只要两个时间的getTime()时间戳一样,那么就相等,这也是符合我们的认知的。
所以,在我们以后需要判断两个对象相等的用equals的时候,我们可以完全根据自己的业务来重写equals方法,比如两个Person实例,如果id一样,我们就应该认为他们俩是相等,这个时候我们就可以重写equals方法,用id作比较来返回值。
三、总结
这次终于搞明白了==和equals的用法和作用,以后学什么东西还必须要深入理解一下内部原理才行,这样就不怕面试官再来搞事情了。
Java基础系列-深入理解==和equals的区别(一)的更多相关文章
- Java基础系列-equals方法和hashCode方法
原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述 equals方法和hashCode方法都是有Object类定义的. publi ...
- 夯实Java基础系列9:深入理解Class类和Object类
目录 Java中Class类及用法 Class类原理 如何获得一个Class类对象 使用Class类的对象来生成目标类的实例 Object类 类构造器public Object(); register ...
- 夯实Java基础系列13:深入理解Java中的泛型
目录 泛型概述 一个栗子 特性 泛型的使用方式 泛型类 泛型接口 泛型通配符 泛型方法 泛型方法的基本用法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型方法总结 泛型上下边界 泛型常见面试 ...
- Java基础系列1:深入理解Java数据类型
Java基础系列1:深入理解Java数据类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括四个 ...
- Java基础系列2:深入理解String类
Java基础系列2:深入理解String类 String是Java中最为常用的数据类型之一,也是面试中比较常被问到的基础知识点,本篇就聊聊Java中的String.主要包括如下的五个内容: Strin ...
- 夯实Java基础系列10:深入理解Java中的异常体系
目录 为什么要使用异常 异常基本定义 异常体系 初识异常 异常和错误 异常的处理方式 "不负责任"的throws 纠结的finally throw : JRE也使用的关键字 异常调 ...
- 夯实Java基础系列11:深入理解Java中的回调机制
目录 模块间的调用 多线程中的"回调" Java回调机制实战 实例一 : 同步调用 实例二:由浅入深 实例三:Tom做题 参考文章 微信公众号 Java技术江湖 个人公众号:黄小斜 ...
- 夯实Java基础系列14:深入理解Java枚举类
目录 初探枚举类 枚举类-语法 枚举类的具体使用 使用枚举类的注意事项 枚举类的实现原理 枚举类实战 实战一无参 实战二有一参 实战三有两参 枚举类总结 枚举 API 总结 参考文章 微信公众号 Ja ...
- Java基础系列--HashMap(JDK1.8)
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...
随机推荐
- 简单的JavaScript字符串加密解密
简单的JavaScript字符串加密解密 <div> <input type="text" id="input" autofocus=&quo ...
- Delphi - cxGrid设定字段类型为CheckBox
cxGrid设定字段类型为CheckBox 1:设定OraQuery属性 CachedUpdates设定为True: 双击打开OraQuery,选中Update SQLs页面,Insert.Updat ...
- 在Azure云上实现postgres主备切换
以下是工作上实现postgres主备切换功能所用到的代码和步骤,中间走了不少弯路,在此记录下.所用到的操作系统为centos 7.5,安装了两台服务器,hostname为VM7的为Master,VM8 ...
- DOM的高级操作-一种JS控制元素的视觉假象
1.运动中的边界处理(让其在一个指定区域内运动) 当元素的offsetLeft值超出一定距离或达到一个我们想要设置的边界值时,停止计时器. var timer; timer = setInterval ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu Tree and Permutation 找规律+求任意两点的最短路
Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- 通过对微信pc hook实现微信助手
本软件主要通过对pc端微信hook来实现的,微信版本2.6.8.52. 软件下载地址: http://blog.yshizi.cn/104.html 软件实现功能: 支持爆粉 支持文本消息群发 支持自 ...
- odoo12之应用:一、双因子验证(Two-factor authentication, 2FA)(HOTP,TOTP)附源码
前言 双因子认证:双因子认证(2FA)是指结合密码以及实物(信用卡.SMS手机.令牌或指纹等生物标志)两种条件对用户进行认证的方法.--百度百科 跟我一样"老"的网瘾少年想必一定见 ...
- Day004_Linux基础命令之特殊符号与正则表达式通配符
特殊符号: . 点 cd . 表示当前目录 ' '' 单引号,所见即所得 原封不动输出 " ""双引号,里面的特殊符号会被解析运行 `` ====$( ) 先运行() 里 ...
- NGINX的启停命令、以及动态加载配置文件的命令
-- 启动(不推荐):在nginx目录下有一个sbin目录,sbin目录下有一个nginx可执行程序../nginx -- 启动(指定配置文件,推荐)/usr/local/nginx/sbin/ngi ...
- 2019最新WEB全栈架构师第八期视频教程
下载链接:https://www.yinxiangit.com/117.html