在java中我们可以装箱然后加宽。为什么我们不能扩大和包装? 例如:
class WidenAndBox{
static void go(Long x) { }
public static void main(String [] args)
{
byte b=5;
go(b);
}
}
编译器错误
答案 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()方法的行:
但是在你的情况下。为什么编译器在试图处理WidenAndBox类时尝试使用box-then-widen逻辑?
如果它首先尝试打包,则该字节将被转换为字节。现在我们又回到尝试将字节扩展到Long,当然,IS-A测试失败了。
答案 2 :(得分:2)
我认为主要原因是表现。如果允许扩展和(非)装箱的任意组合,则需要检查是否存在更多可能匹配的方法。特别是在函数需要多个小范围原始参数的上下文中,可能的组合量可能会变得非常大。
答案 3 :(得分:1)
把它投了很久。
答案 4 :(得分:1)
只需将其转换为长型
go( (long) b);