Author : Cyan_RA9
Source : 【卡码笔记】网站
Question : 解释一下Java中的自动装箱和拆箱?
【简要回答】
-
拆装箱介绍 :
- 装箱 : 基本类型 ——> 包装类型(或者叫对象类型,引用类型)
- 拆箱 : 包装类型 ——> 基本类型
-
手动拆装箱 :
JDK5.0之前,拆装箱均是手动完成的。- 手动装箱,可以使用包装类的构造器来完成,也可以使用 valueOf() 方法。
- 手动拆箱,以Integer类为例,需要用到 intValue() 方法。
-
自动拆装箱 :
JDK5.0开始,java提供了自动拆装箱的机制。(不需要手动调用构造器或者方法了)- 自动装箱 : 实际上 底层仍然调用了valueOf() 方法。
- 自动拆箱 : 实际上 底层仍然调用了intValue() 方法(以Integer包装类为例)
-
代码演示:
//JDK5.0之前,拆装箱都是手动完成。 int temp = 19; //手动装箱(基本类型 ————> 包装/引用类型) Integer integer_0 = new Integer(temp); //划线表示该构造方法已过时 Integer integer_1 = new Integer(11); Integer integer_2 = Integer.valueOf(temp); //手动拆箱(包装/引用类型 ————> 基本类型) int tempI_0 = integer_0.intValue(); //该方法的接收类型为int类型 //JDK5.0以后,java提供了自动拆装箱 Integer integer_3 = 199; //(自动)装箱——其实底层调用的仍然是valueOf方法(可Debug) int tempI_1 = integer_3; //(自动)拆箱——其实底层调用的仍然是intValue方法
【详细回答】
-
拆装箱介绍:
- 装箱(Boxing):将基本数据类型转换为对应的包装类型(也称为对象类型或引用类型);eg:将 int 转换为 Integer。
- 拆箱(Unboxing):将包装类型转换回基本数据类型;eg:将 Integer 转换为 int。
-
手动拆装箱:
在 JDK 5.0 之前,Java 没有自动拆装箱机制,开发者需要手动完成拆装箱操作。- 手动装箱:使用包装类的构造器(如 new Integer(10)),但这种方式已过时(Deprecated);更推荐使用包装类的静态方法
valueOf(..)。 - 手动拆箱:使用包装类的实例方法,例如intValue()、doubleValue() 等。
-
自动拆装箱:
从 JDK 5.0 开始,Java 引入了 自动拆装箱 机制,开发者不需要手动调用方法,编译器会自动完成拆装箱操作。- 自动装箱:将基本数据类型直接赋值给包装类型时,编译器底层会自动调用 valueOf(..) 方法。
- 自动拆箱:将包装类型直接赋值给基本数据类型时,编译器底层会自动调用 intValue()、doubleValue() 等方法。
-
底层实现:
-
自动装箱:底层调用包装类的 valueOf(..) 方法。eg:Integer.valueOf(..) 方法会缓存
-128到127之间的整数,因此在自动装箱时,如果值在这个范围内,会直接从缓存中获取对象,而不会创建新的对象。自动装箱的代码演示如下:Integer a = 100; // 调用 Integer.valueOf(100) Integer b = 100; // 从缓存中获取,a 和 b 是同一个对象 (若 a和b 都是new出来的,那么 a和b 是不同的对象) Integer c = 200; // 超出缓存范围,创建新的对象 Integer d = 200; // 创建新的对象,c 和 d 是不同的对象 -
自动拆箱:底层调用包装类的 intValue()、doubleValue() 等方法。自动拆箱的代码演示如下:
Integer integer = 10; int num = integer; // 调用 integer.intValue()
-
-
代码演示:
// JDK 5.0 之前,手动拆装箱 int temp = 19; // 手动装箱 Integer integer_0 = new Integer(temp); // 已过时 Integer integer_1 = Integer.valueOf(temp); // 手动拆箱 int tempI_0 = integer_0.intValue(); // JDK 5.0 之后,自动拆装箱 Integer integer_3 = 199; // 自动装箱——底层调用 valueOf(199) 方法 int tempI_1 = integer_3; // 自动拆箱——底层调用 intValue() 方法
【知识拓展】
-
Java 中的基本数据类型和对应的包装类型如下:
基本数据类型 包装类型 byte Byteshort Shortint Integerlong Longfloat Floatdouble Doublechar Characterboolean Boolean -
null值问题:-
自动拆箱时,如果包装类型的值为
null,会抛出NullPointerException。演示代码如下:Integer integer = null; int num = integer; // 抛出 NullPointerException
-
-
性能问题:
-
频繁的拆装箱操作可能会导致额外的对象创建和内存开销,尤其是在循环中。演示代码如下:
for (int i = 0; i < 100000; i++) { Integer integer = i; // 对于 -128 到 127 之间的值,从缓存中获取对象;否则创建新的对象 }
-