为了澄清问题,“T”是在Class中声明的类型参数。
举个例子,请查看以下应用程序:
输出结果如预期所示:
编译器会发出警告,因为函数签名表明它返回一个Class对象;然而,Class类的Javadoc说明如下:
如果此对象表示一个类,则返回值是一个数组,其中包含表示类实现的所有接口的对象。
这里的“此对象”指的是ClassA。根据这个语句,如果我们调用:
那么我们可以逻辑地推断出,返回的数组中的每个
问题出在第15行。你需要将类型转换为
举个例子,请查看以下应用程序:
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对象;然而,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>
才能得到正确的类型。编译器警告可以被忽略,但这样做是否合理呢?是否存在某些情况下这种类型转换是不正确的呢?
Class<? super T>
。鉴于这一点,对我而言,getInterfaces()返回类似的类型似乎更为合适。如果他们像您所建议的那样考虑,即Class永远不会使用通过允许有界通配符可访问的那些方法,为什么Class会提供一个被指定为<? super T>
的超类呢? - sager