温JZ

导航

Integer类自动拆箱,装箱解析

1.自动拆箱

例1:

int i1 = 10;
Integer i2 = new Integer(10);
System.out.println(i1 == i2);

这个结果是true

i1为基本数据类型值为10,i2为Integer类对象value属性值为10,在进行比较运算时,i2会自动拆箱成int类型然后再与i1进行比较所以结果是true。

所以我们来看一下自动拆箱里面发生了什么,其实非常简单,

在执行i1 == i2时由于i2是包装类和基本数据类型进行比较所以要进行拆箱,通过反编译我们在code:18可以看到他执行了intValue这个函数将i2转化成了int类型进行比较所以结果是true。

2.自动装箱

例2:

        Integer i1 = 126;
        Integer i2 = Integer.valueOf(126);

        Integer i3 = 128;
        Integer i4 = Integer.valueOf(128);
        System.out.println(i1 == i2);
        System.out.println(i3 == i4);

乍一看这两个乍一看无论对错结果应该一样吧,因为都是相同的结构,但是答案是第一个是true,第二个是false。

为什么是这样呢?首先这段代码的第一行会进行自动装箱,自动装箱会调用Integer.valueOf()。来看一下这段代码的反编译结果。

根据反编译结果我们明显可以看出自动装箱本质上调用了valueOf这个函数,那为什么上下结果不一样呢。我们来追一下它的源码。

根据源码可以看出Integer类中存在一个缓存机制,当调用valueOf函数时,如果参数i的范围在[-128,127]区间时,它会从IntegerCache中取出已有的Integer对象返回,如果超过这个范围则会重新创建一个Integer的对象。所以我们再来看一下IntegerCache类中如何给cache数组赋值的。

根据之前所说最大值可以通过启动JVM时使用系统属性来更改缓存的最大值,所以当我更改时看看会有什么不同的效果。

看下一个例子:

    public static void main(String[] args) {
        Integer i1 = 126;
        Integer i2 = Integer.valueOf(126);

        Integer i3 = 128;
        Integer i4 = Integer.valueOf(128);

        Integer i5 = 250;
        Integer i6 = Integer.valueOf(250);
        System.out.println(i1 == i2);
        System.out.println(i3 == i4);
        System.out.println(i5 == i6);
    }

因为我已经更改了IntegerCache的high值为200不再是之前的127所以在[-128,200]之间的数我们可以直接通过cache数组拿到Integer实例,不需要重新创造。所以126和128都是true,250不在这个区间范围之内所以它需要重新创造Integer类的实例所以返回false。下次我们再遇到类似问题就可以迎刃而解了。

posted on 2021-12-05 05:55  温JZ  阅读(165)  评论(0编辑  收藏  举报