在java中为什么不加宽然后框?

时间:2010-01-12 18:39:31

标签: java core

在java中我们可以装箱然后加宽。为什么我们不能扩大和包装? 例如:

 class WidenAndBox{
  static void go(Long x)  {   }
  public static void main(String [] args)
   {
    byte b=5;
    go(b);
   }
}

编译器错误

5 个答案:

答案 0 :(得分:6)

我不知道规范是如何编写的,但一般来说,你不会在不兼容的类之间自动转换。扩展原语是一个单独的问题,并且在将自动装箱添加到语言之前很久就制定了Java扩展规则。这是让编译器抓住你的错误而不是用小细节激怒你的人之间的权衡。

在你的例子的情况下,如果你已经自动装了很长时间就可以了,或者你已经创建了一个以Number作为参数的函数,你也可以。您可能认为编译器应该通过认识到Byte可以轻松地取消装箱并重新装箱为Long来帮助您,但是那些使编译器不同意的人,我也不是。

答案 1 :(得分:3)

编译器可以执行装箱操作 然后进行扩展操作,以便将调用与方法匹配。 让我们举个例子

 class BoxAndWiden {
   static void go(Object o) {
   Byte b2 = (Byte) o; // ok - it's a Byte object
   System.out.println(b2);
   }
    public static void main(String [] args) {
    byte b = 5;
    go(b); // can this byte turn into an Object ? 
    }
    }

这会编译(!),并产生输出:5 让我展示它如何在幕后工作。当JVM时, 到了调用go()方法的行:

  1. 字节b被装箱为字节。
  2. 字节引用被扩展为Object(因为Byte扩展了Object)。
  3. go()方法获得了一个实际引用字节的Object引用 对象。
  4. go()方法将Object引用强制转换为Byte引用(re 在这个场景中,从来没有一个Object类型的对象,只有一个 Byte的类型对象!)。
  5. go()方法打印了Byte的值。
  6. 但是在你的情况下。为什么编译器在试图处理WidenAndBox类时尝试使用box-then-widen逻辑?

    如果它首先尝试打包,则该字节将被转换为字节。现在我们又回到尝试将字节扩展到Long,当然,IS-A测试失败了。

答案 2 :(得分:2)

我认为主要原因是表现。如果允许扩展和(非)装箱的任意组合,则需要检查是否存在更多可能匹配的方法。特别是在函数需要多个小范围原始参数的上下文中,可能的组合量可能会变得非常大。

答案 3 :(得分:1)

把它投了很久。

答案 4 :(得分:1)

只需将其转换为长型

 go( (long) b);