前言

  在我们Java面试中,基础知识基本上比定会考核的点,而“==和equals的区别”则是面试官最喜欢、最经常问的问题。

  但我们看了不少的文章、解释,总是一头雾水、一知半解的,往往很容忘记。今天,我带大家从底层去深入理解这两个玩意的区别,相信下次面试官再问的时候,肯定能镇住面试官

一、初始“==”的含义

  在Java中,“==”的作用主要有两个:

  1、基础数据类型:比较的是两者的值是否相等,比如两个 int 类型的变量,比较的是变量的值是否相等。

  2、引用数据类型:比较的是引用地址是否相同,比如新建了两个 User 对象,比较的是两个 User 的地址是否一样。

  到这里,有些人就有会疑问了:你这里怎么用了个User对象,怎么不是String?别急,请允许我卖个关子。

二、理解equals的含义

  我们通过Object的源码,先看看Object里面的equals方法

  通过源码,我们可以看到equals方法比较的是当前对象的引用和 obj 的引用是否相同,也就是说默认比较的就是地址

  我们刚才使用的是 User 对象而不是String,在这里“==”比较的就是引用地址,“equals”也是比较引用地址,这两者是没有区别的。

public class MobileTestBase {

    public static void main(String[] args) {

        int a = 2;
int b = 2;
//常量比较的是两者的值,故为 ture;
System.out.println(a==b); User user1 = new User();
User user2 = new User();
//普通对象User,"=="和"equals"作用是一样,比较两者的引用地址,均为 false
System.out.println(user1==user2);
System.out.println(user1.equals(user2));
}
}

  到这里,我们发现,好像“==”和“equals”并没有什么区别,但是,接下来的String类型,就有点意思了,且听我徐徐道来。

三、重写equals

  1、String中的equals方法

  看到标题,相信我们已经有点印象了,Object对象里面的“==” 和 “equals” 没有什么区别,这样的 equals 方法是没有什么意义的。

  但是,我们可以看到 String 在 Object 的基础上对 equals 进行重写,那么 equals 的逻辑、功能自然就发生变化了。至于怎么重写,我们一起到 String 源码中寻找答案吧。

  从源码中可以看出:String 中的 equals 方法是在比较字符串的内容是否一样。也就是说,如果像 String、Date 这些重写 equals 的类,在使用的时候会和 Object 的 equals 不一样。

  2、测试String

  看看下面的测试代码:

public class Test {

    public static void main(String[] args) {

        String str1 = "hello world";
String str2 = new String("hello world");
String str3 = str2; //赋值,引用传递; System.out.println(str1 == str2); // false
System.out.println(str1 == str3); // false
System.out.println(str2 == str3); // true System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true
System.out.println(str2.equals(str3)); // true
}
}

  可以看到,定义了3个字符串,分别使用“==” 和 “equals” 比较,出现了不同的结果。其中的原因,就需要我们从内存的角度去解释了。

  3、内存解释

  在Java中,我们一般把对象存放在堆区,把对象的引用存放在栈区。因此,上面3个字符串的内存状态应该是下面这样的。

  从上图我们可以看出来:

  1. String str1 = "hello world"; 会在堆区存放一个字符串对象;
  2. String str2 = new String("hello world"); 会在堆区再次存放一个字符串对象;
  3. String str3 = str2; 这时候 str3 和 str2 是两个不同的引用,但是指向同一个对象。

  借助于上图,我们再次比较:

  1. str1 == str2 ? 即地址指向的是同一个地方吗? 当然是 false
  2. str1 == str3 ? 即地址指向的是同一个地方吗? 当然是 false
  3. str2 == str3 ? 即地址指向的是同一个地方吗? 明显内容是一样的,当然是 true
  4. str1.equals(str2) ? 即地址指向的内容相同吗? true
  5. str1.equals(str3) ? 即地址指向的内容相同吗? true
  6. str2.equals(str3) ? 即地址指向的内容相同吗? true

  到了这里,不知道我们是否能理解?

四、总结

  1、基础数据比较

    使用“==”是比较值是否相等

  2、引用数据比较

  • 重写了equals方法,比如String类。

    • “==”    :比较的是String的引用是否指向同一块内存
    • “equals”:比较的是String的引用的对象内容是否相等;  
  • 没有重写equals方法,如User等自定义类。
    • “==” 和 “equals” 比较的都是引用是否指向了同一块内存

五、其他

  String 类型还没结束,有一个小知识点需要注意下,如下:

public class Test {

    public static void main(String[] args) {
String str1 = "hello world";
String str2 = new String("hello world"); str2 = str2.intern(); System.out.println(str1 == str2); //true
System.out.println(str1.equals(str2)); //true
}
}

  细心就会发现,中间多了个 intern 方法。这个方法表示,检查字符串池中是否存在,如果存在,那就直接返回 true。因为这里 str1 首先会在字符串池里面有一个,然后 str2.intern() 发现池子里有了,就不再新建了,直接把 str2 指向它。

《面试经典系列》- 从底层理解==和equals的区别的更多相关文章

  1. Java基础系列-深入理解==和equals的区别(一)

    一.前言 说到==和equals的问题,面试的时候可能经常被问题到,有时候如果你真的没有搞清楚里边的原因,被面试官一顿绕就懵了,所以今天我们也来彻底了解一下这个知识点. 二.==和equals的作用 ...

  2. 《面试经典系列》- SpringMVC原理及工作流程

    前言 SpringMVC 作为 MVC 的开源框架,现在依旧是不少项目使用的重点框架.SpringMVC = Struts2 + Spring,SpringMVC就相当于 Struts2 + Spri ...

  3. 《面试经典系列》- MySQL数据库存储引擎

    一.MySQL有多少种存储引擎? 在MySQL5之后,支持的存储引擎有十多个,但是我们常用的就那么几种,而且,默认支持的也是 InnoDB. 通过命令:show engines \g,我们可以查看到当 ...

  4. 关于==和equals的区别和联系,面试这么回答就可以

    长篇大论的话,我这里就不多写了,相信大家入门java 的时候就知道个大概了,这里想表述的是,如果面试官问你<关于==和equals的区别>,该怎么回答完美呢?可以这样说 总结的来说: 1) ...

  5. 别傻傻不知道 == 和 equals 的区别【面试系列】

    ​ 关于这个问题,一般初中级面试中都会遇到,还记得我当初实习找工作的时候也遇到了这个问题,现在都还记得自己是怎么回答的:== 是基本类型比较,equals 是对象比较,不懂 hashCode,想起来简 ...

  6. 面试经典算法题集锦——《剑指 offer》小结

    从今年 3 月份开始准备找实习,到现在校招结束,申请的工作均为机器学习/数据挖掘算法相关职位,也拿到了几个 sp offer.经历这半年的洗礼,自己的综合能力和素质都得到了一个质的提升. 实话说对于未 ...

  7. Java基础系列之你真的懂==与equals的区别吗?

    对于Java初学者而言,可能会对这两个比较方法比较模糊,有的人可能会觉得两个的方法使用起来结果是一样的等.如果你有这样的想法,我建议你来看看这边博客,让你充分了解这两个比较的异同,以及他们底层是如何比 ...

  8. Java面试炼金系列 (1) | 关于String类的常见面试题剖析

    Java面试炼金系列 (1) | 关于String类的常见面试题剖析 文章以及源代码已被收录到:https://github.com/mio4/Java-Gold 0x0 基础知识 1. '==' 运 ...

  9. 让代码重构渐行渐远系列(3)——string.Equals取代直接比较与非比较

    重构背景及原因 最近由于项目组的人员在不断扩充,导致项目中代码风格各异,大有百花齐放甚至怒放之势.考虑到团队的生存与发展,经过众人多次舌战之后,最终决定项目组根据业务分成几个小分队,以加强团队管理与提 ...

随机推荐

  1. 将js进行到底:node学习5

    HTTP开发之Connect工具集--中间件 继学习node.js的TCP API和HTTP API之后,node.js web开发进入了正轨,但这就好像Java的servlet一样,我们不可能使用最 ...

  2. RROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2

    RROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2 ...

  3. 模型压缩之Channel Pruning

    论文地址 channel pruning是指给定一个CNN模型,去掉卷积层的某几个输入channel以及相应的卷积核, 并最小化裁剪channel后与原始输出的误差. 可以分两步来解决: channe ...

  4. 详解服务器性能测试的全生命周期?——从测试、结果分析到优化策略(转载)

    服务器性能测试是一项非常重要而且必要的工作,本文是作者Micheal在对服务器进行性能测试的过程中不断摸索出来的一些实用策略,通过定位问题,分析原因以及解决问题,实现对服务器进行更有针对性的优化,提升 ...

  5. 接口自动化测试平台 http://120.79.232.23

    接口自动化测试平台 http://120.79.232.23 T Name Latest commit message Commit time .idea 修改自动化用例修改接口时,其他接口信息被删的 ...

  6. 设计模式-11享元模式(Flyweight Pattern)

    1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...

  7. CSS(0)CSS的引入方式

    CSS (cascading  style  sheet)  层叠样式表 css引入的三种方式: 1.行间样式 <!--在body内写入--> <div></div> ...

  8. yii2设置默认控制器

    以Yii2高级模板配置为例

  9. CSS Sprite雪碧图的应用

    CSS雪碧图,即CSS Sprite,也有人叫它CSS精灵图,是一种图像拼合技术.该方法是将多个小图标和背景图像合并到一张图片上,然后利用CSS的背景定位来显示需要显示的图片部分. 雪碧图的使用场景 ...

  10. 【30分钟学完】canvas动画|游戏基础(6):坐标旋转探究

    前言 本篇主要讲坐标旋转及其应用,这是编程动画必不可少的技术. 阅读本篇前请先打好前面的基础. 本人能力有限,欢迎牛人共同讨论,批评指正. 坐标旋转 模拟场景:已知一个中心点(centerX,cent ...