【问题标题】:Passing List<Subclass> to method expecting List<SuperClass>将 List<Subclass> 传递给期望 List<SuperClass> 的方法
【发布时间】:2012-02-16 22:02:08
【问题描述】:

我有一个方法需要 List&lt;SuperClass&gt; 作为参数:

public void myMethod(List<SuperClass> list) {}

我想用List&lt;Subclass&gt; 来调用该方法,例如:

List<SubClass> subList = new ArrayList<>();
// ...
myMethod(subList); // Got an argument mismatch error on this line.

SubClass extends SuperClass时我不应该能够做到这一点吗?

【问题讨论】:

  • 你没有传递一个子类。您正在传递一个子类的 listlist 不是另一个列表的子类。

标签: java list generics compiler-errors subclass


【解决方案1】:

不,泛型不是那样工作的。您可以做的是将您的方法定义为MyMethod(List&lt;? extends SuperClass&gt; list)(按照惯例,它应该命名为myMethod(...) btw)。

List&lt;SuperClass&gt;List&lt;SubClass&gt; 的问题在于,您可以向此类列表添加新元素,而编译器不允许您向 List&lt;? extends SuperClass&gt; 添加内容 - 这是有原因的:

考虑以下几点:

class A {}

class B extends A {}

class C extends A {}

如果您现在有List&lt;A&gt;,您可以添加ABC 的实例。但是,如果您将List&lt;B&gt; 作为List&lt;? extends A&gt; 参数传递给方法,编译器不知道是否允许将AC 的实例添加到该列表(不允许,但如果你通过List&lt;A&gt; 它会是)。因此编译器会限制你不要这样做。

将参数定义为List&lt;A&gt; 告诉编译器可以将所有三个类的实例放入该列表。现在,如果允许您传递List&lt;B&gt; 作为这样的参数,您最终可能会得到一个包含A 和/或C 实例的List&lt;B&gt;。这显然不是您想要的,并且可能导致应该在编译时已经防止的运行时错误 - 通过使用泛型。这就是为什么你的方法不起作用的原因。

【讨论】:

  • 谢谢 - 我什至不知道要谷歌什么。顺便说一句,它是“扩展”
  • 如果可以的话,我会为这个答案投不止一个赞成票。这是一个很好的解释。谢谢。
  • 非常感谢 - 这是一个非常有用的解释。
【解决方案2】:

值得注意的是,您还可以从子类列表中创建超类列表:

myMethod(new ArrayList<SuperClass>(list));

【讨论】:

    猜你喜欢
    • 2011-03-15
    • 1970-01-01
    • 2021-05-10
    • 2014-08-14
    • 2011-07-02
    • 1970-01-01
    相关资源
    最近更新 更多