Java泛型超级关键字 [英] Java generics super keyword

查看:32
本文介绍了Java泛型超级关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我浏览了这些主题

然而,我似乎还是对super关键字有点迷茫:

However, I still seem to be kind of lost with super keyword:

  1. 当我们像这样声明一个集合时:

  1. 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.

  1. 假设我们有以下代码

  1. 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())ListList,因为这违反了泛型类型安全规则.

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) vs valueOf
          • Too many to list, PECS, new Integer(0) vs valueOf, etc

          这篇关于Java泛型超级关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆