为什么不能使用具有多态返回类型的原始类型?

Cla*_*oft 10 java polymorphism primitive return-type

考虑以下两个类:

public interface Foo<T>
{
    public T moo();
}

public class IntFoo implements Foo<Integer>
{
    public int moo()
    {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码将产生错误,表示与重写方法的返回类型不兼容.严格来说,这是事实,因为并不直接相等.但是,我们都知道可以使用auto(un)boxing将它们隐式转换为彼此.更少知道的是编译器在此示例中生成桥接方法:publicintmoointIntegerintInteger

public class IntFoo implements Foo<Integer>
{
    public <synthetic> <bridge> Object moo()
    {
        return this.moo(); // upcast
    }

    public Integer moo() {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

必须这样做是因为JVM在解析方法时区分返回类型,并且由于擦除了返回类型Foo.moois Object,编译器生成了具有与方法相同签名的桥接方法.

我想知道为什么这对原始多态返回类型也不起作用:

public class IntFoo implements Foo<Integer>
{
    public <synthetic> <bridge> Object moo()
    {
        return Integer.valueOf(this.moo());
    }

    public int moo()
    {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎没有任何理由不具备此功能:

IntFoo intFoo = new IntFoo();
Foo<Integer> foo = intFoo;
Integer i = foo.moo(); // calls the synthetic method, which boxes the result of the actual implementation
Run Code Online (Sandbox Code Playgroud)

实际上,REPL会话的这个屏幕截图显示我甚至能够在我的自定义编程语言(它编译为Java字节码)中实现它:

REPL会话

Pau*_*ton 6

一如既往地提出这些问题,答案是您必须向语言设计师询问.我看不出为什么不能这样做的任何理由.但是在我看来这个功能毫无意义.正如你在问题中指出的那样,只有在moo静态类型的变量上调用IntFoo才会返回原语; 在一个类型的变量上Foo<Integer>,Integer无论如何都会返回.因此,通过这样做你可以实现基本相同的事情.

public class IntFoo implements Foo<Integer> {

    @Override
    public Integer moo() { return mooAsInt(); }

    public int mooAsInt() { return 0; }
}
Run Code Online (Sandbox Code Playgroud)

我个人认为这更好,因为当拳击没有发生时更明显.在你的提案中,moo()可以返回一个int或一个Integer取决于变量的静态类型,这将是非常混乱的.