Integer中为什么-128~127之间的值可以直接==

在判断两个Integer是否相等的时候我们一般都是使用equals来比较是否相等,很多网上的博客也有提到过两个Integer的值在[-128, 127] 之间的时候,可以直接通过==来比较是否相等。那么为什么[-128, 127] 之间的Integer可以直接用==呢?

从自动装箱说起

public class Demo {
    public static void main(String[] args) {
        Integer i1 = 100;
        Integer i2 = 100;
        System.out.println(i1 == i2);  //输出true
        i1 = 1000;
        i2 = 1000;
        System.out.println(i1 == i2);  //输出false
    }
}

实际上,这段代码在JDK1.5之前是不合法的,因为代码中的100是个int类型,属于Java中的8种基本类型之一,而Integer是个对象,对象怎么能等于一个基本类型呢?所以在JDK1.5之前要声明一个值为100的Integer,正确的写法是:Integer i = new Integer(100)Integer i = Integer.valueOf(100)

而在JDK1.5之后,编译器提供了自动拆箱和装箱的功能,Integer i = 100 正是编译器帮我们自动装箱了。

那么我们看看上面代码的编译后是什么样子。借助jd-gui这个工具,我们将.class文件反编译出来。
在这里插入图片描述
可以看见编译后的代码其实是由编译器用Integer.valueOf 帮我们将基本类型装箱了

不简单的valueOf

让我们来看看valueOf 的源代码
在这里插入图片描述
valueOf方法上面的注释说明的非常明白,这个方法会将传入的int值包装成Integer对象返回,这个方法默认会缓存-128到127的值,也可能缓存这个范围外的值。

再来看看方法中的逻辑,这个方法会判断传入的int值是否在IntegerCache 的最高值和最低值之间,如果在这个之间,就会从IntegerCache 的缓存中获取Integer对象,否则就会new一个新的Integer对象。
我们通过debug看一下IntegerCache.cache 里面到底有什么
在这里插入图片描述
IntegerCache.cache 中的元素是-128到127顺序排列在数组的0-256位置,假设我们传入的i = -128,通过寻址公式计算下标
i + (-IntegerCache.low) = -128 + (128) = 0
而下标0的元素刚好就是-128。这个寻址公式还挺巧妙的,设计者真是个天才。

思考最初的问题

到了这一步我们就可以明白了:为什么当Integer的值为 [-128, 127] 时,用== 判断两个两个值相等的Integer可以得到true,而超出这个范围后,用 == 判断两个两个值相等的Integer却得到false?因为当值在[-128, 127] 之间时,valueOf 方法不会创建新的Integer对象,而是从缓存中获取,这样一来,值相同的int,计算所得的下标是一样的,自然会获取到同一个Integer对象。而超出这个范围就不会从缓存中获取了,每次都new一个新的Integer对象,两个不同的对象的内存地址不同,用==自然会得到false。

静态内部类IntegerCache

在明白了装箱的原理后,我们不妨看一看IntegerCache 的缓存是如何初始化的。
在这里插入图片描述
初始化缓存的过程如下

  1. 获取JVM的中的参数java.lang.Integer.IntegerCache.high,将其转为int类型,作为high的值
  2. 计算highlow 之间的差值并+1作为缓存数组的长度
  3. 从-128开始连续递增,给缓存数组的每个位置设置Integer对象。

以上就是缓存初始化的步骤。

另外,java.lang.Integer.IntegerCache.high的值默认是127,但是我们可以在程序启动时通过启动参数对其进行设置。
网上都说用-Djava.lang.Integer.IntegerCache.high=<size> 来修改,但是我看到类上的注释推荐我使用-XX:AutoBoxCacheMax=<size> 来修改。亲自试了一下,两种参数都可以成功修改。

在这里插入图片描述
在这里插入图片描述
将缓存最大值改成1000后,再次测试一下最开始的那段代码
在这里插入图片描述
此时两个输出都为true。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值