前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记住这道必考题:不是所有包装类型都有缓存的!

记住这道必考题:不是所有包装类型都有缓存的!

作者头像
程序视点
发布2023-11-10 18:45:23
2011
发布2023-11-10 18:45:23
举报
文章被收录于专栏:程序小小事程序小小事

大家好,欢迎来到程序视点!我是小二哥。

上一篇文章中,我们分辨了基本类型和包装类型的区别。今天我们来聊聊包装类型的缓存机制。

笔试题

关于包装类型的缓存机制,几乎是一道必考题。题例大概如下:

代码语言:javascript
复制
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
代码语言:javascript
复制
Integer a = 200;
Integer b = 200;
System.out.println(a == b);

请给出上面两处打印的结果。答案分别是:truefalse

ps:如果你能正确给出答案,且能明白其中缘由,请直接查看文末最后一题。如果文末的题目你也能做对,且明白其中原因,那以下内容就可以直接跳过了;反之,请详细阅读本文。

同样都是包装类型的赋值,比较结果却不一样,这是怎么回事呢?这和自动装箱有关。

把基本类型转换成包装类型的过程叫做装箱(boxing)。

自动装箱的发生,就涉及到包装类型的缓存机制。(我们会在下一篇文章中来说明这个知识点)

包装类型的缓存源码

Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。

先记住下面这四句话:

Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据。 Character 创建了数值在 [0,127] 范围的缓存数据。 Boolean 直接返回 True or False。 两种浮点数类型的包装类 Float和Double 没有实现缓存机制。

自动装箱是通过包装类的 valueOf() 方法完成的。 因此,我们去看它们 valueOf() 方法的源码即可。

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);
}
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;
        ...
        high = h;

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

Integer 的缓存是由一个Integer数组来实现的(上面哪个 cache 数组)。

ps:我这里只摘取了核心的逻辑。详细源码,请自行查阅JDK源码!

同理,Character 缓存源码:

代码语言:javascript
复制
public static Character valueOf(char c) {
    if (c <= 127) { // must cache
      return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

private static class CharacterCache {
    private CharacterCache(){}
    static final Character cache[] = new Character[127 + 1];
    static {
        for (int i = 0; i < cache.length; i++)
            cache[i] = new Character((char)i);
    }

}

还有Boolean 缓存源码:

代码语言:javascript
复制
public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

至于Byte,Short和Long的缓存,就请大家抽空自己翻翻了。这里就不粘贴了。

特别注意:Float和Double 没有实现缓存机制。 我们来瞧瞧Double的valueOf()方法:

代码语言:javascript
复制
public static Double valueOf(double d) {
    return new Double(d);
}

在double进行自动装箱时,返回的是new出来的一个对象,即每一个都是不同的。

最后一题

根据上面的知识,看看下面这道题的输出结果:

代码语言:javascript
复制
Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);

Float i11 = 333f;
Float i22 = 333f;
System.out.println(i11 == i22);

Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);

答案分别是:truefalsefalse。你答对了吗?

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-11-09,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 程序视点 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 笔试题
  • 包装类型的缓存源码
  • 最后一题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com