通配符声明的非显式泛型类型的通用返回类型

时间:2017-04-08 17:10:59

标签: java generics wildcard

想象一下这段代码:

public static <T> T[] superClassArray(Class<? extends T[]> subClass) {
    T[] superArray = (T[]) Array.newInstance(subClass.getComponentType().getSuperclass(), 0);
    return superArray;
}

此方法的返回类型T[]将是作为参数subClass提供的任何类型,甚至认为subClass无法实际代表T[]但只是一个子类? extends T)。因此,实际的返回类型应为Object,因为T[]未明确声明为 subclass的任何超类。 然而,

Integer[] objA = superClassArray(Integer[].class);

编译因为错误地期望返回Integer[]对象,但显然会抛出ClassCastException因为实际返回了Number[]个对象。

那么,只有通过相当模糊的通配符声明的泛型类型处理不当,或者我在我考虑的任何时候都错了,是否存在理由?

2 个答案:

答案 0 :(得分:1)

据我了解,你在尝试做的事情上并不十分一致。 使用您的方法,您将创建一个类的SUPERTYPE数组,实际上已成功完成。

但是你试图将它分配给对SUBTYPE的引用是非法的。如果您确实知道此数组不能包含除Integer之外的任何其他类型的值,则可以显式转换它:

Integer[] objA = (Integer[]) superClassArray(Integer[].class);

但是我在这样的代码中看不到任何价值,如果你有一个你正试图用这样的东西解决的任务,你真的可以考虑更多时间,并提出一个更好的解决方案。 :)

答案 1 :(得分:0)

你不应该做任何手动施法。泛型必须在编译期间处理它。如果您遇到编译时错误,最好修复此问题,而不是在下面的代码片段中进行不安全的转换。

T[] superArray = (T[])Array.newInstance(subClass.getComponentType().getSuperclass(), 0);