Java中的自动拆装箱及128陷阱分析----超详细

本文详细介绍了Java中Integer的自动装箱特性,特别是128陷阱,即在-128到127之间Integer对象会复用缓存,而超过这个范围则每次都会创建新对象。通过实例代码展示了当比较Integer对象时,使用`==`可能导致错误,推荐使用`equals()`方法。同时,解释了Integer对象的缓存机制,以及自动装箱和拆箱的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

128陷阱

integer a = 127 , Integer b = 127 时 , a 和 b 被自动装箱到同一个对象中 , 所以 用 == 号判断时, 认为是相等的. 而当等于

128 时,则是分装在两个对象中的 , 自然地址也不会相等 , 所以 == 号 判断结果为 false . 超过128 结果也是一样的 .

所以在比较两个包装类的对象时, 尽量使用 equals 方法 ,这样可以得到你想要的结果 , 使用 == 号容易导致 128陷阱 .

简单来讲就是:在小于127大于-128的时候,自动装箱的是同一个地址存在的数值。大于127时,自动装箱的不是同一个对象,所以地址不同。
这就是所谓的 “128陷阱” .
 

解释:

在Java中,Interger是数据类型int的封装类,Java设计者是这么认为的:

每次都要开辟新空间会占用大量的资源,因此他们规定在-128~127(因为Java设计者认为大家对数的使用大多在100以内)之间的Integer类型的变量,直接指向常量池中的缓存地址,不会new开辟出新的空间。
 

首先是我们先简单说一下自动装箱和拆箱的一些机制
Integer(int的封装类)使用le缓存策略,缓存的这些对象都是经常使用到的(-128至127之间的数字),防止每次自动装箱都创建一次对象的实例。

public class Test {
    public static void main(String[] args) {
        Integer a = 56;
        int a2 = 56;
        Integer b = 56;
        Integer c = new Integer(56);
        System.out.println(a1 == a2);
        System.out.println(a1==b);
        System.out.println(a1==c);
        Integer d = 128;
        Integer e = 128;
        System.out.println(d == e);
        System.out.println(d.intValue()==e.intValue());
        System.out.println(d.equals(e));

    }
}

输出结果:

分析运行结果:
1.true 证明此时a1(integer)和a2(int)都指向了常量池中的56。
2 true 证明了两个integer也是同时指向了常量池中的56(缓存机制)。
3 false 证明了此时new方法出来的integer对象在堆中,故引用地址不同是false。
4 false 证明了只有-128~127(128陷阱)会加载到常量池中,而其他会在堆中开辟不同的空间。
5 true 证明了也可以主动调用拆箱方法使得integer的值得以比较。
6 true 证明了integer重写了equal()方法,更方便我们应用。
如果想要正确比较的话,一定要拆箱比较,即在变量后加intValue()方法,也可以调用equal()

Integer i = 56; 自动装箱,相当于调用了Integer.valueOf(56)方法。进行装箱的时候首先判断i值是否在-128和127之间,如果在-128和127之间则直接从IntegerCache.cache缓存中获取指定数字的包装类;不存在则new出一个新的包装类。

使用i的时候,自动拆箱,相当于调用了Integer.intValue()的方法。

(源码中)IntegerCache内部实现了一个Integer的静态常量数组,在类加载的时候,执行static静态块进行初始化-128到127之间的Integer对象,存放到cache数组中。cache属于常量,存放在java的方法区中。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值