前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官六连问拆箱装箱Integer那些事,给我整懵圈了!

面试官六连问拆箱装箱Integer那些事,给我整懵圈了!

作者头像
乔戈里
发布2020-02-21 16:02:02
5250
发布2020-02-21 16:02:02
举报
文章被收录于专栏:Java那些事Java那些事

小萌:由于基本数据类型不是对象,所以java并不是纯面向对象的语言,好处是效率较高(全部包装为对象效率较低)。Java是一个面向对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

小萌:

基本类型

包装器类型

boolean

Boolean

char

Character

int

Integer

byte

Byte

short

Short

long

Long

float

Float

double

Double

Number是所有数字包装类的父类

小萌:

•自动装箱:可以将基础数据类型包装成对应的包装类•Integer i = 10000; // 编译器会改为new Integer(10000)•自动拆箱:可以将包装类转为对应的基础数据类型•int i = new Integer(1000);//编译器会修改为 int i = new Integer(1000).intValue();•自动拆箱时如果包装类是null,那么会抛出NPE

面试官:第一题:

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

第二题:

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

第三题:

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

new Integer(100) 与 Integer.valueOf(100) 的区别在于:

•new Integer(100) 每次都会新建一个对象;•java在编译Integer i = 100 ;时,会翻译成为Integer i = Integer.valueOf(100);而java API中对Integer类型的valueOf的定义如下:

在 Java 8 中,Integer 缓存池的大小默认为 -128~127。

代码语言:javascript
复制
// 根据JLS的要求,缓存以支持-128和127(包括)之间的值的自动装箱。
// 缓存在首次使用时初始化。
// 缓存的大小可以由{@code -XX:AutoBoxCacheMax = <size>}选项控制。
// 在JVM初始化期间,可以设置java.lang.Integer.IntegerCache.high属性并将其保存在私有系统属性sun.misc.VM类。

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

Integer.valueOf(100) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。所以这三个题的答案也昭然若揭。

第一题由于都是调用缓存池中的数值,是同一个对象,所以是相等:

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

第二题由于 new Integer(100) 每次都会新建一个对象,两个对象的地址不同,所以结果为false:

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

第三题由于128不在Integer 缓存池的大小默认为 -128~127中,所以两者不是同一个对象,所以不相等:

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

其中Integer缓冲池 IntegerCache 是 Integer 类的一个私有静态内部类,其中关键部分是static final Integer cache[];,即它内部保存了Integer类型的数组,用以缓存值在 IntegerCache.low ~ IntegerCache.high 之间的Integer对象。

为什么设计这个缓存?

实践发现,大部分数据操作都是集中在有限的、较小的数值范围。所以在Java 5 中增加了静态工厂方法 valueOf(),在调用它的时候利用缓存机制,这样不用反复new 值相同的Integer对象,减少了内存占用。

基本类型对应的缓冲池如下:

•boolean values true and false•all byte values•short values between -128 and 127•int values between -128 and 127•char in the range \u0000 to \u007F

在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。

这是代码的开头的注释:

•// 缓存在首次使用时初始化。•// 缓存的大小可以由{@code -XX:AutoBoxCacheMax = }选项控制。•// 在VM初始化期间,可以设置java.lang.Integer.IntegerCache.high属性并将其保存在私有系统属性sun.misc.VM类。

在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特殊,这个缓冲池的下界是 - 128,上界默认是 127,但是这个上界是可调的,在启动 jvm 的时候,通过-XX:AutoBoxCacheMax = ; 来指定这个缓冲池的大小,该选项在 JVM 初始化的时候会设定一个名为 java.lang.IntegerCache.high 系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。

参考:

•https://blog.csdn.net/darlingwood2013/article/details/96969339•https://www.cnblogs.com/guodongdidi/p/6953217.html•https://github.com/CyC2018/CS-Notes](https://github.com/CyC2018/CS-Notes

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

本文分享自 程序员乔戈里 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档