Java泛型中“超级”和“扩展”之间的区别是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1910892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
what is the difference between 'super' and 'extends' in Java Generics
提问by benhsu
I am trying to learn Java generics. I am not clear when you will use <T extends Foo>
and when you will use <T super Foo>
. What do each one of these things mean about T? Lets say I have <T extends Comparable>
and <T super Comparable>
, what do each of these mean?
我正在尝试学习 Java 泛型。我不清楚你什么时候用<T extends Foo>
,什么时候用<T super Foo>
。这些事情中的每一项对 T 意味着什么?假设我有<T extends Comparable>
和<T super Comparable>
,这些是什么意思?
I've read several tutorials at sun.com but I'm still lost. Can somebody illustrate with examples?
我已经在 sun.com 上阅读了几个教程,但我仍然迷失了方向。有人可以举例说明吗?
Thanks!
谢谢!
采纳答案by whiskeysierra
See Effective Java 2nd Edition, Item 28:
参见 Effective Java 2nd Edition,Item 28:
PECS
职业教育学院
Producer extends, Consumer super
Producer ëxtends,Çonsumer小号UPER
If your parameter is a producer, it should be <? extends T>
, if it's a consumer it has to be <? super T>
.
如果您的参数是生产者,则应该是<? extends T>
,如果是消费者,则必须是<? super T>
。
Take a look at the Google Collections, they know how to use it, because they got Bloch ;)
看看 Google Collections,他们知道如何使用它,因为他们有 Bloch ;)
回答by R Samuel Klatchko
It depends which way on the inheritance hierarchy it allows. Assume you have a class "Child" which inherits from "Parent" which inherits from "Grandparent".
这取决于它允许的继承层次结构。假设您有一个从“祖父母”继承的“父”继承的“子”类。
<T extends Parent>
accepts either Parent or Child while <T super Parent>
accepts either Parent or Grandparent.
<T extends Parent>
接受父母或孩子,同时<T super Parent>
接受父母或祖父母。
回答by Ivo Bosticky
There are three types of wildcards:
通配符分为三种类型:
? extends Type
: Denotes a family of subtypes of typeType
. This is the most useful wildcard.? super Type
: Denotes a family of supertypes of typeType
.?
: Denotes the set of all types or any.
? extends Type
: 表示 type 的一系列子类型Type
。这是最有用的通配符。? super Type
: 表示 type 的超类型家族Type
。?
: 表示所有类型或任何类型的集合。
回答by Alexander Pogrebnyak
If you are asking about type parameters, then there is no <T super X>
construct in Java. Bounded parameter can only extend
, but it can extend more than one type. E.g
如果您问的是类型参数,则<T super X>
Java 中没有构造。有界参数只能extend
,但可以扩展不止一种类型。例如
public class MyClass< T extends Closeable & Runnable >
{
// Closeable and Runnable are chosen for demonstration purposes only
}
In this case if you see MyClass< ConcreteT >
then ConcreteT must be declared as
在这种情况下,如果您看到MyClass< ConcreteT >
ConcreteT 必须声明为
public class ConcreteT
implements Closeable, Runnable
{
...
}
For bounded wildcards, read this article. Read section on get-put principle. Basically, super
corresponds to write
semantics, and extends
corresponds to read
semantics.
对于有界通配符,请阅读这篇文章。阅读关于get-put 原则的部分。基本上super
对应write
语义,extends
对应read
语义。
回答by BSingh
Remember PECS - Producer Extends Consumer Support. Also, uncle Bob discusses it well in his craftsman series. Check out http://objectmentor.com/resources/articles/The_Craftsman_44__Brown_Bag_I.pdf
记住 PECS - 生产者扩展消费者支持。另外,鲍勃叔叔在他的工匠系列中也很好地讨论了这一点。查看http://objectmentor.com/resources/articles/The_Craftsman_44__Brown_Bag_I.pdf
回答by Stathis Alexopoulos
For me the best answer came from @BSingh, when i read the article of Uncle Bob. I resume here, the conclusion of article.
对我来说,最好的答案来自@BSingh,当我阅读鲍勃叔叔的文章时。我在这里恢复,文章的结论。
Use List< T superSuit> whenever you are going to writeinto the list.
每当您要写入列表时,请使用 List<T superSuit> 。
When you put an Object to the List, all you care about is that the object is of a type that is compatible with type held by the list. So you want the list to take the type of that object or any of the superclasses of that object.
当您将一个对象放入列表时,您所关心的只是该对象的类型是否与列表中的类型兼容。因此,您希望列表采用该对象的类型或该对象的任何超类。
Use List< T extendsSuit> whenever you are going to readfrom a list.
每当您要从列表中读取时,请使用 List< T extendsSuit> 。
On the other hand, when you read from a list, you want the type you are reading to be the type contained byt the list, or a derivative from that type.
另一方面,当您从列表中读取时,您希望正在读取的类型是列表中包含的类型,或者是该类型的派生类型。