IDEA告警:Unnecessary unboxing ‘xxx.intValue()‘

x33g5p2x  于2022-04-07 转载在 其他  
字(1.0k)|赞(0)|评价(0)|浏览(424)


显式编码拆箱已包装的原始数值。在Java5及以上的版本,拆箱是不必要的,可以安全地删除。那么 JDK5 到底做了啥?

自动装箱(auto-boxing)与自动拆箱(auto-unboxing)

Java语言的基本类型都有包装(wrapper)类型。需要包装类型,是因为许多Java核心类库的API都是面向对象。如Java的容器类,就只支持引用类型。当需要一个能存储数值的容器类时,往往定义一个存储包装类对象的容器。

对基本类型的数值,需先将其转换为对应包装类,再存入容器。在Java程序中,这个转换可显式,也可隐式,后者即Java的自动装箱。

构造一个Integer类型ArrayList,向其中添加一个int值0。然后,获取该ArrayList的第0个元素,并作为int值返回,对应字节码:

当向泛型参数为Integer的ArrayList添加int值时,便用到自动装箱。字节码偏移量为10的指令,调用了Integer.valueOf,将int类型的值转换为Integer,再存储至容器类。

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

当请求的int值在某个范围内时,会返回缓存的Integer对象;在范围之外时,新建Integer对象。

参数java.lang.Integer.IntegerCache.high影响这里的IntegerCache.high。可配置该参数,扩大Integer缓存的范围。Java虚拟机参数**-XX:+AggressiveOpts**也会将IntegerCache.high调整至20000。

Java并不支持对IntegerCache.low的更改,对小于-128的整数,无法直接使用由Java核心类库所缓存的Integer对象。

25: invokevirtual java/lang/Integer.intValue:()I

当从泛型参数为Integer的ArrayList取出元素时,我们得到的实际上也是Integer对象。如果应用程序期待的是一个int值,那么就会发生自动拆箱,对应字节码偏移量为25的指令,调用Integer.intValue,直接返回Integer对象所存储的int值。

相关文章