==和equals的区别,源码解析

这是Object类里面的equals方法源代码:

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

看着还是用==在比较,原因分析:在大部分的封装类中,都重写了Object类的这个方法,所以两者还是会有区别的。总的来说,==是一个关系运算符,如果比较的两端都为基本类型,则判断两者的值是否相等,(判断过程中还有不同基本类型的转化),如果比较的两端都为引用类型的话,则比较两者所指向对象的地址是否相同;对于equals方法,首先,能调用这个方法肯定是一个对象,然后,如果这个对象所在的类重写了equals方法,则按照重写的方法进行比较,如果没有,则比较两者所指向对象的地址是否相同。

我们以Integer类的equals()方法的源代码的详细实现过程说明:

Integer重写了equals方法如下(加注解):

public boolean equals(Object obj) {
        if (obj instanceof Integer) { //判断传进来的参数是不是Integer类的一个实例,
        如果不是直接返回false;
        return value == ((Integer)obj).intValue();//如果是,则判断两者的成员变量
        value值是不是相等的,这块又回到了基本类型的比较。value的值在创建这个对象的时候
        被赋值。
        }
        return false;
    }

上面的源码可知,equals方法又调用了一个intValue方法,继续查看intValue方法源码:

 public int intValue() {
        return value;
    }

又因为在Integer类的实例在创建的时候还会调用valueOf方法自动装箱,例如java在编译Integer i = 100 ;时,会翻译成为Integer i = Integer.valueOf(100);在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);
    }

上面这段代码首先规定了一个范围,默认IntegerCache.low 是-127,Integer.high是128,如果参数中的i在这个范围之内,则返回一个数组中的内容,如果不在这个范围,则new一个新的Integer对象并返回,相当于把-128~127之间的数进行了缓存,如果i这个范围内 ,直接从缓存中取,就不会new了,否则new一个新的Integer对象并返回。查看Integer类的源码可以发现,这个数组里面缓存了基本类型-128-127之间的Integer对象

总的来说:
==比较地址,equals比较值,但是对于包装类和基本类型,还要涉及它们的自动装箱、自动拆箱,所以小心一点还是比较好的:

  1. Integer 类型的值在[-128,127] 期间,Integer 用 ==是可以的 , Integer 与 int 类型比较的是值。

  2. 如果要比较Integer的值,比较靠谱的是通过Integer.intValue();这样出来的就是int值,就可以直接比较了;或者equals()比较

猜你喜欢

转载自blog.csdn.net/QQ2899349953/article/details/82944960