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是 ...
随机推荐
- Mybatis-plus的使用
接口mapper需要继承BaseMapper<要操作的类>外加@Mapper mport org.apache.ibatis.annotations.Mapper; import org. ...
- idea 开发中常用的26个快捷键!
------- udea中窗口最大化---->Windows 上: Ctrl+Shift+F12 -------- ctrl+z撤回代码 ------- c ...
- vue-cli+vue 2.0+element-ui+vue-router+echarts.js开发后台管理系统项目教程
一.首先使用npm创建vue项目框架: 1.安装vue-cli: $ npm install --global vue-cli 2.初始化项目:$ npm init webpack 项目名 3 ...
- java JVM原理讲解和调优和gc
- Codeforces 1009E
题意略. 思路: 比如现在n = 11.那么我们观察a[1.....n]的出现次数: a[1]:2 ^ 10 + 10 * 2 ^ 9 a[2]:2 ^ 9 + 9 * 2 ^ 8 a[3]:2 ^ ...
- CentOS重置MySQL root密码的方法
1.修改MySQL的登录设置: # vim /etc/my.cnf 在[mysqld]的段中加上一句:skip-grant-tables 例如: [mysqld] skip-grant-tables ...
- javascript之操作数组方法
掌握如何操作数组,会让你的开发变得更加高效 1.栈和队列方法(以下四个方法都改变原数组) arr.push() //接受任意类型的参数,逐个添加到数组的末尾,并返回数组的长度 改变原数组 arr.po ...
- [转]Android中设置TextView的颜色setTextColor
[转自]http://txlong-onz.iteye.com/blog/1249609 Android中设置TextView的颜色setTextColor android中设置TextView的颜色 ...
- 【Linux命令】modprobe命令
modprobe(module probe)命令 用于自动处理可载入模块. 1)语法 modprobe [-acdlrtvV][--help][模块文件][符号名称 = 符号值] 2)补充 modpr ...
- URAL-1982-Electrification Plan最小生成树或并查集
Electrification Plan 题意:在一个无向图中,给你几个源点,找出把所有点连接到源点后最小的消费: 可以利用并查集: 先用结构体把每个边存起来,再按照消费大小排序.之后从消费小的到大的 ...