【问题标题】:Compile-time error using List.addAll to add a List<? extends BaseClass> to another one使用 List.addAll 添加 List<?扩展 BaseClass> 到另一个
【发布时间】:2016-07-01 20:34:26
【问题描述】:

在这段代码中,最后一行 (list1.addAll(list2);) 生成编译时错误

List) extends BaseClass> 不适用于参数 (List)

我确实意识到,如果允许这样做,则可以将不同类的相同列表实例添加到相同的列表中。但是我不知道这样做的正确方法是什么。

我的getList() 方法需要返回BaseClass 的子类,我无法更改该要求。

我有这两个列表,以相同的方式声明并包含相同类型的对象,我需要将一个添加到另一个列表中。 对此有任何想法将不胜感激。

BaseClass.java

package main;

public class BaseClass {}

Main.java

package main;

import java.util.ArrayList;
import java.util.List;

public class Main {

    private static List<? extends BaseClass> getList() {

        return new ArrayList<>();
    }

    public static void main(String[] args) {

        List<? extends BaseClass> list1 = getList();

        List<? extends BaseClass> list2 = getList();

        list1.addAll(list2); // Compile-time error: "The method addAll(Collection<? extends capture#3-of ? extends BaseClass>) in the type List<capture#3-of ? extends BaseClass> is not applicable for the arguments (List<capture#4-of ? extends BaseClass>)".
    }

}

【问题讨论】:

    标签: java generics


    【解决方案1】:

    您可以创建一个新的 List&lt;BaseClass&gt; 并将两个列表添加到其中:

    List<BaseClass> merged = new ArrayList<>();
    merged.addAll(list1);
    merged.addAll(lise2);
    

    但让getList 返回List&lt;BaseClass&gt; 可能是一个更好的主意。

    【讨论】:

      【解决方案2】:

      编译器无法确定这些类是否兼容。

      在示例中 list1 可以是类型

      List<SubSubSubClass>
      

      并且您尝试将 BaseClass 合并到其中。您不能将 BaseClass 转换为随机子类。 另外:

      List<? extends BaseClass> list1
      

      将声明一个基于 BaseClass 的对象列表,但以下内容也会这样做:

      List<BaseClass> list1
      

      试试这个:

       private static List<BaseClass> getList() {
      
          return new ArrayList<BaseClass>();
      }
      public static void main(String[] args) {
      
          List<BaseClass> list1 = getList();
      
          List<BaseClass> list2 = getList();
      
          list1.addAll(list2);
      }
      

      这将保证您的列表项都是 BaseClass 类型或该类型的子类。

      【讨论】:

      • 好点List&lt;BaseClass&gt; list1 将声明一个基于BaseClass 的对象列表,就像我的List&lt;? extends BaseClass&gt; list1 一样。但是我无法更改getList() 的返回类型,因为在其他地方我需要覆盖它并让它返回BaseClass 的不同子类的列表。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-26
      • 1970-01-01
      • 2014-04-14
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      相关资源
      最近更新 更多