考虑以下玩具方法:
public Float testReturnFloat() {
return 2f;
}
以下客户端代码:
float resultOne = testReturnFloat();
Float resultTwo = testReturnFloat();
现在两个调用都涉及自动装箱,或者只涉及后者,即使Float testReturnFloat()
已被用作方法签名?
小注意:这个问题仅用于理论分析,我遇到了它,因为我几乎把这个问题写入生产代码中。
答案 0 :(得分:9)
testReturnFloat()
本身涉及自动装箱,因为原始浮动2f
在返回之前被隐式转换为Float
。现在你写的时候
float resultOne = testReturnFloat();
结果再次取消装箱以生成原始float
,然后将其分配给resultOne
。
写作时
Float resultTwo = testReturnFloat();
没有什么特别的事情发生。 Float
返回的testReturnFloat()
已分配给resultTwo
。
理解这一点的最好方法是查看字节码。这是testReturnFloat()
的字节码:
public java.lang.Float testReturnFloat();
Code:
0: fconst_2
1: invokestatic #57 // Method java/lang/Float.valueOf:(F)Ljava/lang/Float;
4: areturn
如您所见,Float.valueOf()
(2f
)会调用fconst_2
。这是我正在谈论的自动装箱。
现在为您的客户代码:
float resultOne = testReturnFloat();
变为
0: invokestatic #16 // Method testReturnFloat:()Ljava/lang/Float;
3: invokevirtual #20 // Method java/lang/Float.floatValue:()F
6: fstore_1
请注意,取消装箱通过Float#floatValue()
进行。
最后,
Float resultTwo = testReturnFloat();
变为
7: invokestatic #16 // Method testReturnFloat:()Ljava/lang/Float;
10: astore_2
正如我所说,没什么特别的; testReturnFloat()
的返回值仅存储在resultTwo
。