为什么不能将原始类型与多态返回类型一起使用? [英] Why is it not possible use primitive types with polymorphic return types?

查看:128
本文介绍了为什么不能将原始类型与多态返回类型一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下两个类:

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.但是,我们都知道可以使用自动装箱将它们隐式地相互转换.鲜为人知的是,在此示例中,编译器会生成一个桥方法:

This code will produce an error at publicintmoo, saying that int is incompatible with the overridden method's return type Integer. Strictly speaking, this is true, since int does not directly equal Integer. However, we all know that they can be implicitly converted to each other using auto(un)boxing. What is less know is the fact that the compiler generates a bridge method in this example:

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

    public Integer moo() {
        return 0;
    }
}

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

This has to be done because the JVM differentiates between return types when resolving methods, and since the erased return type of Foo.moo is Object, the compiler generated a bridge method with the same signature as the method.

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

I am wondering why this wouldn't work with primitive polymorphic return types as well:

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

    public int moo()
    {
        return 0;
    }
}

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

There doesn't seem to be any reason not to have this feature:

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会话的屏幕快照显示,我什至可以在我的自定义编程语言中实现(可编译为Java字节码):

In fact, this screenshot of a REPL session shows that I was even able to implement this in my custom programming language (which compiles down to Java bytecode):

推荐答案

与这些问题一样,答案是您必须询问语言设计师.我看不到无法完成此操作的任何原因.但是,我认为此功能将毫无意义.正如您在问题中指出的那样,只有在静态类型为IntFoo的变量上调用moo时,才会返回原语.在类型为Foo<Integer>的变量上,无论如何都将返回Integer.因此,您可以通过执行此操作来实现基本相同的事情.

As always with these questions, the answer is that you'd have to ask the language designers. I can't see any reason why this couldn't be done. However in my opinion this feature would be fairly pointless. As you point out in the question it's only when moo is invoked on a variable of static type IntFoo that a primitive would get returned; on a variable of type Foo<Integer>, an Integer would get returned anyway. So you can achieve essentially the same thing by doing this.

public class IntFoo implements Foo<Integer> {

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

    public int mooAsInt() { return 0; }
}

我个人认为这是更好的选择,因为装箱/不装箱会更加明显.在您的建议中,moo()可能会返回intInteger,具体取决于变量的静态类型,这将非常令人困惑.

Personally I think this is better because it's much more obvious when boxing does / does not take place. In your proposal, moo() could return an int or an Integer depending on the static type of the variable, which would be extremely confusing.

这篇关于为什么不能将原始类型与多态返回类型一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆