Java自动装箱与拆箱

自动装箱与拆箱

自动装箱与拆箱是自JDK 1.5 引入的概念:

  • 自动装箱:自动将基本数据类型变成对象
  • 自动拆箱:自动将对象转换回基本数据类型

基本数据类型与包装类对应如下:

Java自动装箱与拆箱_第1张图片

当表格中左边列出的基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱:

  • 进行 = 赋值操作(装箱或拆箱)
  • 进行四则运算(拆箱)
  • 进行 > < == 比较运算(拆箱)
  • 调用 equals 进行比较(装箱)
  • ArrayList、HashMap等集合类添加基本数据类型时(装箱)

Integer

​ 我们特别来看看非常特殊的 Integer 类,为什么特殊呢?看代码:

Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;
int i5 = 128;
Integer i6 = new Integer(127);
Integer i7 = new Integer(127);
System.out.println(i1 == i2);
// 结果:true
System.out.println(i3 == i4);
// 结果:false
System.out.println(i4 == i5);
// 结果:true
System.out.println(i6 == i7);
// 结果:false

​ 第 1-4 行都是将基本数据类型赋值给了包装类,这里就完成了自动装箱,因为包装类都是对象,是存储在堆中的。第 8 行将 i1 和 i2 两个对象进行比较,结果竟然是true,按理说就算两个对象的属性值一样也是不相等的呀,就像 i6 与 i7 一样,这是为什么呢?

image-20200719230223688

如图,通过字节码指令我们可以看到,自动装箱实际上是调用了 Integer 的 valueOf 方法,我们继续看valueOf 的源码:

Java自动装箱与拆箱_第2张图片

从源码中我们可以看到如果 i 大于 Interger 缓存的最小值或者小于 Integer 缓存的最大值,那么就会直接从Intefer 缓存中取数据,我们再查看 IntegerCache 源码可以看到,IntegerCache 创建了一个 cache 数组存储了从 -128到127共256个 Integer对象,也就是说我们在通过自动装箱创建Integer对象的时候,如果数值在 -127 -到 128 之间,就会直接从IntegerCache 中取出 Integer对象,否则会创建新的对象。因此 i1 和 i2 这两个通过自动装箱创建的对象引用实际上指向了 IntegerCache 中的同一个对象,故相等。而 i3、i4 超出了 IntegerCache的范围,所以会分别创建两个新的对象,因此是不相等的,等同于 i6 和 i7 。

Java自动装箱与拆箱_第3张图片

​ 而 i4 和 i5 相比较就是自动拆箱了,如图,通过字节码指令可以看到自动拆箱实际上是通过调用 Integer.intValue() 实现的,从intValue() 的源码可以看出直接返回了 Integer 对象的 value 值:

image-20200719233613530

Java自动装箱与拆箱_第4张图片

你可能感兴趣的:(笔记,面试)