简体   繁体   English

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

[英]How does auto boxing/unboxing work in Java?

Since JDK 5.0, auto boxing/unboxing was introduced in Java.从 JDK 5.0 开始,在 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.这个技巧很简单也很有帮助,但是当我开始测试包装类和原始类型之间的不同转换时,我真的很困惑自动装箱的概念在 Java 中是如何工作的。 For example:例如:

Boxing拳击

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

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 .在尝试了不同的情况( shortlongfloatdouble )之后,编译器唯一接受的情况是伪装运算符右侧的值的类型是int When I looked inside the source of Integer.class I found that it implements only one constructor with int parameter.当我查看Integer.class的源代码时,我发现它只实现了一个带有int参数的构造函数。

So my conclusion is that the concept of auto boxing is based on constructor implemented in the wrapper class.所以我的结论是,自动装箱的概念是基于在包装器 class 中实现的构造函数。 I want to know if this conclusion is true or there is another concept used by auto boxing?我想知道这个结论是真的还是自动拳击使用了另一个概念?

Unboxing拆箱

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

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 ).我关于拆箱的结论是,包装器short给出了由 Z byte包装的相应类型( Integer ==> int => 转换原始类型long常用规则) int => 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;

becomes:变成:

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

So in actuality, valueOf() is used as opposed to the constructor (and the same goes for the other wrapper classes).因此,实际上, valueOf()的使用与构造函数相反(其他包装类也是如此)。 This is beneficial since it allows for caching, and doesn't force the creation of a new object on each boxing operation.这是有益的,因为它允许缓存,并且不会在每次装箱操作时强制创建新对象。

The reverse is the following:反过来如下:

int n = Integer.valueOf(42);

which becomes:变成:

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      

ie intValue() is used (again, it's analogous for the other wrapper types as well).即使用intValue() (同样,它也类似于其他包装器类型)。 This is really all auto(un)boxing boils down to.这实际上是所有自动(取消)拳击归结为。

You can read about boxing and unboxing conversions in JLS §5.1.7 and JLS §5.1.8 , respectively.您可以分别在JLS §5.1.7JLS §5.1.8 中阅读有关装箱和拆箱转换的信息。

This confusion can be cleared by using a switch of javac -XD-printflat which is very helpful in cases such as this one.这种混淆可以通过使用 javac -XD-printflat的开关来清除,这在这种情况下非常有用。 So to unravel the mystery of boxing and unboxing you can write a simple program like following :因此,要解开装箱和拆箱的奥秘,您可以编写一个简单的程序,如下所示:

import java.util.*;

public class Boxing{
  public static void main(String[] args){
    Double d1 = 10.123;
    Float  f1 = 12.12f;
    Long   l1 = 1234L;
    Integer i1 = 55555;
    Short   s1 = 2345;
    Byte    b1 = 89;

    double d2 = d1;
    float  f2 = f1;
    long   l2 = l1;
    int    i2 = i1;
    short  s2 = s1;
    byte   b2 = b1;
  }
} 

and now we compile the above file as:现在我们将上述文件编译为:

javac -XD-printflat -d src/ Boxing.java javac -XD-printflat -d src/ Boxing.java

output of this command is a java file with all the syntactic sugar ( Generic types, enhanced for loop and in this case boxing-unboxing etc ) removed.此命令的输出是一个 Java 文件,其中删除了所有语法糖(通用类型、增强的 for 循环以及在这种情况下装箱拆箱等)。 following is the output以下是输出

import java.util.*;

public class Boxing {

    public Boxing() {
        super();
    }

    public static void main(String[] args) {
        Double d1 = Double.valueOf(10.123);
        Float f1 = Float.valueOf(12.12F);
        Long l1 = Long.valueOf(1234L);
        Integer i1 = Integer.valueOf(55555);
        Short s1 = Short.valueOf(2345);
        Byte b1 = Byte.valueOf(89);
        double d2 = d1.doubleValue();
        float f2 = f1.floatValue();
        long l2 = l1.longValue();
        int i2 = i1.intValue();
        short s2 = s1.shortValue();
        byte b2 = b1.byteValue();
    }
}

this is how java does boxing unboxing.这就是java如何进行装箱拆箱。 using valueOf and ***Value methods.使用 valueOf 和 ***Value 方法。

Auto boxing and auto unboxing自动装箱和自动拆箱

Auto boxing means when we try to assign a primitive data to a object type it automatically converts itself to the object type.that process called auto boxing.. and when a object type converts to the primitive type its called unboxing...try to understand it from following examples.自动装箱意味着当我们尝试将原始数据分配给对象类型时,它会自动将自身转换为对象类型。该过程称为自动装箱。它来自以下示例。

class Demo{
public static void main(String args[]){
    int x=100;

    //Integer iob=x; //Illegal jdk1.4
    Integer iob=Integer.valueOf(x); //Legal at JDK1.4 =>Boxing

    Integer iob2=x; //Legal JDK1.5 - Autoboxing
    System.out.println(iob2);
}

} }

another example for auto boxing自动拳击的另一个例子

class Demo{
public static void main(String args[]){
    Integer iob=new Integer(100);    
    int x;
    x=iob; //Legal => auto unboxing
    System.out.println(x);
}

} }

example for auto unboxing自动拆箱示例

class Demo{
public static void main(String args[]){
    Integer iob=new Integer(100);
    int x=iob; //Auto unboxing ==>Assignment

}

} }

thank you..谢谢你..

Consider the following code as an example of auto un-boxing:考虑以下代码作为自动拆箱的示例:

System.out.println('b'+ new Integer(63));

Here's a breakdown of how the above code is compiled:以下是对上述代码的编译方式的细分:

Step 1: Object Integer 63 is instantiated and then AUTO-UNBOXED to int 63步骤1:实例化对象Integer 63,然后AUTO-UNBOXED到int 63

new Integer(63)

Step 2: char 'b' is converted to numeric value ie 98第 2 步:将 char 'b' 转换为数值即 98

Step 3: the two values are added: 98+63第三步:两个值相加:98+63

Step 4: Output is 161第 4 步:输出为 161

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM