有什么区别:
SomeClass<T extends OtherClass>
和
SomeClass<T super OtherClass>
答案 0 :(得分:4)
Sun说(来自Using and Programming Generics in J2SE 5.0)
通配符有三种类型:
- “?extends Type”:表示Type类型的子类型。这是最有用的通配符
- “?super Type”:表示Type
类型的超类型系列- “?”:表示所有类型或任何
的集合 醇>
More Fun with Wildcards为这三种类型提供了一些很好的例子。
另一个很好的例子(取自@Adrian推荐的视频)是:
class Stack<E> {
void pushAll( Collection<? extends E> src );
void popAll( Collection<? super E> dest );
}
您可以在此处看到super
和extends
:
对于方法pushAll
,假设您有一个Stack<Number>
。您希望将src
的所有元素推送到Stack
。但src
应该是Collection<Integer>
。这就是您在此处选择? extends E
的原因。
对于方法popAll
,假设您有一个Stack<Integer>
。您想要将Stack
的所有元素都弹出到dest
。但dest
应该是Collection<Number>
。这就是您在此处选择? super E
的原因。
答案 1 :(得分:1)
区别在于问题的答案“哪种类型是SomeClass
的子类型?”。这显然是Java中一个有趣的问题,因为该语言的大部分功能来自于替换子类型的能力。现在,用
SomeClass<T extends OtherClass>
子类型都是SomeClass<S>
,其中S是T的子类型。例如,
SomeClass<T extends List>
包括SomeClass&lt; LinkedList&gt;和SomeClass&lt; ArrayList&gt;。但是
SomeClass<T super OtherClass>
子类型都是SomeClass<S>
,其中S是T的超类型。例如,
SomeClass<T super LinkedList>
包括SomeClass<List>
和SomeClass<Collection>
。
答案 2 :(得分:1)
tangens的回答是正确的,这只是(可能)有用的信息伴随着这个答案。
如何在Josh Bloch的Effective Java 2nd Edition中使用两个不同的通配符,这是一个很好的解释。它也在this视频中进行了描述。
他使用的助记符是PECS - Producer Extends,Consumer Super。这在视频和书中有解释。这是对谈话中使用的一张幻灯片的解释:
PECS - 制作人extends
消费者super
T
制片人使用Foo<? extends T>
T
消费者使用Foo<? super T>
这仅适用于输入参数,不要使用通配符类型作为返回类型。
答案 3 :(得分:0)
在第一种情况下,OtherClass和任何子类适用于类型参数。这对于要将元素限制为Figure
(包括Rectangle
和Circle
)但不限制任何其他非数字对象的集合非常有用。因此,我们将集合限制为Group<? extends Figure>
。
在后一种情况下,OtherClass和任何超类适用于类型参数。如果您需要将Comparator
传递给一组数字,这非常有用:此比较器应该只假设元素是数字或更一般。期望每个对象为Object
或Figure
的比较器将起作用,但假设所有元素都为Rectangle
的比较器在遇到例如Circle
时将失败。因此,我们将比较器限制为Comparator<? super Figure>
。