0%

装箱与拆箱

装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;

1
2
Integer i = 10;  //装箱
int n = i; //拆箱

上面这两行代码对应的字节码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
L1

LINENUMBER 8 L1

ALOAD 0

BIPUSH 10

INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;

PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;

L2

LINENUMBER 9 L2

ALOAD 0

ALOAD 0

GETFIELD AutoBoxTest.i : Ljava/lang/Integer;

INVOKEVIRTUAL java/lang/Integer.intValue ()I

PUTFIELD AutoBoxTest.n : I

RETURN

从字节码中,我们发现装箱其实就是调用了 包装类的 valueOf()方法,拆箱其实就是调用了 xxxValue()方法。因此

1
2
Integer i = 10 等价于 Integer i = Integer.valueOf(10)
int n = i 等价于 int n = i.intValue();

注意 1如果频繁拆装箱的话,也会严重影响系统的性能。我们应该尽量避免不必要的拆装箱操作。

1
2
3
4
5
6
7
private static long sum() {
// 应该使用 long 而不是 Long,避免拆箱浪费性能
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++)
sum += i;
return sum;
}

注意 2:拆箱时需要注意是否会报空指针错误

1
2
3
4
Integer i1 = null;
System.out.println(i1.intValue());

// Exception in thread "main" java.lang.NullPointerException