Java学习笔记——自动装箱、拆箱(Autoboxing and Unboxing)

一、概念

自动装箱(Autoboxing)指Java编译器自动将基本类型(primitive types)转换为其对应的包装类型对象(object wrapper classes)。
举个栗子,比如说int->Integerdouble->Double,如果是相反的情况,就称之为自动拆箱(Unboxing)。

二、自动装箱

1.案例驱动

我们来看下面这个案例:

List<Integer> list = new ArrayList<>();
for(int i = 0;i<50;i+=2)
    list.add(i);
复制代码

定义了一个泛型为Integer的Arraylist,按照泛型原则,我们在添加数据时,应该只能添加Integer类型的对象,添加基本数据类型会出现编译错误,但是在本案例中编译器并未报错。

2.原因分析

未报错的原因是Java编译器会创建一个int类型数据对应的Integer类型对象。
编译器会在运行时将案例代码转换成如下代码:

List<Integer> list = new ArrayList<>();
for(int i = 0;i<50;i+=2)
    list.add(Integer.valueOf(i));
复制代码

我们也可以通过反编译查看,将上述案例代码进行反编译如下:

D:\IdeaProjects\HighJava\out\production\practice\BoxandUnbox>javap -c AutoBoxing.class
Compiled from "AutoBoxing.java"
public class BoxandUnbox.AutoBoxing {
  public BoxandUnbox.AutoBoxing();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/util/ArrayList
       3: dup
       4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
       7: astore_1
       8: aload_1
       9: iconst_1
      10: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      13: invokevirtual #5                  // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      16: pop
      17: return
}

复制代码

可以看到,在main方法的Code10行中,在运行时真实的调用了Integer的静态方法valueOf()

三、自动拆箱

自动拆箱与自动装箱的实现原理相差不大,其本质是编译器在运行时自动调用了IntegerintValue()方法,在此不多做赘述。

四、总结

1.自动装箱

  • 基本类型作为参数传递到一个需要其对应包装类对象的方法时;
  • 赋值给其对应的包装类对象的变量

2.自动拆箱

  • 包装类对象作为参数传递到一个需要其对应基本类型的方法时;
  • 赋值给其对应的基本类型的变量

四、附加

下表为Java编译器可进行装拆箱的数据类型及其对应的包装类:

Primitive type wrapper class
boolean Boolean
byte Byte
short Short
int Integer
char Character
long Long
float Float
double Double
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享