【问题标题】:Wildcards: Talking about "Object" vs "?" [duplicate]通配符:谈论“对象”与“?” [复制]
【发布时间】:2014-03-08 00:49:37
【问题描述】:

看这两个例子:

void printCollection(Collection<Object> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

这两者有什么区别?我读到第二个例子更强大。但这是为什么呢?哪个参数不能传给方法 1,哪个参数可以传给方法 2?

【问题讨论】:

    标签: java generics collections wildcard


    【解决方案1】:

    泛型aren't covariant。换句话说,Collection&lt;String&gt; 不是Collection&lt;Object&gt;,即使StringObject。例如,使用第一个签名,我将无法打印List&lt;String&gt;

    通用通配符有助于表达协变(如您的示例)和逆变。 Collection&lt;?&gt;Collection&lt;? extends Object&gt; 的缩写,意思是“一些特定的、未知类型的集合,它是或扩展Object”。因此,我们无法向这样的集合添加除 null 之外的任何内容,因为我们无法保证添加的对象的类型是有效的。

    这是一个使用通配符表示逆变的示例:

    void populateCollection(Collection<? super Integer> c) {
        for (int i = 0; i < 10; i++) {
            c.add(i);
        }
    }
    

    我可以将Collection&lt;Object&gt;Collection&lt;Number&gt;Collection&lt;Integer&gt; 传递给此方法,因为它被视为Integers 的消费者。在您的示例中,该集合是Objects 的生产者。有关通配符泛型类型的“生产者”和“消费者”之间的区别,请参阅这篇文章:What is PECS (Producer Extends Consumer Super)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-06
      • 2011-06-23
      • 1970-01-01
      • 2023-03-17
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      相关资源
      最近更新 更多