Java 128陷阱

在java中 List list = new ArrayList(); 中 如果写为List<> list = new ArrayList(); 这样会报错的。 那么int 和Integer有什么区别呢??

我们知道int是基本数据类型,而Integer是int的包装类。这里就设计到了自动装箱和自动拆箱了,简单一点讲装箱就是基本数据类型自动转换为包装类,拆箱与之对应,包装类自动转换为基本数据类型。

        //自动装箱
        Integer s = 123;
        //上面语句其实相当于这条语句
        Integer ss = Integer.valueOf(123);

Integer s = 123自动将123装箱转换为包装类型。那么是如何实现自动装箱的呢,那就是执行了图中的第二条语句,看一下源码是如何实现的

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

可以看到首先会将参数会低值和高值比较(低值和高值在类中已给出,有兴趣可以看一下源码),低值low是-128,高值high是127。
高值赋值判断
如果参数大于等于-128 并且小于等于127则返回缓存中指定数据的包装类对象,否则返回一个新的对象。

比较一下代码,并判断一下

        Integer a = 127;
        Integer aa = 127;
        Integer b =  128;
        Integer bb = 128;
        int aaa = 127;
        int bbb = 128;
        
        System.out.println(a == aa);
        System.out.println(b == bb);
        System.out.println(a == aaa);
        System.out.println(b == bbb);

根据我们以前的想法,俩个数值相同 那么结果应该为true。但是执行结果并不是想象那样的。
执行结果

可以看到在为127是结果和我们想象的一样,但是为128时却为false,在看一下上面我们所说的,在自动装箱时但基本数据类型数据大于127时返回的是一个新对象,所以这里Integer b和bb所指向的引用并不是同一个对象。所以结果为false,这也就是java中的128陷阱。如果想要相等那么一定要拆箱比较。

通过分析源码发现,只有double和float的自动装箱代码没有使用缓存,每次都是new 新的对象,其它的6种基本类型都使用了缓存策略。
使用缓存策略是因为,缓存的这些对象都是经常使用到的(如字符、-128至127之间的数字),防止每次自动装箱都创建一次对象的实例。
而double、float是浮点型的,没有特别的热的(经常使用到的)数据的,缓存效果没有其它几种类型使用效率高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值