一、概念
自动装箱(Autoboxing)指Java编译器自动将基本类型(primitive types)转换为其对应的包装类型对象(object wrapper classes)。
举个栗子,比如说int->Integer
,double->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()。
三、自动拆箱
自动拆箱与自动装箱的实现原理相差不大,其本质是编译器在运行时自动调用了Integer
的intValue()方法,在此不多做赘述。
四、总结
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