前言

  在我们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. mysql中not exists的简单理解

    http://www.cnblogs.com/glory-jzx/archive/2012/07/19/2599215.html http://sunxiaqw.blog.163.com/blog/s ...

  2. 吴裕雄--python学习笔记:os模块函数

    os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'. os.getcwd:得 ...

  3. 发现日志文件和打印在eclipse控制台中的编码不一致

    发现日志文件和打印在eclipse控制台中的编码不一致,正好相反. 日志文件是用notepad打开的,notepad有自己的编码方式,查询编码为utf-8,日志文件汉字等等显示正常. 但是在eclip ...

  4. JSP9个内置对象和3个常用指令

    一.9个内置对象: 1.request对象客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应.2.response对象包含了响应客户请求的有关信息,但在JSP中很少 ...

  5. 《JavaScript算法》常见排序算法思路与代码实现

    冒泡排序 通过相邻元素的比较和交换,使得每一趟循环都能找到未有序数组的最大值或最小值. 最好:O(n),只需要冒泡一次数组就有序了. 最坏: O(n²) 平均: O(n²) *单项冒泡 functio ...

  6. 从Note 5看三星大招 究竟能不能秒杀iPhone

    5看三星大招 究竟能不能秒杀iPhone" title="从Note 5看三星大招 究竟能不能秒杀iPhone"> 从当年HTC发布第一代Android手机G1开始 ...

  7. 从ArrayList的优化中想到的

    在JDK7中ArrayList有一个小的改动,使用延迟加载的思想,默认构造函数不再初始化生成一个大小为10的数组,而是将elementData先赋值为一个共享的空数组. package java.ut ...

  8. ansible使用指北(二)

    前言在上一篇文章里我们了解了ansible的常用模块,今天我们来了解下ansible-playbook,ansbile-playbook是一系统ansible命令的集合,其利用yaml 语言编写,an ...

  9. Angular总结

    angular关键核心点进行总结 1 2 angular中有很多知识点需要学习,学习成本是很大的,我通过平常开发中把一些 很重要知识点总结下来,不管是以后拿来用,或者跳槽面试需要,我都感觉是很有帮助的 ...

  10. ASP制作建议留言板

    <html>  <head>  <meta http-equiv="Content-Type" content="text/html;cha ...