前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Integer 中你所不知道的

Integer 中你所不知道的

作者头像
haifeiWu
发布2020-02-10 18:45:33
5180
发布2020-02-10 18:45:33
举报

前几天和我六哥讨论技术的时候说到了 Integer,大家可能觉得 Intger 有什么好说的,不就是 int 吗,Java 装箱拆箱机制。那么现在有这样一个问题:

代码语言:javascript
复制
System.out.println(new Integer(1) == (new Integer(1)));
System.out.println(new Integer(1).equals(new Integer(1)));
System.out.println(Integer.valueOf(1) == Integer.valueOf(1));
System.out.println(Integer.valueOf(129) == Integer.valueOf(129));

这四行代码分别输出什么,为什么? 答案:false、true、true、false

如果你没答出来,那么请继续往下看吧~

IntegerCache

对,先说这个类,一看名字就知道是 Integer 缓存,它是 Integer 的一个静态内部类。源码不多,先看代码:

代码语言:javascript
复制
private static class IntegerCache {
    static final int low = -128;
    static final int high;    // 这个值可以在vm属性配置
    static final Integer cache[];

    static {
        ... // 给 high 赋值,从 vm 属性配置获取配置值,默认 127

        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;
    }
}

由上面源码可以看出,IntegerCache 会缓存值为 -128 ~ 127 的 Integer 对象,那么什么时候调用呢? 源码中只有一个地方:valueOf()

代码语言: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 的时候,如果值在 -128 到 127 的范围,就会使用 IntegerCache 中的缓存对象。

解答

针对 new Integer(1) == (new Integer(1)),源码没有做特殊处理,就是 new 了两个不同的对象,他们当然是不相等的,返回 false;

针对 new Integer(1).equals(new Integer(1)),可以看一下 Integer.equals() 函数的实现,函数内部是直接比较两个对象的 value 是否相等,他们的 value 都是 1,所以返回 true;

针对 Integer.valueOf(1) == Integer.valueOf(1),就是我们前面提到的 IntegerCache 了,Integer.valueOf 会直接使用缓存好的对象,两个值相等,所以对象也是相同的,返回 true;

针对 Integer.valueOf(129) == Integer.valueOf(129),由于缓存的范围是 -128 ~ 127,值 129 显然是超出范围了,所以会 new 一个新对象,也不会相等,返回 false;

装箱拆箱

再看一下以下输出:

代码语言:javascript
复制
Integer i = 100;
Integer j = 100;
System.out.print(i == j);       //true

以上例子,Java 在编译是会自动装箱,编译为:Integer i = Integer.valueOf(100),又看到了 valueOf,用了缓存的 Integer,所以输出 true。

代码语言:javascript
复制
Integer i = new Integer(100);
int j = 100;
System.out.print(i == j);       //true

以上例子,在 int 和 Integer 相比较时,Java 编译器会自动把 Integer 拆箱为 int 类型,所以输出 100。

拓展

好,看完了 Integer,我突然想起了其他的包装器类会不会也是这样,于是分别看了一下源码。

我直接说结果吧,有兴趣的同学可以看一下源码:Long,Short 这两个类,内部也缓存了 -128 ~ 127 的对象,Boolean 内部缓存了 TRUE、FALSE 两个对象。和 Integer 类似,都是在调用 valueOf 方法的时候生效,new 的时候不会这样。

作 者:ChanghuiN 原文链接:https://www.hchstudio.cn/article/2019/223d/ 版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • IntegerCache
  • 解答
  • 装箱拆箱
  • 拓展
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档