【问题标题】:Passing Collection<SubClass> into a function expecting Collection<BaseClass> fails in Java [duplicate]将 Collection<SubClass> 传递给期望 Collection<BaseClass> 的函数在 Java 中失败 [重复]
【发布时间】:2012-08-28 10:00:57
【问题描述】:

可能重复:
Most efficient way to cast List<SubClass> to List<BaseClass>
why polymorphism doesn't treat generic collections and plain arrays the same way?

如果我有一个抽象基类 BaseClass 并且我编写了一个期望 Collection&lt;BaseClass&gt; 作为其参数的函数,则使用类 SubClass extends BaseClassCollection&lt;SubClass&gt; 调用该函数将无法编译。

在基类中:

public void addLots(Collection<BaseClass> collection) {
    for(BaseClass yourbase : collection) {
        us.add(yourbase) //what you say!!
    }
}

在子类中:

public void addMoreLots(Collection<SubClass> collection) {
    addLots(collection); //FAILS TO COMPILE
}

现在我想我明白这是为什么了:Collection&lt;SubClass&gt; 不是Collection&lt;BaseClass&gt; 的子类。进行此调用的正确方法是什么?

【问题讨论】:

  • 谢谢——虽然我找不到它,但我认为这解决了一个不同的问题(更多地关注“我该怎么做”,而不是关注“为什么数组不同于集合”) .这个推测适用于任何泛型,例如WeakReference

标签: java inheritance collections


【解决方案1】:

在紧要关头,Collections.unmodifiableCollection(Collection&lt;SubClass&gt;) 可以返回 Collection&lt;BaseClass&gt;。 (当然,它使集合不可修改,但这就是将Collection&lt;SubClass&gt; 视为Collection&lt;BaseClass&gt; 的安全原因。)

【讨论】:

    【解决方案2】:

    Collections仅在编译时检查not运行时,所以这样做是为了保护收集在错误类型的对象中。

    试试这个方法...

    public &lt;T extends BaseClass&gt; void addLots(Collection&lt;T&gt; collection){ }

    public void addLots(Collection&lt;? extends BaseClass&gt; collection) {}

    【讨论】:

    • 我已经解决并发布了我自己的答案,但谢谢你:)
    • @AndrewWyld,没有什么比自己找到答案更有趣和令人鼓舞的了……继续努力……但请看我提到了两种方法…… ..
    【解决方案3】:

    &lt;? extends BaseClass&gt; 应该替换 &lt;BaseClass&gt;addLots 的正确语法是:

    public void addLots(Collection<? extends BaseClass> collection) {
        for(BaseClass yourbase : collection) {
            us.add(yourbase) //what you say!!
        }
    }
    

    【讨论】:

      【解决方案4】:

      你可以使用

      public void addLots(Collection<? extends BaseClass> collection) {
      }
      

      而不是

      public void addLots(Collection<BaseClass> collection) {
      }
      

      表示扩展基类的类型的Collection可以是参数。

      【讨论】:

      • 我已经解决了,见下文,但谢谢:)
      【解决方案5】:
      public void addLots(Collection<? extends BaseClass> collection) {
      }
      

      但是你不能调用添加到集合(即你不能这样做collection.add()),
      但是在这个

      public void addLots(Collection<? super SubClass> collection) {
      }
      

      你可以调用 add(即你可以调用collection.add())。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-16
        • 2019-02-14
        • 2021-07-30
        • 2019-02-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-08
        • 1970-01-01
        相关资源
        最近更新 更多