我想知道为什么以及这段代码是如何工作的。 原始类型不是扩展对象所以为什么这个工作?
public class Main
{
public static void main(String[] args) {
double rndValue = 232;
showObj(rndValue);
}
public static void showObj(Object obj)
{
System.out.printf(obj.toString());
}
}
请尽可能详细解释。提前感谢大家。
答案 0 :(得分:3)
这是一个名为Java language feature的boxing,它允许基本类型使用引用类型参数,变量或集合。编译器将生成适当的代码以在您的案例中获得 1 a java.lang.Integer
。
反汇编清楚地说明了这一点:
public static void main(java.lang.String[]);
Code:
0: ldc2_w #2 // double 232.0d
3: dstore_1
4: dload_1
5: invokestatic #4 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
8: invokestatic #5 // Method showObj:(Ljava/lang/Object;)V
11: return
在指令5中,编译器生成对Double.valueOf(double)
的调用,该调用用于实际获取必要的对象。
1 获取一词用于代替 construct ,因为对象可能被缓存。由于不变性,这不是问题。
答案 1 :(得分:1)
这里有两件事 - 拳击转换(double
到Double
)和参考扩展转换(Double
到Object
)。调用showObj
并将rndValue
分配给obj
时,会发生分配转换,JLS, Section 5.2明确允许装箱转换后跟参考扩展转换:
分配上下文允许使用以下之一:
身份转换(第5.1.1节)
扩大原始转换(第5.1.2节)
扩大参考转换(第5.1.5节)
拳击转换(§5.1.7),可选地后跟扩展参考转换
一个拆箱转换(第5.1.8节),可选地后跟一个加宽的原语转换。
(强调我的)
答案 2 :(得分:0)
它将int
转换为Integer
,这是一个对象。此过程称为autoboxing。