【问题标题】:List<interfaceI> vs List<? extends InterfaceI> in java列表<interfaceI> 与列表<?在java中扩展InterfaceI>
【发布时间】:2014-10-11 06:31:43
【问题描述】:

具有List&lt;interfaceI&gt;List&lt;? extends InterfaceI&gt; 的Arraylist 都将具有实现接口I 的类的对象。那什么时候用呢?

【问题讨论】:

标签: java generics collections arraylist


【解决方案1】:

假设FooBar 是实现InterfaceI 的两个类。

第二个 (List&lt;? extends InterfaceI&gt;) 不允许向列表添加任何内容(null 除外),因为列表包含的类型未知:它可能是 List&lt;Foo&gt;List&lt;Bar&gt;:你只是不知道。

因此,当您希望该方法读取作为参数传递的列表的元素,并希望调用者能够使用List&lt;InterfaceI&gt;List&lt;Foo&gt;List&lt;Bar&gt;。使用List&lt;InterfaceI&gt; 作为参数只会接受List&lt;InterfaceI&gt; 类型的列表。

让我们举一个具体的例子:你想计算一个数字列表的最大双精度值。这种方法不需要向列表添加或设置任何内容。它所做的只是迭代元素,获取每个数字并计算它们的最大值。签名可以是

 public double max(List<Number> list);

但是,你将无法做到

List<Integer> ints = new ArrayList<>();
max(ints);

调用这个方法的唯一方法是做

List<Number> ints = new ArrayList<>();
max(ints);

如果你将方法声明为

public double max(List<? extends Number> list);

那你就可以了

List<Integer> ints = new ArrayList<>();
List<Long> longs = new ArrayList<>();
max(ints);
max(longs)

【讨论】:

  • 我可以将整数对象添加到 List ints = new ArrayList() 并调用 max(ints)。然后它会工作。
  • 是的,你可以作为整数扩展数字
【解决方案2】:

不同之处在于,如果您将列表声明为List&lt;? extends S&gt; myList,则myList 变量可以通过扩展S 的任何类型的列表,因此如下所示的关联将起作用:

public class Clazz implements S{}
List<? extends S> myList = new List<Clazz>(); // its fine as Clazz extends S
List<? extends S> myList = new List<S>(); // its fine as well
List<? extends S> myList = new List<Object>(); // ooooops it wil not work

但是在这种情况下,您将不会对 PUT 这样的列表进行任何操作,因为您无法保证分配给 myList 的列表实现所持有的对象的确切类型

如果您声明List&lt;S&gt; myList,那么您将能够从列表中获得PUTGET 对象,因为您确定其中有什么,但是上面的分配将不起作用!

public class Clazz implements S{}
List<S> myList = new List<Clazz>(); // no way! 
List<S> myList = new List<S>(); //thats perfectly fine! - You can PUT new S in it;
List<S> myList = new List<Object>(); //known result;

【讨论】:

    【解决方案3】:

    这里代替这个

    public double max(List<? extends Number> list){
    

    如果你喜欢-

    public List myList(List<? extends String> list){
    list.add("string");// No, can not add anything in list except null
    list.add(null);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-16
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多