Java 泛型(通配符)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/252055/
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
Java Generics (Wildcards)
提问by Pablo Fernandez
I have a couple of questions about generic wildcards in Java:
我有几个关于 Java 中的通用通配符的问题:
What is the difference between
List<? extends T>
andList<? super T>
?What is a bounded wildcard and what is an unbounded wildcard?
List<? extends T>
和 和有List<? super T>
什么区别?什么是有界通配符,什么是无界通配符?
采纳答案by Bill the Lizard
In your first question, <? extends T>
and <? super T>
are examples of bounded wildcards. An unbounded wildcard looks like <?>
, and basically means <? extends Object>
. It loosely means the generic can be any type. A bounded wildcard (<? extends T>
or <? super T>
) places a restriction on the type by saying that it either has to extenda specific type (<? extends T>
is known as an upper bound), or has to be an ancestor of a specific type (<? super T>
is known as a lower bound).
在您的第一个问题中,<? extends T>
和<? super T>
是有界通配符的示例。无界通配符看起来像<?>
,基本上意味着<? extends Object>
。它松散地意味着泛型可以是任何类型。有界通配符 ( <? extends T>
or <? super T>
) 对类型施加限制,表示它要么必须扩展特定类型(<? extends T>
称为上限),要么必须是特定类型的祖先(<? super T>
称为下限) .
The Java Tutorials have some pretty good explanations of generics in the articles Wildcardsand More Fun with Wildcards.
回答by oxbow_lakes
If you have a class hierarchy A, B is a subclass of A, and C and D both are subclass of B like below
如果您有一个类层次结构 A,B 是 A 的子类,而 C 和 D 都是 B 的子类,如下所示
class A {}
class B extends A {}
class C extends B {}
class D extends B {}
Then
然后
List<? extends A> la;
la = new ArrayList<B>();
la = new ArrayList<C>();
la = new ArrayList<D>();
List<? super B> lb;
lb = new ArrayList<A>(); //fine
lb = new ArrayList<C>(); //will not compile
public void someMethod(List<? extends B> lb) {
B b = lb.get(0); // is fine
lb.add(new C()); //will not compile as we do not know the type of the list, only that it is bounded above by B
}
public void otherMethod(List<? super B> lb) {
B b = lb.get(0); // will not compile as we do not know whether the list is of type B, it may be a List<A> and only contain instances of A
lb.add(new B()); // is fine, as we know that it will be a super type of A
}
A bounded wildcard is like ? extends B
where B is some type. That is, the type is unknown but a "bound" can be placed on it. In this case, it is bounded by some class, which is a subclass of B.
有界通配符就像? extends B
B 是某种类型。也就是说,类型是未知的,但可以在其上放置“绑定”。在这种情况下,它受某个类的限制,该类是 B 的子类。
回答by blank
Josh Bloch also has a good explanation of when to use super
and extends
in this google io video talkwhere he mentions the Producer extends
Consumer super
mnemonic.
Josh Bloch 也很好地解释了何时使用super
,extends
在这个google io 视频演讲中,他提到了生产者extends
消费者super
助记符。
From the presentation slides:
从演示幻灯片:
Suppose you want to add bulk methods to
Stack<E>
void pushAll(Collection<? extends E> src);
– src is an E producer
void popAll(Collection<? super E> dst);
– dst is an E consumer
假设你想添加批量方法到
Stack<E>
void pushAll(Collection<? extends E> src);
– src 是 E 生产者
void popAll(Collection<? super E> dst);
– dst 是 E 消费者
回答by Sandeep Kumar
There may be times when you'll want to restrict the kinds of types that are allowed to be passed to a type parameter. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
有时您可能希望限制允许传递给类型参数的类型的种类。例如,对数字进行操作的方法可能只想接受 Number 或其子类的实例。这就是有界类型参数的用途。
Collection<? extends MyObject>
means that it can accept all object who have IS- Arelationship with MyObject (i.e. any object which is a type of myObject or we can say any object of any subclass of MyObject) or a object of MyObject class.
意味着它可以接受所有与 MyObject有IS-A关系的对象(即任何属于 myObject 类型的对象,或者我们可以说 MyObject 的任何子类的任何对象)或 MyObject 类的对象。
For example:
例如:
class MyObject {}
class YourObject extends MyObject{}
class OurObject extends MyObject{}
Then,
然后,
Collection<? extends MyObject> myObject;
will accept only MyObject or children of MyObject(i.e. any object of type OurObject or YourObject or MyObject, but not any object of superclass of MyObject).
将只接受 MyObject 或 MyObject 的子对象(即类型为 OurObject 或 YourObject 或 MyObject 的任何对象,但不接受 MyObject 超类的任何对象)。
回答by Prateek Joshi
In general,
一般来说,
If a structure contains elements with a type of the form
? extends E
, we can get elements out of the structure, but we cannot put elements into the structure
如果一个结构包含具有 form 类型的元素
? extends E
,我们可以从结构中取出元素,但不能将元素放入结构中
List<Integer> ints = new ArrayList<Integer>();
ints.add(1);
ints.add(2);
List<? extends Number> nums = ints;
nums.add(3.14); // compile-time error
assert ints.toString().equals("[1, 2, 3.14]");
To put elements into the structure we need another kind of wildcard called Wildcards with super
,
要将元素放入结构中,我们需要另一种称为 的通配符Wildcards with super
,
List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
Collections.copy(objs, ints);
assert objs.toString().equals("[5, 6, four]");
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
回答by taoxiaopang
Generic wildcards are created to make methods that operate on Collection more reusable.
创建通用通配符是为了使对 Collection 进行操作的方法更具可重用性。
For example, if a method has a parameter List<A>
, we can only give List<A>
to this method. It is a waste for this method's funtion under some circumstances:
例如,如果一个方法有一个参数List<A>
,我们只能给List<A>
这个方法。在某些情况下,这种方法的功能是一种浪费:
- If this method only reads objects from
List<A>
, then we should be allowed to giveList<A-sub>
to this method. (Because A-sub IS a A) - If this method only inserts objects to
List<A>
, then we should be allowed to giveList<A-super>
to this method. (Because A IS a A-super)
- 如果这个方法只从 读取对象
List<A>
,那么我们应该被允许给List<A-sub>
这个方法。(因为 A-sub 是 A) - 如果这个方法只向 插入对象
List<A>
,那么我们应该允许给List<A-super>
这个方法。(因为A是A超)