== 与 equals的区别(源码级理解)

说到== 与 equals 的区别,大多数小白可能就心想:

==不就是基本数据类型比较值,引用类型比较地址?
equals不就是比较引用类型值?

但凡看过Object源码就知道,原生equals和==没有区别!上源码:

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

这内部不就调用的 ==;况且一搜很多 == 与 equals的区别,置顶的帖子居然还是说 equals不就是比较引用类型值。。。

所以我们明确了第一点:原生的equals和==没有区别,都是比较引用类型地址。当然两个基础类型比较用不上equals。

我们知道JDK1.5之后java引入了自动装箱和自动拆箱机制。那如果是基础类型和对应的包装类进行比较呢?

我们来看下面几个代码

// 基础类型和对应的包装类进行比较
	    int i =200;
        Integer j = 200;
        System.out.println(j.equals(i));
        System.out.println(i == j);

结果是
在这里插入图片描述
第一个是true,那我们就不得不看看Integer里面的equals源码了

// Integer里面的equals源码
 public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

Integer中重写了equals方法,先是判断传入的Object对象是不是Integer类型或者Integer类型子类,然后强转Object对象为Integer类型,调用intValue()方法返回这个Object对象的值,和调用equals()的对象进行值比较。

拓展那我们这个例子,equals()括号里面是基本数据类型,基本数据类型是Object的子类吗?

从下图我们可以看到,当1赋值给Object对象时,编译器没有报错,通过反射我们发现1自动装箱成了Integer

 public static void main(String[] args) {
        //编译器没报错
        Object i = 1;
        System.out.println(i.getClass().getName());
    }

在这里插入图片描述
所以我们明白了Integer里面equals是优先比较包装类的,意思是说即使括号里是基础数据类型也会自动装箱再进行比较,先比较类型,再比较值。

我们再回过头看第二个true,也就是基础数据类型和对应包装类用==比较,也是返回true,如果 ==是和Integer里面equals一样优先比较包装类,那么把i装箱成integer,两个值超过127的integer用 == 比较肯定是false,地址不同了,如果两个Integer值是在-128 - 127,两个Integer会指向常量池的同一个地址,会返回true,但这不是我们现在讨论的情况

由此我们明白了==是优先比较基础类型的,如果基础数据类型和对应包装类用 ==比较,会把包装类自动拆箱再比较。

小结:
1.原生的equals和==没有区别
2.在一个包装类和对应的一个基础类型进行比较时, ==是优先比较基础类型的,Integer里面equals是优先比较包装类的
3.==是两个都是基础类型时比较值,两个都是包装类型时比较地址,
equals两个都是包装类时,先比较类型,再比较值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值