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

时间:2014-03-25 23:41:17

标签: java autoboxing unboxing

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

拳击

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

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

所以我的结论是自动装箱的概念是基于包装类中实现的构造函数。我想知道这个结论是否属实,还是自动拳击还有另一个概念?

开箱

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)。 我想知道这个结论是否属实,还是自动拆箱使用了另一个概念?

感谢您提前:)

4 个答案:

答案 0 :(得分:13)

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

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.7JLS §5.1.8中阅读有关装箱和拆箱转化的信息。

答案 1 :(得分:0)

自动装箱和自动拆箱

自动装箱意味着当我们尝试将原始数据分配给对象类型时,它会自动将自身转换为对象类型。这个过程称为自动装箱...当对象类型转换为基本类型时,其称为拆箱...尝试通过以下示例来理解它。

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);
}

}

自动装箱的另一个例子

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

}

自动取消装箱的示例

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

}

}

谢谢..

答案 2 :(得分:0)

请考虑以下代码作为自动解除拳击的示例:

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

以下是对上述代码编译方式的细分:

步骤1:对象整数63被实例化,然后AUTO-UNBOXED到int 63

new Integer(63)

第2步:char' b'被转换为数值,即98

步骤3:添加两个值:98 + 63

步骤4:输出为161

答案 3 :(得分:0)

可以通过使用javac -XD-printflat 开关来消除这种混乱,这在诸如此类的情况下非常有用。因此,要解开装箱和拆箱的奥秘,您可以编写一个简单的程序,如下所示:

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;
  }
} 

现在我们将以上文件编译为:

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

此命令的输出是一个Java文件,其中删除了所有语法糖(通用类型,为循环增强,在这种情况下为box-unboxing等)。以下是输出

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();
    }
}

这是java装箱拆箱的方式。使用valueOf和*** Value方法。