此行不会编译:
test(E1.class,E2.class);
只有一种类型参数E
和Java必须准确推断的参数类型相匹配。它不能推断出Example
,因为对象是Class<E1>
和Class<E2>
,而不是Class<Example>
。 Java泛型的不变性防止了这种情况的发生。
您可以解决此通过引入上test
的泛型类型参数的上限通配符:
public static <E extends Example> void test(Class<? extends E>... es)
这使得Java推断Example
为E
,通过满足与E1
和E2
上限通配符。
第二行创建一个Class
es的原始数组,绕过泛型并生成“未经检查的调用”警告。
new Class[]{E1.class,E2.class}
如果你试图提供一个类型参数Class
在这里,你会得到一个编译器错误与任何中途合理的类型参数:
// Needs Class<Example> but found Class<E1> and Class<E2>
test(new Class<Example>[]{E1.class,E2.class});
// Needs Class<E1> but found Class<E2>
test(new Class<E1>[]{E1.class,E2.class});
// Needs Class<E2> but found Class<E1>
test(new Class<E2>[]{E1.class,E2.class});
通过使用通配符通过满足推理这里只是揭示了真正的问题 - 通用数组的创建。
// Generic array creation
test(new Class<? extends Example>[]{E1.class,E2.class});
非常感谢。这对我的计划永远不会造成伤害,但我一直在为此挠头。我非常感谢澄清。 – Squirvin 2014-10-03 01:47:53