导读:昨夜闲来无事,和贾姑娘聊了聊java基础,然后就说到了这个“==”和equals的问题,我俩都是以前了解过,也常用这个,但是,昨天说到的时候,又乱了,什么比较地址值,什么判断是否同一个对象,基本数据类型啥的,谁都没个准儿,后来写了点代码验证了一番,今儿个写此博客,纪念和好朋友一起探讨学习的经历!PS:我一直知道我这一路走来,受好朋友的恩惠太多了!

一、三组示例代码

1.1,String类(引用类型)

  1. String str1="test";
  2. String str2="test";
  3. //true true
  4. System.out.println(str1==str2);
  5. System.out.println(str1.equals(str2));
  6. String str3=new String("test");
  7. String str4=new String("test");
  8. //false true
  9. System.out.println(str3==str4);
  10. System.out.println(str3.equals(str4));
  11. String str5=str1;
  12. //true true
  13. System.out.println(str5==str1);
  14. System.out.println(str5.equals(str1));
  15. String str6=str3;
  16. //false true
  17. System.out.println(str6==str1);
  18. System.out.print(str6.equals(str1));

刚开始,统一的意见是“==”是比较值,equals是比较引用对象,请看下面的经典论断(主要是针对str3和str4):

A:==比值,这两个值都是test,应该是true,可结果是false,后面那个equals比较对象,两个都是new的,应该不一样,可结果是true

B:==比值,因为这两个不是简单类型,无法比较,所以返回false;equals 比较对象,此时str3 和str4新创建了两个字符串对象,这两个对象是一样的,返回true

A:如果是byte、int、boolean、long,float,这些的话,==就是比较值,equals比对象,是吧

B:对

1.2,Integer类(int的包装类,非8种基本类型)

  1. Integer int1=1;
  2. Integer int2=1;
  3. //true true
  4. System.out.println(int1==int2);
  5. System.out.println(int1.equals(int2));
  6.  
  7. Integer int3=new Integer(1);
  8. Integer int4=new Integer(1);
  9. //false true
  10. System.out.println(int3==int4);
  11. System.out.println(int3.equals(int4));
  12.  
  13. Integer int5=int1;
  14. //true true
  15. System.out.println(int5==int1);
  16. System.out.println(int5.equals(int1));
  17.  
  18. Integer int6=int3;
  19. //true true
  20. System.out.println(int6==int3);
  21. System.out.print(int6.equals(int3));

结果和String类一致!

1.3,int(基本类型)

备注:用简单基本类型,根本无法使用equals方法,只能用==,对于String类或者简单类型的包装类(Integer是int的包装类)==比较的是否是同一个地址(对象),equals比较的是地址值

二、分析equals方法

所有的对象都是继承于Object类,那么首先看Object里面,关于equals的定义:

  1.  * @param   obj   the reference object with which to compare.
  2.      * @return  {@code true} if this object is the same as the obj
  3.      *          argument; {@code false} otherwise.
  4.      * @see     #hashCode()
  5.      * @see     java.util.HashMap
  6.      */
  7.     public boolean equals(Object obj) {
  8.         return (this == obj);
  9.     }

从这里可以看出,equals事实上比较的是否是同一个对象目标,也就是是否是同一个内存地址。但从这个角度来说,那么就无法解释为什么在代码段1中str3.equals(str4)的结果为true了。因为这两个对象都采用了new 关键字,在堆中,必定会存在两个空间地址。为了解决这个问题,势必要去看看String类对于equals方法的重写:

  1. /**
  2. * Compares this string to the specified object. The result is {@code
  3. * true} if and only if the argument is not {@code null} and is a {@code
  4. * String} object that represents the same sequence of characters as this
  5. * object.
  6. *
  7. * @param anObject
  8. * The object to compare this {@code String} against
  9. *
  10. * @return {@code true} if the given object represents a {@code String}
  11. * equivalent to this string, {@code false} otherwise
  12. *
  13. * @see #compareTo(String)
  14. * @see #equalsIgnoreCase(String)
  15. */
  16. public boolean equals(Object anObject) {
  17. if (this == anObject) {
  18. return true;
  19. }
  20. if (anObject instanceof String) {
  21. String anotherString = (String)anObject;
  22. int n = value.length;
  23. if (n == anotherString.value.length) {
  24. char v1[] = value;
  25. char v2[] = anotherString.value;
  26. int i = 0;
  27. while (n-- != 0) {
  28. if (v1[i] != v2[i])
  29. return false;
  30. i++;
  31. }
  32. return true;
  33. }
  34. }
  35. return false;
  36. }

从代码可以看出,String类对于equals方法进行了改写,当String类使用equals的时候,if and only if the argument is not null and isa object that represents the same sequence of characters
as this object
. 对比Object基类返回true的条件:if this object is the same as the obj argument。 现在再去看代码段1中的str3.equals(str4)的结果为true,就能理解了!

接下来,再看基本类型的包装类中对于equals方法的改写:

  1. /**
  2. * Compares this object to the specified object. The result is
  3. * {@code true} if and only if the argument is not
  4. * {@code null} and is an {@code Integer} object that
  5. * contains the same {@code int} value as this object.
  6. *
  7. * @param obj the object to compare with.
  8. * @return {@code true} if the objects are the same;
  9. * {@code false} otherwise.
  10. */
  11. public boolean equals(Object obj) {
  12. if (obj instanceof Integer) {
  13. return value == ((Integer)obj).intValue();
  14. }
  15. return false;
  16. }

if and only if the argument is not null and is an object that contains the same value as this object. 从这里可以看出,它的改写,并未要求是同一对象,而要求是同一值!

附:更为明显的代码片段

  1. Integer intA=new Integer(1);
  2. Integer intB=new Integer(1);
  3. Integer intC=1;
  4. //false false true true
  5. System.out.println(intA==intB);
  6. System.out.println(intA==intC);
  7. System.out.println(intA.equals(intB));
  8. System.out.println(intA.equals(intC));

三、总结

写这篇博客,主要是想纪念一下和好朋友之间的探讨交流,感觉和大家一起交流一些简单又有意思的事儿,真心很好玩。而且感觉我现在还比较喜欢看源码,也就来源于对这些小东西的兴趣和好奇。当然目前的学习程度是远远不够的,正在努力中。对了,以上关于equals的各类源码,属于java 8.

多看代码,多交流,多总结,希望自己保持下去,然后和大家一起成长!

【java基础 15】java代码中“==”和equals的区别的更多相关文章

  1. Java基础:Object类中的equals与hashCode方法

    前言 这个系列的文章主要用来记录我在学习和复习Java基础知识的过程中遇到的一些有趣好玩的知识点,希望大家也喜欢. 一切皆对象   对于软件工程来说面向对象编程有一套完整的解决方案:OOA.OOD.O ...

  2. Java基础-使用JAVA代码剖析MD5算法实现过程

    Java基础-使用JAVA代码剖析MD5算法实现过程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  3. Java基础语法(8)-数组中的常见排序算法

    title: Java基础语法(8)-数组中的常见排序算法 blog: CSDN data: Java学习路线及视频 1.基本概念 排序: 是计算机程序设计中的一项重要操作,其功能是指一个数据元素集合 ...

  4. 黑马程序员:Java基础总结----java注解

    黑马程序员:Java基础总结 java注解   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! java注解 lang包中的基本注解 @SuppressWarnings ...

  5. java基础(二)-----java的三大特性之继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  6. Java基础技术-Java其他主题【面试】

    Java基础技术-Java其他主题[面试] Java基础技术IO与队列 Java BIO.NIO.AIO Java 中 BIO.NIO.AIO 的区别是什么? 含义不同: BIO(Blocking I ...

  7. Java基础:Java的四种引用

    在Java基础:java虚拟机(JVM)中,我们提到了Java的四种引用.包括:强引用,软引用,弱引用,虚引用.这篇博客将详细的讲解一下这四种引用. 1. 强引用 2. 软引用 3. 弱引用 4. 虚 ...

  8. java基础-学java util类库总结

    JAVA基础 Util包介绍 学Java基础的工具类库java.util包.在这个包中,Java提供了一些实用的方法和数据结构.本章介绍Java的实用工具类库java.util包.在这个包中,Java ...

  9. Java基础15:深入剖析Java枚举类

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

随机推荐

  1. wall命令

    wall——发送广播信息 write all /usr/bin/wall 示例1: # wall 输入命令之后回车便可以广播消息,如输入Hello everybody online后Ctrl+D结束并 ...

  2. SAP GUI里Screen Painter的工作原理

    我们在SAP GUI里双击一个screen编号: 单击Layout按钮可以打开Screen Painter: 这背后的工作原理是什么? 是这个RFC destination在起作用: Connecti ...

  3. spring security 2.x HttpSessionEventPublisher 以及listener配置

    在环境为spring security2.x时 *JDK6 spring 2* 正确的filter路径是:org.springframework.security.ui.session.HttpSes ...

  4. Processing分形之一——Wallpaper

    之前用C语言实现过一些分形,但是代码比较复杂.而对于天生对绘图友好的Processing,及其方便. 在大自然中分形普遍存在,我们用图形模拟,主要是找到一个贴近的函数. 代码 /** * Wallpa ...

  5. windbg双机调试配置

    环境 虚拟机 win7 Pro x86 vmware 12 windbg x86 虚拟机win7配置 管理员权限运行cmd.exe 然后输入以下命令: bcdedit /? bcdedit /enum ...

  6. Java第7次作业:造人类(用private封装,用static关键字自己造重载输出方法)什么是面向对象程序设计?什么是类和对象?什么是无参有参构造方法 ?什么是封装?

    什么是面向对象程序设计? 我们称为OOP(Object  Oriented  Programming) 就是非结构化的程序设计 要使用类和对象的方法来进行编程 什么是类,什么是对象 类就是封装了属性和 ...

  7. Mybatis 循环 foreach, 批量操作

    mapper.java: int modifySortOfGoods(@Param("idlist") List<String> goodsIds, @Param(&q ...

  8. day2-python 登录

    # username = 'niuhanyang' # 写一个判断登录的程序: # 输入: username # password # 最大错误次数是3次,输入3次都没有登录成功,提示错误次数达到上限 ...

  9. 如何用纯 CSS 创作一个过山车 loader

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/KBxYZg/ 可交互视频 此视频是 ...

  10. vue 顶级组件

    快 有时候懒的把一些通用组件写到template里面去,而业务中又需要用到,比如表示loading状态这样组件. 如果是这样的组件,可以选择把组件手动初始化,让组件在整个app生命周期中始终保持活跃. ...