我问道:
自动装箱/拆箱是在运行时(JVM)还是编译时(编译器)完成的?
我收到了这个答案:
通过将编译器的方法调用和强制转换插入到代码中来实现自动装箱。这些调用和强制转换在运行时处理。
请详细说明。
答案 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的静态类型安全所必需的。