概述

这几天,被几道java基础练习题中的==和equals给绕晕了,所以打算把关于这块的内容好好总结下,争取下次再遇到类似的题目,自己不会再出错,恩,就是这样。

简单了解

在Object类中,equals方法的定义是这样的,

public boolean equals(Object obj)
{    return (this == obj);
}

这块就有点懵了,这不还是用==来进行比较的吗?再往下搜了才知道,在大部分的封装类中,都重写了Object类的这个方法,所以两者还是会有区别的。总的来说,==是一个关系运算符,如果比较的两端都为基本类型,则判断两者的值是否相等,(判断过程中还有不同基本类型的转化,这里不做讨论),如果比较的两端都为引用类型的话,则比较两者所指向对象的地址是否相同;对于equals方法,首先,能调用这个方法肯定是一个对象,然后,如果这个对象所在的类重写了equals方法,则按照重写的方法进行比较,如果没有,则比较两者所指向对象的地址是否相同。

自己动手

了解了上面那么多内容之后,然后自己就写了一个小小的测试程序,打算验证下,代码如下:

public class Test{public static void main(String[] args) {Integer a = new Integer(200);Integer b = new Integer(200);Integer c = 200;Integer e = 200;int d = 200;System.out.println("两个new出来的对象    ==判断"+(a==b));System.out.println("两个new出来的对象    equal判断"+a.equals(b));System.out.println("new出的对象和用int赋值的Integer   ==判断"+(a==c));System.out.println("new出的对象和用int赋值的Integer   equal判断"+(a.equals(c)));System.out.println("两个用int赋值的Integer    ==判断"+(c==e));System.out.println("两个用int赋值的Integer    equal判断"+(c.equals(e)));System.out.println("基本类型和new出的对象   ==判断"+(d==a));System.out.println("基本类型和new出的对象   equal判断"+(a.equals(d)));System.out.println("基本类型和自动装箱的对象   ==判断"+(d==c));System.out.println("基本类型和自动装箱的对象   equal判断"+(c.equals(d)));}
}

执行的结果如下

两个new出来的对象    ==判断false
两个new出来的对象    equal判断true
new出的对象和用int赋值的Integer   ==判断false
new出的对象和用int赋值的Integer   equal判断true
两个用int赋值的Integer    ==判断false
两个用int赋值的Integer    equal判断true
基本类型和new出的对象   ==判断true
基本类型和new出的对象   equal判断true
基本类型和自动装箱的对象   ==判断true
基本类型和自动装箱的对象   equal判断true

首先,第9行中,对于两个new出来的Integer对象,用==比较两者,得到了false,这点应该挺好理解的,每次使用new关键字,都会在堆内存中申请一块空间,存放相应的对象的值,然后在栈中存放这块内存的引用。而==运算符比较两者所指向对象的地址是否相同,申请了两块空间,地址肯定不相同,所以结果为false。
第10行中,结果为true,查了下java的源码,发现Integer重写的equals方法是这样的:

public boolean equals(Object obj) {if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}return false;
}

又调用了一个intValue方法,它的实现是这样的:

public int intValue()
{  return value;
}

首先判断传进来的Object类型是不是Integer类的一个实例,如果不是直接返回false;如果是则判断两者的成员变量value值是不是相等的(Integer类中定义的private final int value),这块又回到了基本类型的比较。value的值在创建这个对象的时候被赋值,两个Integer对象传递的参数都为200,所以value值相等,返回true。
看第11行前,先看下第5行。第5行中,用int给Integer赋值的那条语句,从jdk1.5开始能这么做了,因为从这个版本开始,java引入了自动装箱、自动拆箱机制。第5行就是一个自动装箱的过程,相当于:
Integer c = Integer.valueOf(200);
在Integer类中,valueOf方法是这么实现的:

public static Integer valueOf(int i) {  assert IntegerCache.high >= 127;  if (i >= IntegerCache.low && i <= IntegerCache.high)  return IntegerCache.cache[i + (-IntegerCache.low)];  return new Integer(i);
}

上面这段代码首先规定了一个范围,默认是-128-127之间,如果参数中的i在这个范围之内,则返回一个数组中的内容,如果不在这个范围,则new一个新的Integer对象并返回。查看Integer类的源码可以发现,这个数组里面缓存了基本类型-128-127之间的Integer对象。但是由于第11行是与一个new出来的对象做比较,所以==肯定返回的false。
第12行,equals方法比较两个对象的value值,所以为true。
第13行,两个自动装箱的变量,但是装箱传递的值大于127,所以返回false。这这块又试了下在-128到127之间的数,结果为true,大家可以试下。
第14行,结果为true。两个自动装箱的Integer对象,比较value。
第15行,这块进行比较的时候,会对Integer对象进行自动拆箱,也就是调用intValue方法,方法如上。两个基本数据类型进行==判断,根据值比较,所以结果为true。这块可能有人会问,为什么不是对int类型进行自动装箱处理呢?其实这块是java根据一个很明显的道理进行设计的:如果有人比较一个int类型的值和Integer类型的值,是想比较什么呢?肯定是值呀,所以这块是对Integer对象进行拆箱而不是对int类型装箱了。
第16行这块,首先调用equals方法的肯定是Integer对象,但是Integer类中重写的equals方法参数是一个Object类型呀,怎么能传递一个基本数据类型进去呢?所以,这块又是一个自动装箱的表现,当传递一个int类型给equals这个方法时,java会自动将这个值打包装箱为Integer类,而Integer类的最终父类又是Object,所以这块参数的问题就解决了,然后就是两个Integer对象进行equals判断,返回true。
第17行,首先d为一个基本类型int,c为一个Integer对象,所以进行==比较的时候,肯定会对Integer对象进行拆箱处理,所以结果为true。
第18行,同第16行。

总结

“==比较地址,equals比较值”这个还是挺靠谱的。但是对于包装类和基本类型,还要涉及它们的自动装箱、自动拆箱,所以小心一点还是比较好的,不要走到别人挖的陷阱中。

作者:bu_想
链接:https://www.jianshu.com/p/9cb9c61b0986
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Integer判断相等,到底该用==还是equals相关推荐

  1. Integer判断相等

    前言 工作中,才发现自己的基础很是不扎实,对java的源码以及内存这一块了解甚少!!! 这里转载一篇,感谢大神,mua~~~. 以下内容均为转载:原博客地址:bu_想的博客:Integer判断相等,到 ...

  2. Mybatis if test 中int integer判断非空的坑

    Mybatis 中,alarmType 是int类型.如果alarmType 为0的话,条件判断返回结果为false,其它值的话,返回true. 1 <if test="alarmTy ...

  3. java equal 不等于_java Integer判断相等只能使用equals(不能使用==)

    java Integer包装类和基础类型int,相互之间都可以使用==判断相等,平时没注意不能使用==,也不会轻易报错,但是实际只能用equals,而int之间就没得选,只能==. 测试代码 Inte ...

  4. 一个UTILS判断来实现if else的equals多种判断结果

    文章目录 前言 代码展示 前言 有时候需要判断过来的参数是否等1或者等于2,3,4......这样的写法过于累赘和丑陋. 代码展示 例如:判断参数: public synchronized stati ...

  5. java 判断integer相等_Java Integer判断是否相等

    一般来说,我们平常知道的都是,数值型对象如Integer比较,会有装箱和拆箱的过程.而且代码中很容易就会写出 Integer a = xxService.getId() Integer b =yySe ...

  6. 干货!学霸用12个决策模型告诉你,如何判断你到底需不需要区块链!

    作者 | Sebastien Meunier 编译 | 火火酱 责编 | Carol 出品 | 区块链大本营(blockchain_camp) 区块链自2017年大火至今,已经2年了. 众所周知,现在 ...

  7. 为什么包装类型间的相等判断应该用 equals

    为什么包装类型间的相等判断应该用 equals 大家都知道 java 中 == 和 equal 的区别, == 操作比较的是两个变量的值,对于引用型变量是判断变量是否指向同一引用对象,比地址. equ ...

  8. Java关于对象的相等判断问题(equals)

    之前对于对象的相等判断都比较含糊,最近看见了点规范的判断,稍微记一下. java中的基本类型,包含:int.long.short.byte.char.boolean.float.double这8种,可 ...

  9. Integer关于equals与==的比较(自动拆装箱技术和常量池技术)

    首先介绍下 equals方法遵循的规则:自反性,一致性,传递性,对称性,与null相比,返回false: 1.JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个e ...

最新文章

  1. 【神经网络】(18) EfficientNetV2 代码复现,网络解析,附Tensorflow完整代码
  2. 2、已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列; * 他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直
  3. PHP使用CURL案例
  4. 我为什么用docker-compose来打包开发环境
  5. java 控制jsp_JSP学习之Java Web中的安全控制实例详解
  6. mysql 联合索引 性能_mysql:联合索引及优化
  7. toj 4316 报数游戏
  8. 【leetcode 简单】 第七十七题 单词模式
  9. MIUI Android p手势,小米8 Android P内测9月开启
  10. 怎样在SQL Server上部署SSIS包 2
  11. MATLAB常用的基本数学函数
  12. 拓端tecdat|把握出租车行驶的数据脉搏 :出租车轨迹数据给你答案!
  13. python生成指定年份所有的天,并计算每天属于一年的第几周和周几
  14. Windows7升级IE11蓝屏问题
  15. android adb 环境变量配置,Windows如何配置Android的ADB环境变量
  16. php微博采集,微博采集方法
  17. TestNG 单元测试框架的使用
  18. 在北极都可以穿短袖了,温度飙升至32.5℃
  19. 太厉害了,终于有人能把Ansible讲的明明白白了,建议收藏
  20. UML类图 自我学习 知识备份 自用 转载自最后的轻语_dd43

热门文章

  1. 文档和帮助创作工具提供商Innovasys实用教程(一)
  2. 当redis执行flush操作后的补救措施
  3. iOS 中strong,weak,copy,assign区别
  4. photo如何制作长图(外送搞笑毒故事)
  5. NIOS II 创建示例设计_Quartus II 9.0
  6. 2011年9月最新整理的10个有趣的jQuery插件集合
  7. Linux下rz命令和sz命令使用方法
  8. nginx在CDN加速或使用SLB代理后,获取真实IP,做并发访问限制的方法
  9. 【超参数寻优】量子粒子群算法(QPSO) 超参数寻优的python实现
  10. golang基础-chan的select操作、定时器操作、超时控制、goroutine中使用recover