【问题标题】:Where can we use ArrayList< ? extends My_Class>我们可以在哪里使用 ArrayList< ?扩展 My_Class>
【发布时间】:2012-07-26 12:28:06
【问题描述】:

我们在哪里可以ArrayList&lt;? extends My_Class&gt;,因为如果您以这种方式声明它,它将不允许您添加任何新元素:

ArrayList<? extends My_Class> obj=new ArrayList<? extends My_Class>();
list.add(new Derived_My_Class()); //this is compilation error

【问题讨论】:

标签: java generics


【解决方案1】:

描述这些关键字的广泛使用的首字母缩写词是:PECS:Producer extends - consumer super。

所以,如果你使用“扩展”你的集合产生给定类型的元素。所以你不能添加它,你只能从中获取。

一个示例用法是为您的 API 的客户端提供一个列表:

public List<? extends CharSequence> getFoo() {
    List<String> list = new ArrayList<String>();
    list.add("foo");
    return list;
}

相关:Java generics: Collections.max() signature and Comparator

【讨论】:

  • 我们试图从中得到什么好处我不明白,因为这个方法的调用者也应该定义一个 List 甚至 List 之后你也不能修改接收到的变量,这就是为什么我不明白我们为什么需要它
【解决方案2】:

你是对的,你的ArrayList 不能以它的派生方式使用:你不能把任何东西放进去。

您想要存储My_Class 及其子类的只是ArrayList&lt;My_Class&gt;;它将正确获取My_Class 及其所有DerivedClass 的对象。

【讨论】:

    【解决方案3】:

    嗯...没有必要像这样声明 ArrayList,而是通过编写来实现您的意图

    ArrayList obj=new ArrayList();

    根据我的经验,我在方法参数中看到了这个概念,您希望调用者提供特定超类型的子类型的集合(或者从方法返回,就像上面有人说的那样)。如下所示

    public getAnimals(List< ? extends Animal> obj){
    
    obj.add(something);    //not allowed
    
    }
    

    您很有可能可以在您的特定类型列表中添加驴、猴子和鸟类等(例如猴子)。并在获取时获取 classCastException。

    这就是为什么在这种情况下不允许。阅读 Josh Bloch 的《Effective Java》。他用生产者消费者类比(PECS)很好地解释了这一点

    【讨论】:

    • 啊……什么?是的,这正是我在某些情况下想要的。不解决问题
    • 假设驴、猴子和鸟都来自Animal,那么...将它们存储在ArrayList&lt;Animal&gt; 中会有什么问题??还有……潜在的灾难在哪里??
    • 我没想到自己会这么笨。对不起..参考更新的答案
    猜你喜欢
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2021-07-31
    相关资源
    最近更新 更多