【JAVA】 Integer变量为什么100 = 100为true,而1000 = 1000为false?

抛砖

我们先看下面这段代码,很多人应该都见过这个题目:

        Integer a = 100, b = 100;
        Integer c = 1000, d = 1000;
        System.out.println("a == b " + (a == b)); //结果1
        System.out.println("c == d " + (c == d)); //结果2

相信大多数人看到上面的代码,第一感觉会认为,无论结果是什么,至少应该是一致的,要么都是false,要么都是true。
但运行后,你会得到如下结果:

I/System.out: a == b true
I/System.out: c == d false


引玉

我们知道java里是不支持运算符重载的,所以上述判断的原理跟引用有关。如果两个引用指向同一个对象,那么用==表示它们是相等的;否则即使内容相同,那==两边也不会相等。

那上述的结果就应该都为false才对,但实际上结果1却为true。
正当百思不得其解的时候,聪明的你,小手一点,跳转到了Integer类的定义中,惊奇地发现,原来是Integer类里做的特殊处理。

原因

我们先抛出结论:
Integer与Integer比较的时候,由于直接赋值的时候会进行自动的装箱,那么这里就需要注意两个问题,一个是-128<= x<=127的整数,将会直接缓存在IntegerCache中,那么当赋值在这个区间的时候,不会创建新的Integer对象,而是从缓存中获取已经创建好的Integer对象。二:当大于这个范围的时候,直接new Integer来创建Integer对象。所以比较的时候,-128<= x<=127的整数对应的对象其实是同一个,即IntegerCache中的对象。

解释

首先我们来看看什么是拆箱和装箱?
原始类型转换为对象类型就是装箱,反之就是拆箱。
自动装箱时编译器调用valueOf将原始类型值转换成对象,同时自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法将对象转换成原始类型值。这里就不深入说明,可以参考Java自动装箱与自动拆箱(包装类)

现在我们来看看Integer类是如何特殊处理的。
首先,我们知道
Integer a = 100;
编译器实际上的处理为:
Integer a = Integer.valueOf(100);
查看valueOf的方法如下:

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

确实,正如我们上述结论提到的,一个是-128<= x<=127的整数,将会直接缓存在IntegerCache中,那么当赋值在这个区间的时候,不会创建新的Integer对象,而是从缓存中获取已经创建好的Integer对象。
所以,Integer a = 100, b = 100; a与b指向了同一个对象,故结果1为true。


问题引申

1.Integer类中为什么会使用缓存IntegerCache?
原因不难猜想,在此范围内的整数使用率较高,因此,使用相同底层对象是有价值的,可以减少内存的额外开销。

2.Integer和int可以比较吗?
当然可以,int 和Integer进行比较的时候,Integer会进行拆箱,转为int值与int进行比较。

3.new Integer(1) 和Integer a = 1是一样的吗?
现在应该很清楚了吧,是不一样的。前者会创建对象,存储在堆中,而后者因为在-128到127的范围内,不会创建新的对象,而是从IntegerCache中获取的。


总结

1.等号两边的引用比较时,其实比较的是,两个引用是否指向同一个对象。
2.Integer类在-128~127的范围内,使用了缓存,所有的Integer a = 1都引用的是同一个对象。
3.JDK1.5 ,新增了 2 个功能:自动装箱、自动拆箱,这个功能使得Interger和int可以自动转换;而不会因为混用时导致编译运行出错,比如可以对Integer和int进行比较,以及相互赋值等。
4.分析问题不能停留在表面,要从原理上入手,得从源码角度去找原因。android的源码将会对你学习java语言和android系统,有十分重要的意义。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值