展开此自动装箱说明

时间:2012-03-15 04:37:30

标签: java boxing autoboxing

我问道:

  

自动装箱/拆箱是在运行时(JVM)还是编译时(编译器)完成的?

我收到了这个答案:

  

通过将编译器的方法调用和强制转换插入到代码中来实现自动装箱。这些调用和强制转换在运行时处理。

请详细说明。

3 个答案:

答案 0 :(得分:2)

来自Java规范

Chapter 5. Conversions and Promotions

  

用Java编程语言编写的每个表达式都有一个类型   这可以从表达式的结构和类型中推断出来   表达式中提到的文字,变量和方法。   但是,可以在上下文中编写表达式   表达式的类型不合适。在某些情况下,这会导致   在编译时出错。在其他情况下,上下文可能是   接受与表达式类型相关的类型; 作为一个   方便,而不是要求程序员指明类型   显式转换,Java编程语言执行   从表达式的类型到类型的隐式转换   其周围环境可以接受

从这里开始,我们知道即使程序员没有指明类型转换,编译器也会接受特定的表达式。这就是为什么下面的代码在编译时不会引发错误的原因。

int i = new Integer(3);
Integer j = 3;

Chapter 5. Conversions and Promotions 5.1.7. Boxing Conversion

  

...在运行时,拳击转换按如下方式进行:

     

如果p是boolean类型的值,则装箱转换会转换p   进入类的引用r并输入Boolean,这样   r.booleanValue()== p ...

Chapter 5. Conversions and Promotions 5.1.8. Unboxing Conversion

  

...在运行时,拆箱转换过程如下:

     

如果r是Boolean类型的引用,则取消装箱转换将转换   r进入r.booleanValue()...

这就是在运行时完全发生的事情。

答案 1 :(得分:1)

Autoboxing和unboxing是编译时进程。

我们可以通过如下所述的小测试进行验证:

创建一个名为'Crap'的Java项目。在其中,创建一个包含以下内容的.java文件:

public class Crap {

    private Boolean crap;

    public Boolean getCrap() {
        return crap;
    }

    public void setCrap(Boolean crap) {
        System.out.println("lol.. this is crap!!");
        this.crap = crap;
    }
}

构建此项目并导出为jar文件,例如crap.jar。

现在创建一个名为'Junk'的Java项目。将crap.jar文件添加到此项目的类路径中,然后创建一个包含以下内容的.java文件:

public class Junk {

    public static void main(String[] args) {
        Crap crap = new Crap();
        crap.setCrap(true);
    }
}

现在,构建Junk项目,并将Junk.java作为Java应用程序运行。它将成功运行,输出将

大声笑......这是废话!!

现在,修改Crap.java,将布尔crap修改为boolean以及相应的getter和setter。代码如下所示:

public class Crap {

    private boolean crap;

    public boolean getCrap() {
        return crap;
    }

    public void setCrap(boolean crap) {
        System.out.println("lol.. this is crap!!");
        this.crap = crap;
    }
}

再次构建此项目并将其导出为crap.jar。将此crap.jar文件放入Junk项目的类路径中(并从其类路径中删除早期的jar文件)。

现在,如果您尝试将Junk.java作为Java应用程序运行,那么您将获得以下stacktrace:

Exception in thread "main" java.lang.NoSuchMethodError: crap.Crap.setCrap(Ljava/lang/Boolean;) at junk.Junk.main(Junk.java:9)

答案 2 :(得分:0)

嗯,它说编译器做到了。所以它发生在编译时。

这是确保Java的静态类型安全所必需的。