1、序言
随着jdk7而来的Objects工具类为我们解决了很多类比较带来的困扰,但是如果你使用的姿势不对,那可能会给你带来更多的烦恼。
2、问题重现
为避免比较带来的空指针问题,我最近常用Objects.equals()方法来进行比较,但是结果却和我想象的不一样,代码如下:
1 | // numInt是int型,numLong是包装类Long |
查看equals方法源码:
1 | public static boolean equals(Object a, Object b) { |
我当时也不知道咋想的,可能脑子转不过来,想着不是方法里有 a == b吗?我打印一下numInt == numLong结果就是true。然后我又将numInt的类型从int换成了包装类Integer,返回的结果还是false,此时的我才反应过来人家的 == 比较的是地址,尴了个尬。
那为什么我们打印输出的时候,这两个不同类型的变量 == 就返回true呢?这是因为包装类和基本数据类型比较时,包装类有个自动拆箱的过程,比如上面的两个变量比较,numLong就会执行一个longValue()的方法,将变量从Long包装类型拆箱成为了long基本数据类型,两个基本数据类型比较的就是数值了(具体可以debug执行一下)。
不知道会不会有小伙伴跟我有同样的疑问:为什么Objects.equals方法内的 == 没有实现自动拆箱?debug跟一下就会发现,当基本数据类型使用该方法时,会进行自动装箱,所以我以为的比较int和Long类型的值,实际上比较的是Integer和Long的地址。但是Objects.equals方法后半截的equals比较方法为什么返回的也是false呢?直接上源码:
1 | // 包装类的equals方法 |
从上面的源码我们可以看出,如果两个参数的类型不一样,都不存在去比较数值,直接就返回false了,因此即便我传入的是两个数值相等的int和long基本数据类型的值,返回的依旧是false,并不会比较数值。
3、使用好处
虽然上面踩了坑,但那只是我学艺不精,使用的方法不对,如果你正确的理解并使用将会给你带来便利。比如我们之前比较字符串都是这么写:str1.equals(str2)
,但凡有点经验的小伙伴都知道如果前面str1为null,就有NPE空指针异常。但是你使用Objects.equals(str1, str2)
就不会出现空指针的情况,会返回给你false,省去了你去判空的过程。
方法虽易不看不理解,踩坑虽多不摔不成长。
- 本文作者: tenyears
- 本文链接: https://tenyears94.gitee.io/2020/08/08/Objects工具类equals()的踩坑记录/
- 版权声明: 本博客所有文章转载请注明出处!