我有一个Class对象列表,所有这些对象都需要扩展一个泛型类。这是我的代码:
private final List<Class<? extends A<?>>> CLASS_LIST =
Arrays.asList(B.class, C.class, D.class);
// Base class
private abstract class A<T extends Object> {}
// Some class that extends A
private class B extends A<String> {}
// Some other class that extends A
private class C extends A<String> {}
// A class that extends A, but with a different type than the first two
private class D extends A<OtherClass> {}
private static class OtherClass {}
这样可以正常工作,但是如果从列表中删除D.class,我会收到错误消息:
Incompatible types, Required A<?>, found A<String>
为什么会这样?我假设Java推断出类型......但为什么呢?它有办法吗?我发现如果我使用List<?>
它在所有情况下都有效,但后来我失去了类型安全性。
修改 此外,如果我有这个方法:
private void Check(){
A a = new B();
if(CLASS_LIST.contains(a.getClass())){
// Do something
}
}
它向我发出了List.contains(...)
可疑电话的警告。但是,如果我使用List<?>
,警告会消失......为什么会这样?
EDIT2: Java 1.8.0_51-b16编译,但Java 1.7.0_79给出了错误。
答案 0 :(得分:2)
你写的时候是对的
Arrays.asList(B.class, C.class)
编译器(1.7,1.8在类型推断方面稍微好一点)从其参数中推断出Class<? extends A<String>>
的类型,这与赋值不兼容。您可以通过指定所需的类型来解决此问题:
Arrays.<Class<? extends A<?>>>asList(B.class, C.class)
答案 1 :(得分:-1)
我建议你看看JDK源代码。
方法Arrays.asList返回一个ArrayList是Arrays的内部类,而不是java.util.ArrayList。
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
....
}
并且Arrays的内部类ArrayList不会覆盖remove
方法,因此会引发异常。