java - 为什么 java.lang.Class 的 getInterfaces() 方法返回 Class<?>[] 而不是 Class<? super T>[]?

标签 java generics interface bounded-wildcard

(为了澄清问题,'T'指的是类中声明的类型参数)

举个例子,请查看以下应用程序:

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 确实满足通配符的边界,所有其他接口(interface)也是如此。

凭直觉,我希望以下内容是安全的,但事实并非如此:

Class<? super ClassA>[] interfaces = ClassA.class.getInterfaces();

编译器给出警告,因为签名说它返回类;但是,Class 的 javadoc 声明如下:

If this object represents a class, the return value is an array containing objects representing all interfaces implemented by the class.

“这个对象”在我们的例子中指的是 ClassA .基于这个声明,如果我们调用:

ClassA.class.getInterfaces()

然后我们从逻辑上知道,每个Class<?>在返回的数组中将包含对父类(super class)型 ClassA 的引用.

作为额外的引用点:

来自 Java 语言引用,第三版:

A class necessarily implements all the interfaces that its direct superclasses and direct superinterfaces do. This (multiple) interface inheritance allows objects to support (multiple) common behaviors without sharing any implementation.

阅读规范的这一部分和其他部分,我会认为任何类或接口(interface)由类 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 X>反正不是很有用。 Class<?>对于大多数用途来说已经足够了。

如果我们有一个声明G<T> , 对于 G<? super X>有用,通常G应该有接受 T 的方法.例如,List<T>add(T) .所以List<? super X>有用,我们可以调用add(x)在它上面( x 属于 X 类型)

Class没有这样的方法。

您是否有一个您真正需要的令人信服的用例 Class<? super ClassA>

关于java - 为什么 java.lang.Class 的 getInterfaces() 方法返回 Class<?>[] 而不是 Class<? super T>[]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8190127/

相关文章:

java - 如何用 Java 制作多组件 Swing 类

c# - 如何更好地组合从一个接口(interface)继承的不同类型的通用列表?

c# - 为什么不能从泛型约束中隐式推断出 `this` 的类型转换?

java - 在 Android 中创建界面

java - 将从 C 接收到的字符串转换为 Java 字符串

java - 如何使面向对象的java项目完全通用

java - 如何向多个类继承的方法添加参数

methods - 无效操作 : s[k] (index of type *S)

java - Java中的文件声明

java - 如何将对象实例的类型与泛型进行比较?