Java 两个Integer对象的==判断时由于自动装箱而出现的奇怪问题

Integer是int的包装类,既然是类,Integer类型的变量进行==比较的时候就是判断两个对象引用的地址是否相同了。
因此下列代码的返回值为false

public static void main(String[] args) {
        Integer i1 = new Integer(1);
        Integer i2 = new Integer(1);
        System.out.println(i1 == i2);//false
    }

这个比较好理解,因为每次new操作,都会在堆空间中申请一个新的对象。他们的地址肯定不同。
但是下列代码的结果呢?

public static void main(String[] args) {
        Integer i1 = 1;
        Integer i2 = 1;
        System.out.println(i1 == i2);//true
    }

这段代码的结果竟然是True。
1是int类型,他会自动装箱成Integer,也就相当于

public static void main(String[] args) {
        Integer i1 = Integer.valueOf(1);
        Integer i2 = Integer.valueOf(1);
        System.out.println(i1 == i2);//true
    }

但是这样貌似也不能解释为什么i1和i2引用的地址会相同。
别着急接着往下看

public static void main(String[] args) {
        //Integer i1 = Integer.valueOf(128);
        //Integer i2 = Integer.valueOf(128);
        Integer i1 = 128;
        Integer i2 = 128;
        System.out.println(i1 == i2);//false
    }

什么!?这段代码的返回值竟然是False
那么这是什么原因造成的呢。
首先我们知道,int在赋值给Integer的时候会自动装箱成Integer
即下列两行代码是等价的

 		Integer i1 = Integer.valueOf(128);
        Integer i1 = 128;

然后我们打开Integer.valueOf()的源码

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

其中的IntegerCache.low又是什么呢?
在这里插入图片描述

到这里谜题就揭晓了,原来Integer早就把-128到127的数字帮我们缓存好了,如果我们调用Integer.valueOf()方法的话,会判断传入的参数是否在这个范围内,如果在的话,就返回缓存好的Integer对象。
其他的包装类也有相似的缓存机制。
因此我们在判断包装类是否相等时,最好用equals()方法而不要用== (当然Boolean类型无所谓啦,因为他只有两种可能,这两种早就被缓存好了)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值