为什么泛型边界不能超载?

时间:2014-06-01 23:20:37

标签: java generics

我有点难以理解"新型"变量不允许在泛型中进行编译,特别是在使用已经有界变量重载方法的方面:

public class Schema {

    private interface Stringable {
        public String s();
    }

    public static <T extends Enum<T> & Stringable> String getName(T inst) {
        return Schema.getName(inst.getClass()); // error
    }

    public static <T extends Enum<T> & Stringable> String getName(Class<T> clazz) {
        return clazz.getName().toLowerCase();
    }

}

通奸错误:

Schema.java:[46,21] error: no suitable method found for getName(Class<CAP#1>)

我的主要问题是,为什么第二次在相同的通用边界下适用彼此适当界限的东西?

1 个答案:

答案 0 :(得分:3)

当我将代码复制/粘贴到Eclipse中时,我得到了一个不同的错误:

  

getName(T)类型中的方法Schema不适用于参数(Class<capture#1-of ? extends Enum>

经过进一步调查后,这似乎不是一个超载问题。实际上,这有点违反直觉,因为inst.getClass()实际上不是 getName(Class<T extends Enum<T> & Stringable> clazz)的正确类型。

这似乎是由于您不能在泛型类中具有泛型类型的多个边界。换句话说,您期望inst.getClass()返回的类型:

Class<? extends Enum<T> & Stringable>

不是实际返回的内容。

为什么?

因为您无法参数化具有多个边界的对象。

根据this问题,它似乎是Java的限制;其中一部分原因是Java不支持正确的语法使其成为可能。那么inst.getClass()实际返回的是:

Class<? extends Enum<T>>

肯定不符合你定义的getName(Class<T extends Enum<T> & Stringable> clazz)的界限。

不幸的是,一个快速谷歌搜索没有给出真正的这个好理由,所以我不能完全按照我的意愿回答你的问题。但我希望这至少可以解释你的代码发生了什么。