什么时候自动进行自动装箱?

时间:2014-05-21 13:21:28

标签: java autoboxing

考虑以下玩具方法:

public Float testReturnFloat() {
    return 2f;
}

以下客户端代码:

float resultOne = testReturnFloat();
Float resultTwo = testReturnFloat();

现在两个调用都涉及自动装箱,或者只涉及后者,即使Float testReturnFloat()已被用作方法签名?

小注意:这个问题仅用于理论分析,我遇到了它,因为我几乎把这个问题写入生产代码中。

1 个答案:

答案 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