Java 中的自动装箱/拆箱是如何工作的? [英] How does auto boxing/unboxing work in Java?

查看:29
本文介绍了Java 中的自动装箱/拆箱是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Since JDK 5.0, auto boxing/unboxing was introduced in Java. The trick is simple and helpful, but when I started testing different conversions between wrapper classes and primitive types, I get really confused how the concept of auto boxing works in Java. For example:

拳击

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

尝试不同的情况(shortlongfloatdouble)后,唯一的情况是编译器接受的是当做作运算符右边的值的类型为int时.当我查看 Integer.class 的源代码时,我发现它只实现了一个带有 int 参数的构造函数.

After trying different cases (short, long, float, double), the only case which is accepted by the compiler is when the type of the value on the right of affectation operator is int. When I looked inside the source of Integer.class I found that it implements only one constructor with int parameter.

所以我的结论是自动装箱的概念是基于在包装类中实现的构造函数.我想知道这个结论是真的还是自动装箱使用的另一个概念?

So my conclusion is that the concept of auto boxing is based on constructor implemented in the wrapper class. I want to know if this conclusion is true or there is another concept used by auto boxing?

拆箱

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).我想知道这个结论是否正确,或者自动拆箱使用了另一个概念?

My conclusion about unboxing is that the wrapper class gives the value wrapped by the object in the corresponding type (Integer ==> int), then the compiler use the usual rules of converting primitive types (byte => short => int => long => float => double). I want to know if this conclusion is true or there is another concept used by auto unboxing?

推荐答案

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

When in doubt, check the bytecode:

Integer n = 42;

变成:

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

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

So in actuality, valueOf() is used as opposed to the constructor (and the same goes for the other wrapper classes). This is beneficial since it allows for caching, and doesn't force the creation of a new object on each boxing operation.

反之如下:

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() 被使用(同样,对于其他包装器类型也是类似的).这实际上是所有自动(取消)拳击归结为.

i.e. intValue() is used (again, it's analogous for the other wrapper types as well). This is really all auto(un)boxing boils down to.

您可以在 阅读有关装箱和拆箱转换的信息JLS §5.1.7JLS §5.1.8,分别.

You can read about boxing and unboxing conversions in JLS §5.1.7 and JLS §5.1.8, respectively.

这篇关于Java 中的自动装箱/拆箱是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆