有人可以解释一下<?super T> mean和何时应该使用以及这种结构应该如何配合<T>和<?延伸T>?

Rom*_*man 18 c# java generics generic-programming

我使用泛型相当长的时间,但我从来没有使用像List<? super T>.

这是什么意思?如何使用它?擦除后如何看待?

我也想知道:它是泛型编程(模板编程?)中的标准还是它只是一个java'发明'?例如,c#是否允许类似的结构?

Pét*_*rök 10

当您想要将集合中的项目用于另一个集合时,将使用此构造.例如,您有一个泛型,Stack并且您想要添加一个popAll将Collection作为参数的方法,并将堆栈中的所有项目弹出到其中.根据常识,此代码应该是合法的:

Stack<Number> numberStack = new Stack<Number>();
Collection<Object> objects = ... ;
numberStack.popAll(objects);
Run Code Online (Sandbox Code Playgroud)

但只有你这样定义它才会编译popAll:

// Wildcard type for parameter that serves as an E consumer
public void popAll(Collection<? super E> dst) {
    while (!isEmpty())
    dst.add(pop());
}
Run Code Online (Sandbox Code Playgroud)

硬币的另一面pushAll应该是这样定义的:

// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
    for (E e : src)
    push(e);
}
Run Code Online (Sandbox Code Playgroud)

更新: Josh Bloch传播此助记符以帮助您记住要使用的通配符类型:

PECS代表生产者延伸,消费者超级.

有关更多详细信息,请参阅Effective Java 2nd Ed.,Item 28.