sag*_*ger 12 java generics interface bounded-wildcard
(要清除问题,'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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出是人们所期望的:
TestClass$InterfaceA
TestClass$InterfaceB
TestClass$InterfaceC
Run Code Online (Sandbox Code Playgroud)
因此,基于上面的这个例子,我们可以看到编译器认识到InterfaceA 确实符合通配符的边界,所有其他接口也是如此.
直观地说,我希望以下是安全的,但它不是:
Class<? super ClassA>[] interfaces = ClassA.class.getInterfaces();
Run Code Online (Sandbox Code Playgroud)
编译器发出警告,因为签名表示它返回Class; 但是,Class的javadoc声明如下:
如果此对象表示类,则返回值是一个数组,其中包含表示该类实现的所有接口的对象.
'这个对象'在我们的例子中指的是ClassA.基于此声明,如果我们致电:
ClassA.class.getInterfaces()
Run Code Online (Sandbox Code Playgroud)
然后我们从逻辑上知道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 }
Run Code Online (Sandbox Code Playgroud)
问题出在第15行.您必须转换<? super W>为获取正确的类型.编译器警告可以被抑制,但它是否合理?是否有某种情况下这种演员不是真的?
你是对的,返回类型可能更具体.
但是,Class<? super X>无论如何都不是很有用.Class<?>足以满足大多数用途.
如果我们有一个声明G<T>,为了G<? super X>有用,通常G应该有接受的方法T.例如,List<T>有add(T).所以List<? super X>很有用,我们可以调用add(x)它(x属于类型X)
Class 没有这样的方法.
你有一个令人信服的用例,你真的需要Class<? super ClassA>吗?