一、前言

说到==和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的区别(一)的更多相关文章

  1. Java基础系列-equals方法和hashCode方法

    原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述         equals方法和hashCode方法都是有Object类定义的. publi ...

  2. 夯实Java基础系列9:深入理解Class类和Object类

    目录 Java中Class类及用法 Class类原理 如何获得一个Class类对象 使用Class类的对象来生成目标类的实例 Object类 类构造器public Object(); register ...

  3. 夯实Java基础系列13:深入理解Java中的泛型

    目录 泛型概述 一个栗子 特性 泛型的使用方式 泛型类 泛型接口 泛型通配符 泛型方法 泛型方法的基本用法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型方法总结 泛型上下边界 泛型常见面试 ...

  4. Java基础系列1:深入理解Java数据类型

    Java基础系列1:深入理解Java数据类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括四个 ...

  5. Java基础系列2:深入理解String类

    Java基础系列2:深入理解String类 String是Java中最为常用的数据类型之一,也是面试中比较常被问到的基础知识点,本篇就聊聊Java中的String.主要包括如下的五个内容: Strin ...

  6. 夯实Java基础系列10:深入理解Java中的异常体系

    目录 为什么要使用异常 异常基本定义 异常体系 初识异常 异常和错误 异常的处理方式 "不负责任"的throws 纠结的finally throw : JRE也使用的关键字 异常调 ...

  7. 夯实Java基础系列11:深入理解Java中的回调机制

    目录 模块间的调用 多线程中的"回调" Java回调机制实战 实例一 : 同步调用 实例二:由浅入深 实例三:Tom做题 参考文章 微信公众号 Java技术江湖 个人公众号:黄小斜 ...

  8. 夯实Java基础系列14:深入理解Java枚举类

    目录 初探枚举类 枚举类-语法 枚举类的具体使用 使用枚举类的注意事项 枚举类的实现原理 枚举类实战 实战一无参 实战二有一参 实战三有两参 枚举类总结 枚举 API 总结 参考文章 微信公众号 Ja ...

  9. Java基础系列--HashMap(JDK1.8)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...

随机推荐

  1. 网站设计:将Footer固定在浏览器底部

    在设计网站的时候,如果你某个页面的内容没有满屏,那你的footer会离浏览器底部很远,整体看起来很难看,这里用JavaScript提供一种方法来将footer固定在浏览器底部. function fi ...

  2. 字符串匹配算法之————KMP算法

    上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符.但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博 ...

  3. caffe学习网站

    1.http://www.cnblogs.com/denny402/tag/caffe/

  4. 我常用的一些linux命令

    之前做过两年的运维,用过很多命令,深切体会到某些linux命令熟练掌握后对效率提升有多大.举个简单的例子,在做了研发后经常会有跑一些数据,对于结果数据的处理,我们的产品同学一般都习惯于用excel做统 ...

  5. excel表格导出之后身份证号列变成了科学计数法

    excel表格导出之后身份证号列变成了科学计数法 解决:写sql查询出所有数据,并在身份证列添加字符,然后导出,将要复制的excel表格设置单元格格式问文本类型,然后复制粘贴,再把加入的字符删除,搞定 ...

  6. PHP工程师学Python数据类型

    一.背景 继上篇文章比较了PHP与Python语法之后,这周又学习了Python数据类型,准备从通过这篇文章给自己进行一些总结,也给其他读者一些参考. 二.内容概要 字符串(str) 列表(list) ...

  7. POJ1833 排列 调用全排列函数 用copy函数节省时间 即使用了ios同步代码scanf还是比较快

    排列 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21268   Accepted: 8049 Description 题 ...

  8. Ubuntu 18.04 安装 onedrive

    问题 在Ubuntu 18.04上安装Onedrive 问题背景 对于文档的同步,还是喜欢用Onedrive,主要因为Onedrive对文档的在线编辑支持很好. Onedrive初始免费容量5G,加上 ...

  9. CCPC-Wannafly Camp #2 (部分题解)

    L: New Game! 题目描述: Eagle Jump公司正在开发一款新的游戏.泷本一二三作为其员工,获得了提前试玩的机会.现在她正在试图通过一个迷宫. 这个迷宫有一些特点.为了方便描述,我们对这 ...

  10. Mysql高手系列 - 第8篇:详解排序和分页(order by & limit),及存在的坑

    这是Mysql系列第8篇. 环境:mysql5.7.25,cmd命令中进行演示. 代码中被[]包含的表示可选,|符号分开的表示可选其一. 本章内容 详解排序查询 详解limit limit存在的坑 分 ...