0

我想弄清楚为什么我不能super在泛型方法声明中使用?请参阅下面的示例,它无法编译,但我不确定为什么。

public class A<E> {
    public <T extends A> void test1(T t) {   // Compiles fine
    }
    public <T super A> void test2(T t) {     // Compilation error??
    }
    public <T super A> <T> void test3(T t) { // Compilation error??
    }
}

class A {}
....
4

2 回答 2

2

类型参数和类型参数之间存在差异。通配符 ( superand extends) 用于类型参数,也就是说,当您实际定义类型参数的相应值时,您在调用站点声明它们。或者,关键字extends可用于类型参数约束。

类型参数与类型参数

因此,在定义class List<T>{}中,T称为类型参数。当您声明 type 的引用时List,您可以在调用站点为 提供类型参数T,该参数可以是不变量(即List<String> jedis)或带有 super 或扩展的通配符(即List<? extends Number> myNums, List<? super String> names)。

类型参数约束

该关键字extends还可以用于完全不同的目的来声明给定类型参数的约束。例如,声明:

class List<T extends CharSequence>{}

类型参数T是受约束的。这意味着每当您为类型参数声明类型参数T时,它必须是类型CharSequence或其任何子类型。

因此,这List<String>将是有效的声明,但List<Integer>不会。

super在类型参数约束的声明中不允许使用关键字,可能是因为它没有多大意义,在您的声明中,什么可能是有效的类型参数,因为它本身T不是A

于 2012-06-24T02:39:59.977 回答
2

想一想,如果一个方法可以有签名

public <T super A> void test2(T t) {
}

那么它可以将任何对象作为参数。为什么?因为,例如,您总是可以推断TObject(Object是 的超类型A),并且任何对象都是 的实例Object,所以它可以工作。所以以这种方式声明它是非常多余的。你可以写

public void test2(Object t) {
}

为了同样的效果。

于 2012-06-24T08:15:53.090 回答