java.lang.Integer-自动装箱和拆箱

什么是装箱和拆箱

装箱:把基本数据类型转换成包装类。

拆箱:把包装类转换成基本数据类型。

在JDK1.5中,为了减少开发人员的工作,Java提供了自动拆箱与自动装箱功能。

自动装箱与自动拆箱的实现原理

如下所示源代码

生成class文件后,再反编译得到的源代码如下所示

装箱操作是通过以下代码实现Integer a = Integer.valueOf(1);
拆箱操作是通过如下代码实现int c = a.intValue();

是编译器自动加上的代码。

图二

哪些场景会自动拆装箱

赋值操作也会进行拆箱和装箱操作除了这个还有以下几种场景

一、将基本类型放到集合里时,会自动装箱,参考图二

List<Integer> list=new ArrayList<>();
list.add(1);//1 这个值被自动装箱,并把装箱好的对象引用塞给list
int b=list.get(0);//list里的第0个对象被取出,自动拆箱,把值赋给b

二、当一个基础数据类型与包装类进行==、>、<、+、-、*、/运算时,先将包装类进行拆箱成基本数据类型。

反编译后的代码为

三、当两个包装类型进行算术运算时,也会被自动拆箱成基本类型进行

反编译后的代码如下所示

 

四、三目运算符,i自动拆箱,如果i为null则会抛出空指针异常

Integer i=null;
int j=1;
int k=true?i:j;//i自动拆箱

五、函数参与与返回值

源码

反编译后的代码

 

六、调用equals进行比较(装箱)

从执行结果可分析得知equals方法的形参最后装箱成了包装类型,虽然num3和num1与num2相加的结果数值相同,但是equals方法只有类型相同,并且数据相同的时候才会返回true,其他情况均为false。Long的equals方法如下所示

 

反编译得到的源码为

 

自动拆装箱与缓存

自动装箱时,会调用以下方法,当i的值为-128-127中的一个数时,此时会从缓存里拿对象返回,如果超出范围会new Integer

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

例如如下图所示

a==b是因为a与b是引用的同一个对象(地址相同),即缓存对象

a!=c是因为a是缓存对象,c是new的一个新对象,引用地址不同

d!=f是因为首先d超出了-128-127的范围,所以需要new一个,同事f也是一样

d!=g是因为d与g都是通过new来获取到的对象

 

下面我们进行一个归类: 
Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。 
Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。没有缓存。

总结

1、装箱操作会创建对象(缓存的除外),频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。

参考

详解Java的自动装箱与拆箱(Autoboxing and unboxing)

什么是Java中的自动拆装箱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值