考虑以下两个类:
public interface Foo<T>
{
public T moo();
}
public class IntFoo implements Foo<Integer>
{
public int moo()
{
return 0;
}
}
此代码将在以下位置产生错误public
int
moo
,说的是int
与重写方法的返回类型不兼容Integer
。严格来说,这是真的,因为int
才不是directly equal Integer
。然而,我们都知道它们可以使用自动(取消)装箱隐式地相互转换。鲜为人知的是,编译器在此示例中生成了一个桥接方法:
public class IntFoo implements Foo<Integer>
{
public <synthetic> <bridge> Object moo()
{
return this.moo(); // upcast
}
public Integer moo() {
return 0;
}
}
必须这样做,因为 JVM 在解析方法时会区分返回类型,并且由于擦除的返回类型Foo.moo
is 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 会话的屏幕截图表明我什至能够在我的自定义编程语言 https://github.com/Dyvil/Dyvil(编译为 Java 字节码):
与这些问题一样,答案是您必须询问语言设计者。我看不出有什么理由不能做到这一点。但在我看来,这个功能毫无意义。正如您在问题中指出的那样,只有当moo
在静态类型的变量上调用IntFoo
将返回一个原语;在类型变量上Foo<Integer>
, an Integer
无论如何都会被退回。因此,通过这样做,您基本上可以实现相同的目标。
public class IntFoo implements Foo<Integer> {
@Override
public Integer moo() { return mooAsInt(); }
public int mooAsInt() { return 0; }
}
就我个人而言,我认为这更好,因为当拳击发生/不发生时,它更加明显。在你的提议中,moo()
可以返回一个int
or an Integer
取决于变量的静态类型,这会非常令人困惑。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)