请考虑以下两类:
public interface Foo<T>
{
public T moo();
}
public class IntFoo implements Foo<Integer>
{
public int moo()
{
return 0;
}
}
此代码将在
public
int
moo
处产生错误,表示int
与重写的方法的返回类型Integer
不兼容。严格来说,这是正确的,因为int
不直接等于Integer
。但是,我们都知道可以使用自动装箱将它们隐式地彼此转换。鲜为人知的是,在此示例中,编译器会生成一个桥接方法:public class IntFoo implements Foo<Integer>
{
public <synthetic> <bridge> Object moo()
{
return this.moo(); // upcast
}
public Integer moo() {
return 0;
}
}
之所以必须这样做,是因为JVM在解析方法时会区分返回类型,并且由于
Foo.moo
的擦除返回类型为Object
,因此编译器生成了一个桥方法,该桥方法具有与该方法相同的签名。我想知道为什么这也不适用于原始多态返回类型:
public class IntFoo implements Foo<Integer>
{
public <synthetic> <bridge> Object moo()
{
return Integer.valueOf(this.moo());
}
public int moo()
{
return 0;
}
}
似乎没有任何理由不具有此功能:
IntFoo intFoo = new IntFoo();
Foo<Integer> foo = intFoo;
Integer i = foo.moo(); // calls the synthetic method, which boxes the result of the actual implementation
实际上,REPL session 的屏幕截图显示,我什至可以在ojit_a(编译为Java字节码)中实现此功能:
custom programming language
最佳答案
与这些问题一样,答案是您必须问语言设计师。我看不到无法完成此操作的任何原因。但是我认为此功能将毫无意义。正如您在问题中指出的那样,只有在静态类型为moo
的变量上调用IntFoo
时,才会返回原语。在类型为Foo<Integer>
的变量上,无论如何都会返回Integer
。因此,您可以通过执行此操作来实现基本相同的目的。
public class IntFoo implements Foo<Integer> {
@Override
public Integer moo() { return mooAsInt(); }
public int mooAsInt() { return 0; }
}
我个人认为这样做比较好,因为装箱/不装箱会更明显。在您的建议中,
moo()
可能会返回int
或Integer
,具体取决于变量的静态类型,这将非常令人困惑。关于java - 为什么不能将原始类型与多态返回类型一起使用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32418456/