小编典典

Java自动装箱/拆箱如何工作?

java

从JDK 5.0开始,自动装箱/拆箱是在Java中引入的,这种技巧很简单而且很有帮助,但是当我开始测试包装器类和原始类型之间的不同转换时,我真的很困惑自动装箱的概念在Java中的工作原理:

Boxing

int intValue = 0;
Integer intObject = intValue;
byte byteValue = 0;
intObject = byteValue; // ==> Error

尝试不同的情况下后(short,long,float,double),这是由编译器所接受的唯一情况是,当值的上做作运算符右侧的类型是int。当我查看源代码时,Integer.class发现它仅实现一个带int参数的构造函数。

因此,我的结论是,自动装箱的概念基于在包装类中实现的构造函数。我想知道这个结论是否正确,还是自动装箱使用了另一个概念?

Unboxing

Integer intObject = new Integer(0);
byte byteValue = intObject; // ==> Error (the same Error with short)
int intValue = intObject; 
double doubleValue = intObject;

我关于拆箱的结论是,包装器类提供了对象以相应类型(Integer==> int)包装的值,然后编译器使用转换原始类型的常规规则(byte=> short=> int=> long=> float=> double)。我想知道这个结论是否正确,还是自动拆箱使用了另一个概念?

谢谢你的进阶:)


阅读 386

收藏
2020-03-16

共1个答案

小编典典

如有疑问,请检查字节码:

Integer n = 42;

变成:

0: bipush        42
2: invokestatic  #16                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1   

因此,实际上,它valueOf()是与构造函数相对使用的(其他包装类也是如此)。这是有益的,因为它允许缓存,并且不会在每次装箱操作时强制创建新对象。

反之则如下:

int n = Integer.valueOf(42);

变成:

0: bipush        42
2: invokestatic  #16                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: invokevirtual #22                 // Method java/lang/Integer.intValue:()I
8: istore_1  

intValue()使用(同样,它也与其他包装类型类似)。这实际上是所有自动装箱归结为。

你可以分别在JLS§5.1.7和JLS§5.1.8中了解装箱和拆箱转换。

2020-03-16