前言

  在我们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. rancher1.6高可用集群搭建

    rancher高可用集群搭建 一.搭建环境 1.安装系统 下载centos最新版, http://mirrors.sohu.com/centos/7/isos/x86_64/CentOS-7-x86_ ...

  2. Nginx部署前后端分离服务

    飘过... 一,安装Nginx 二,配置nginx 一般nginx配置文件在etc目录下 另,如何找nginx.conf配置文件: 在前后端分离端项目里,前端的代码会被打包成为纯静态文件.使用 Ngi ...

  3. NSURLSession与NSURLConnection区别

    1. 使用现状      NSURLSession是NSURLConnection 的替代者,在2013年苹果全球开发者大会(WWDC2013)随ios7一起发布,是对NSURLConnection进 ...

  4. Image图片

    # View more python tutorials on my Youtube and Youku channel!!! # Youtube video tutorial: https://ww ...

  5. Android Pay正式启用 支付宝们还好吗

    Pay正式启用 支付宝们还好吗" title="Android Pay正式启用 支付宝们还好吗"> 苹果发布会上能够真正让人眼前一亮的产品并不多,但对于" ...

  6. 不装逼地说,在 Google 到底能学到啥?

    不装逼地说,在 Google 到底能学到啥? 2017-03-17 PHP开发者 (点击上方蓝字,快速关注我们) 本文转自公众号「半轻人」(ID:ban-qing-ren),伯乐在线/PHP开发者已获 ...

  7. coreseek 在gcc 4.9+ 上编译不通过 [sphinxexpr.o] Error 1 错误解决方案

    这几天玩hhvm,把gcc环境都装到4.9了,然后编译coreseek的时候就出问题,google一大圈,貌似捕风捉影看到一些信息说是gcc4.7+的c++作用域必须用this->去引用,这里整 ...

  8. GRE阅读

    界面和托福差不多,就是反一反 GRE先读文章!因为出题顺序不一致.另外,不能跳读!!每一句都要读,即使不是观点. 考察能力: 1 三秒版本 边读边概括 解决前面的抗遗忘能力 2 句间关系 取同 取反 ...

  9. RTL8812AU双频无线网卡在ubuntu19和20上的驱动安装

    旧爱已去 疫情在家,突然邻居敲门说,我这网上不了,帮下忙呗兄弟:兄弟都叫了,哥就冒回险,口罩扎起,一顿xxxx,原来是路由器没插到wlan口,看他拉网线可怜,就把我台式机上无线网卡送给他了,这就是又送 ...

  10. python 字典元组集合字符串

    s1 = ''hello, world!'' s2 = '\n\hello, world!\\n' print(s1, s2, end='') s1 = '\141\142\143\x61\x62\x ...