考虑以下两个类:
public interface Foo<T> { public T moo(); } public class IntFoo implements Foo<Integer> { public int moo() { return 0; } }
该代码会在publicintmoo中产生错误,表示int与重写方法的返回类型Integer不兼容.严格来说,这是真的,因为int并不直接等于整数.然而,我们都知道,他们可以使用auto(un)拳击相互隐含地转换.在这个例子中,编译器生成一个桥接方法是不太了解的事实:
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会话的这个屏幕截图显示,我甚至能够在我的custom programming language(它编译为Java字节码)中实现:
解决方法
和往常一样,这些问题的答案是你必须要求语言设计师.我看不出有什么不了解的原因.不过在我看来,这个功能是相当毫无意义的.正如你在问题中指出的那样,只有当moo被调用在静态类型IntFoo的变量上时,原语将被返回;对于类型为Foo< Integer>的变量,整数将被返回.所以你可以通过这样做实现基本相同的事情.
public class IntFoo implements Foo<Integer> { @Override public Integer moo() { return mooAsInt(); } public int mooAsInt() { return 0; } }
就个人而言,我认为这更好,因为当拳击不发生时,这更为明显.在你的提议中,moo()可以返回一个int或一个整数,这取决于变量的静态类型,这将是非常混乱的.