Objects.equals方法的坑

前言: Objects.equals()方法是java.util下的一个工具类,使用它可以进行两个对象equals的比较,避免繁琐的null指针判断。

本文由代码示例展开,以源码断点调试进行分析,Objects.equals()方法使用时容易忽略的一些问题。

1. Objects.equals()官方源码

这里我们先看Objects.equals()的官方源码

    /**
     * Returns {@code true} if the arguments are equal to each other
     * and {@code false} otherwise.
     * Consequently, if both arguments are {@code null}, {@code true}
     * is returned and if exactly one argument is {@code null}, {@code
     * false} is returned.  Otherwise, equality is determined by using
     * the {@link Object#equals equals} method of the first
     * argument.
     *
     * @param a an object
     * @param b an object to be compared with {@code a} for equality
     * @return {@code true} if the arguments are equal to each other
     * and {@code false} otherwise
     * @see Object#equals(Object)
     */
    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

2. 分析如下代码的执行结果

    public static void main(String[] args) {
        Integer integer1 = Integer.valueOf(1);
        Integer integer200 = Integer.valueOf(200);
        Integer integer100 = Integer.valueOf(100);
        Long long200 = 200L;
        Byte Byte100 = (byte) 100;
        byte byte100 = (byte) 100;
        System.out.println("--------------------Integer-----------------------");
        System.out.println(Objects.equals(integer1, 1));         // true
        System.out.println(Objects.equals(integer200, 200));     // true
        System.out.println(Objects.equals(integer100, byte100));    // false
        System.out.println(Objects.equals(integer100, Byte100));    // false
        System.out.println("--------------------Long--------------------------");
        System.out.println(Objects.equals(long200, 200L));      // true
        System.out.println(Objects.equals(long200, 200));       // false
        System.out.println(Objects.equals(long200, integer200));    //false
        System.out.println("--------------------Byte--------------------------");
        System.out.println(Objects.equals(Byte100, 100));       // false
        System.out.println(Objects.equals(Byte100, (byte) 100));    // true
        System.out.println(Objects.equals(Byte100, byte100));       // true
        System.out.println("--------------------byte--------------------------");
        System.out.println(Objects.equals(byte100, 100));       // false
        System.out.println(Objects.equals(byte100, (byte) 100));   // true
        System.out.println(Objects.equals(100,byte100));        // false
    }

3. 重点疑问解答

3.1 System.out.println(Objects.equals(integer100, byte100));

这两个都是赋值100,但是使用Objects.equals()进行比较的时候却发现,返回的是false,这是为什么呢?下面在源码中打断掉调试,如图:
第一步、打上断点
在这里插入图片描述
第二步、断点跳入Objects.equals()方法
可以看到我们的byte100基本数据类型变量,已经被自动装箱为Byte包装类了,下一步就是走的Integer的equals方法了
在这里插入图片描述
第三步、断点跳入Integer.equals()方法,由此可见,因为Byte并非是Integer的实例,所以Integer.equals()方法直接返回false,而不是进行值的比较。
在这里插入图片描述

3.2 System.out.println(Objects.equals(long200, 200));

一个是200L一个是200,对于我们惯性思维肯定认为是true,但是使用Objects.equals()进行比较的时候却发现,返回的是false,这是为什么呢?下面在源码中打断掉调试,如图:
第一步、打上断点
在这里插入图片描述
第二步、由此可以发现,200的基本数据类型(int)被自动装箱为Integer
在这里插入图片描述
第三步、下一步,断点直接跳入到了Long.equals()方法中,如图:
因为两者根本不是同一个对象类型,所以直接返回false,原理同上3.1
在这里插入图片描述

总结:上述问题的本质原因,是因为使用Object.equals()方法时,会将基本数据类型进行自动装箱后,进行对应的包装类的equals比较。而我们忽略了类型的比较,仅仅关注到了值的比较。

说了这么多,其实这也不算是Objects.equals()方法的坑,只是我们想当然的认为和理解与计算机代码执行的不一致罢了,这也告诉我们如下道理。我们使用别人造好的轮子的时候,在快捷高效方便的书写代码的时候,一定要清楚它们对应的功能边界,使用场景,失效场景,这样才能帮助我们更好的写出少bug的正确代码。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值