【问题标题】:ArrayList of objects and abstract对象和抽象的 ArrayList
【发布时间】:2015-08-16 05:34:43
【问题描述】:

我正在尝试学习 Java 中的通配符。在这里,我试图修改printCollection 方法,使其只采用扩展AbstractList 的类。它在评论中显示错误。我尝试使用 ArrayList 的对象,它工作正常。我正在使用 Java 7。

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class Subtype {
    void printCollection(Collection<? extends AbstractList<?>> c) {
        for (Object e : c) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        Subtype st= new Subtype();
        ArrayList<String> al = new ArrayList<String>();
        al.add("a");
        al.add("n");
        al.add("c");
        al.add("f");
        al.add("y");
        al.add("w");
        //The method printCollection(Collection<? extends AbstractList<?>>) in the type Subtype is not applicable for the 
        // arguments (ArrayList<String>)
        st.printCollection(al);
    }

}

【问题讨论】:

  • 您是否只允许扩展 AbstractList 而不是所有实现 List 接口(合同)的列表的特定原因?通过指定AbstractList,您将代码耦合到特定实现。只要有可能,您应该编写接口而不是实现。
  • @MickMnemonic 谢谢我会记住这一点。

标签: java arraylist wildcard subtyping


【解决方案1】:

您正在请求一个抽象列表对象的集合,例如一个列表,其中填充了抽象列表。这真的是你想要的吗?

解决它的一种方法是......

<T extends AbstractList<?>> void printCollection(T c) {

...这样,您的方法将只接受扩展 AbstractLists 的具有任何通用内容的对象。

但正如其他评论者、海报和作家(J. Bloch:Effective Jave,p134+)已经正确指出的那样,更好的风格是简单地尝试这样的事情:

void printCollection(AbstractList<?> c) {

【讨论】:

  • 谢谢你是对的,但我不明白这是怎么回事
  • 我很抱歉,但我无法真正重申需要一本好书页才能在这里解释的内容。我建议参考一些 Java 泛型教程或书籍。
  • 我使用这个链接阅读了通配符docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
  • 好主意,但对于初学者来说,可能有比 oracle 文档更基本的解释,如果你问我,这往往是好的,但对新手并不友好。
  • @FlorianSchaetz:我要添加到您的答案中的唯一一件事是正式类型参数T 在方法签名中只出现一次。在这种情况下,通过使用有界通配符来提供更灵活的 API(Effective Java, 2nd Ed. J. Block)。
【解决方案2】:

在您的代码中,您假设参数应该实现Collection 并且应该包含 扩展AbstractList 的元素

void printCollection(Collection<? extends AbstractList<?>> c)

要得到你想要的,你可以简单地这样写:

void printCollection(AbstractList<?> c)

【讨论】:

  • 我认为这是一个更好的答案。在可能的情况下,在方法签名中使用有界通配符可以产生更灵活的 API。
猜你喜欢
  • 2018-11-06
  • 2017-11-04
  • 2020-07-03
  • 1970-01-01
  • 2014-09-13
  • 2016-06-28
  • 1970-01-01
  • 2019-09-09
  • 2016-07-23
相关资源
最近更新 更多