Java泛型超级关键字 [英] Java generics super keyword
问题描述
我浏览了这些主题
然而,我似乎还是对super
关键字有点迷茫:
However, I still seem to be kind of lost with super
keyword:
当我们像这样声明一个集合时:
When we declare a collection like that:
List<? super Number> list = null;
list.add(new Integer(0)); // this compiles
list.add(new Object()); // this doesn't compile
不应该是相反的 - 我们有一个包含一些对象(未知类型)的列表,这些对象是 Number
的父对象.所以 Object
应该适合(因为它是 Number
的父级),而 Integer
不应该.出于某种原因,情况正好相反.
shouldn't it be the opposite - we have a list that contains some objects (of unknown type) which are parents of Number
. So Object
should fit (since it is the parent of Number
), and Integer
shouldn't. The opposite is the case for some reason.
假设我们有以下代码
Provided we have the following code
static void test(List<? super Number> param) {
param.add(new Integer(2));
}
public static void main(String[] args) {
List<String> sList = new ArrayList<String>();
test(sList); // will never compile, however...
}
编译上述代码是不可能的(我的理智表明这是正确的行为),但基本逻辑可以证明相反:
It is impossible to compile the above code (and my sanity suggests that this is the right behaviour), but the basic logic could prove the opposite:
String 是 Object,Object 是 Number 的超类.所以 String 应该可以工作.
我知道这很疯狂,但这不是他们不允许
构造的原因吗?如果是,那为什么 <?super T>
是否允许?
I know this is crazy but isn't this the reason why they didn't allow <S super T>
constructs? If yes, then why <? super T>
is allowed?
有人可以帮我恢复这个逻辑链的缺失部分吗?
Could someone help me restore the missing part of this logic chain?
推荐答案
List
可以捕获 Number
及其任何超类型.由于Number extends Object 实现了Serializable
,这意味着只有List
是:
The bounded wildcard in List<? super Number>
can capture Number
and any of its supertypes. Since Number extends Object implements Serializable
, this means that the only types that are currently capture-convertible by List<? super Number>
are:
列表<数字>
列表<对象>
列表<可序列化>
请注意,您可以add(Integer.valueOf(0))
到上述任何类型.但是,您不能 add(new Object())
到 List
或 List
,因为这违反了泛型类型安全规则.
Note that you can add(Integer.valueOf(0))
to any of the above types. however, you CAN'T add(new Object())
to a List<Number>
or a List<Serializable>
, since that violates the generic type safety rule.
因此,您可以添加
任何Number
的超类型到List
;这根本不是有界通配符和捕获转换的工作方式.你没有声明一个 List
因为你可能想给它添加一个Object
(你不能!);你这样做是因为你想向它添加 Number
对象(即它是 Number
的消费者"),并且只是一个 List
太严格了.
Hence it is NOT true that you can add
any supertype of Number
to a List<? super Number>
; that's simply not how bounded wildcard and capture conversion work. You don't declare a List<? super Number>
because you may want to add an Object
to it (you can't!); you do because you want to add Number
objects to it (i.e. it's a "consumer" of Number
), and simply a List<Number>
is too restrictive.
- Angelika Langer 的泛型常见问题解答
- 什么是有界通配符?
- 我什么时候会使用具有下限的通配符参数化类型?(当一个具体的参数化类型过于严格时.")
- 为什么类型参数没有下限? ("因为它没有意义.")
- Angelika Langer's Generics FAQs
- What is a bounded wildcard?
- When would I use a wildcard parameterized type with a lower bound? ("When a concrete parameterized type would be too restrictive.")
- Why is there no lower bound for type parameters? ("Because it does not make sense.")
- Effective Java 2nd Edition,第 28 条:使用有界通配符提高 API 灵活性
- "PECS 代表生产者-
extends
,消费者-super
- Effective Java 2nd Edition, Item 28: Use bounded wildcards to increase API flexibility
- "PECS stands for producer-
extends
, consumer-super
- 太多无法列出,PECS、
new Integer(0)
vsvalueOf
等
- Too many to list, PECS,
new Integer(0)
vsvalueOf
, etc
这篇关于Java泛型超级关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- "PECS stands for producer-
- "PECS 代表生产者-