为什么java.lang.Class的getInterfaces()方法返回Class<?>[]而不是Class<?超级T>[]?非数组示例
(为了澄清这个问题,“T”指的是在Class中声明的类型参数)
例如,请查看以下应用程序:
public class TestClass {
interface InterfaceA{}
interface InterfaceB{}
interface InterfaceC{}
class ClassA implements InterfaceA, InterfaceB, InterfaceC{}
public static void main(String[] args){
Class<? super ClassA> superClass1 = ClassA.class;
Class<? super ClassA> superclass2 = InterfaceA.class;
Class<? super ClassA> superclass3 = InterfaceB.class;
Class<? super ClassA> superclass4 = InterfaceC.class;
for(Class<?> clazz : ClassA.class.getInterfaces()){
System.out.println(clazz.getName());
}
}
}
输出是人们所期望的:
TestClass$InterfaceA
TestClass$InterfaceB
TestClass$InterfaceC
因此,基于上面的这个例子,我们可以看到编译器识别出InterfaceA确实满足通配符的边界,就像所有其他接口一样。
直观地说,我希望以下内容是安全的,但事实并非如此:
Class<? super ClassA>[] interfaces = ClassA.class.getInterfaces();
编译器发出警告,因为签名说它返回 Class;但是,类的 javadoc 声明如下:
如果此对象表示一个类,则返回值是一个数组,其中包含表示该类实现的所有接口的对象。
“此对象”在本例中指 。基于此语句,如果我们调用:ClassA
ClassA.class.getInterfaces()
然后我们知道,从逻辑上讲,返回的数组中的每个数组都将包含对超类型的的引用。Class<?>
ClassA
作为额外的参考点:
摘自 Java 语言参考,第三版:
类必须实现其直接超类和直接超接口执行的所有接口。这种(多个)接口继承允许对象支持(多个)常见行为,而无需共享任何实现。
阅读规范的这一部分和其他部分,我认为任何由类实现或扩展的类或接口都将落入界限 。T
<? super T>
编辑:
有人认为,我的问题没有具体理由。我将提供一个例子:
1 import java.util.Map;
2 import java.util.HashMap;
3
4 public class MapWrapper<T> {
5 private final Map<Class<?>, OtherClass<T,?>> map = new HashMap <Class<?>, OtherClass<T,?>>();
6
7 public <W> void addToMap(Class<W> type, OtherClass<T,? super W> otherClass){
8 map.put(type, otherClass);
9 }
10
11 public <W> OtherClass<T,? super W> getOtherClassForAnyInterface(Class<W> type){
12 if(type.getInterfaces()!=null){
13 for(Class<?> interfaceType : type.getInterfaces()){
14 // Here, a cast is necessary. It throws a compiler warning for unchecked operations (rightfully so)
15 OtherClass<T,? super W> otherClass = (OtherClass<T,? super W>)getOtherClassForInterface(interfaceType);
16 if(null!=otherClass){
17 return otherClass;
18 }
19 }
20 }
21 return null;
22 }
23
24
25 public class OtherClass<T,V> {}
26
27 }
问题出在第 15 行。您必须强制转换为 才能获得正确的类型。编译器警告可以被禁止显示,但它是否合理?有没有一些场景,这种投射是不正确的?<? super W>