前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Java】Integer 什么是128陷阱(源码分析)

【Java】Integer 什么是128陷阱(源码分析)

作者头像
哈__
发布2024-04-08 21:19:59
710
发布2024-04-08 21:19:59
举报
文章被收录于专栏:哈哈熊哈哈熊

一、128陷阱演示

代码语言:javascript
复制
 public static void main(String[] args) {
       Integer a = 110;
       Integer b = 110;
       Integer c = 130;
       Integer d = 130;
       System.out.println(a==b);
       System.out.println(c==d);
    }

 在上面的方法中我定义了四个变量a、b、c和d并且进行了两次比较。你认为输出结果是什么?难道是true和true吗?请看下面的测试结果。

 二、结果分析及讲解

答案并不是我们认为的两个true 而是一个true和一个false,这是我们就会想了,为什么都是Integer的比较,上边的是true,下边的就是false了?

到了这一步就要分析分析源码了,在我们进行声明的时候例如声明Integer a = 110,在我们的代码被编译之后,这行代码就等同于下图所示的代码。

代码语言:javascript
复制
 Integer a = 110;
 //Integer a = Integer.valueOf(110)
 Integer b = 110;
 //Integer b = Integer.valueOf(110)
 Integer c = 130;
 //Integer c = Integer.valueOf(130)
 Integer d = 130;
 //Integer d = Integer.valueOf(130)

其中注释的部分就是编译后对代码做出的调整。好的,既然我们要比较的是a和b,我们代码跟进到Integer类当中去查看这个方法。

代码语言:javascript
复制
public static Integer valueOf(int i) {
     if (i >= IntegerCache.low && i <= IntegerCache.high)
         return IntegerCache.cache[i + (-IntegerCache.low)];
     return new Integer(i);
 }

Integer类中的valueOf方法需要一个参数,就是我们为Integer对象赋的值,然后进行if判断,那么判断的又是什么呢?实际上有着这么一个缓存类IntegerCache。

代码语言:javascript
复制
 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

 这个IntegerCache类当中有着这么几个变量,low,high和cache[],low和high代表着这个缓存数组catch可以存储的数的范围,具体的代码不在讲解,通过static静态块将catch数组初始化,如果没有额外的配置,那么这个数组存储的数的范围就是-128~127之间。

现在回到我们的valueOf方法当中,知道了IntegerCache是什么之后,下边的部分就很好理解了,如果我们的参数范围在IntegerCache类的缓存数组的存储范围之内,我们就直接将存储在cache数组中的这个Integer返回,否则的话我们就会new出一个新的Integer来保存我们的值。

代码语言:javascript
复制
public static Integer valueOf(int i) {
     if (i >= IntegerCache.low && i <= IntegerCache.high)
         return IntegerCache.cache[i + (-IntegerCache.low)];
     return new Integer(i);
 }

回到我们最开始的部分。

代码语言:javascript
复制
 public static void main(String[] args) {
       Integer a = 110;
       Integer b = 110;
       Integer c = 130;
       Integer d = 130;
       System.out.println(a==b);
       System.out.println(c==d);
    }

 现在你是否可以明白a==b为什么为true以及c==d为什么为false了吗?就是因为a与b拿到的都是缓存数组当中的一个值,而c和d拿到的都是new出的新的Integer,他们的地址是不同的,所以是false,既然Integer是一个包装类,比较包装类中的一些属性我们能够想到一个方法equals,那么equals方法是否可行呢?答案是可以的。

本次文章就到这里了,对大家有帮助的话还希望大家给博主一个关注。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档