【问题标题】:Java: Generics on data structures and wildcardsJava:数据结构和通配符的泛型
【发布时间】:2015-11-16 19:03:11
【问题描述】:

我正在尝试学习如何使用泛型,为此,我正在创建自己的数据结构,类似于带有迭代器的列表。

最上面的类声明为:

public class BasicList<A> implements Iterable {
}

它只是一个带有节点的列表和一个指向下一个元素的指针。

还有另一个列表,称为 DescendingList,它的作用几乎相同,只是这一次,由于迭代器不同,您将获得另一个输出。我给这个 List 一个比较器来让 Iterator 工作。比较器只是一个接口:

public interface Bigger<A> {
    boolean bigger(A x);
}

DescendingList 看起来像这样:

public class DescendingList<A extends Bigger<A>> extends BasicList<A> implements Iterable {
}

这个想法是,它可以与通过 Bigger 接口进行比较的任何类型的对象一起使用。

现在我有了一个抽象类:

public abstract class Rock implements Bigger<Rock> {
}

最后,一个扩展 Rock 类的普通类:

public class Mineral extends Rock {
}

所以,手头的问题是,虽然我可以像这样轻松地创建一个充满矿物质的新 BasicList:

BasicList<Mineral> min = new BasicList<Mineral>();

我不能对 DescendingList 做同样的事情。每当我尝试与

DescendingList<Mineral> min = new DescendingList<Mineral>();

我的 IDE (IntelliJ) 无所不能

"Type parameter "Rock" is not within it's bound; should implement Bigger<Mineral>"

我真的不明白为什么会这样。我很确定我以某种方式弄乱了类型参数,我真的不确定在哪里。这应该可以以某种方式解决(至少在不删除任何类/接口的情况下 - 类头可能并且可能完全搞砸了)。提前感谢您提供的任何帮助。

【问题讨论】:

    标签: java generics inheritance wildcard


    【解决方案1】:

    Mineral 不是Bigger&lt;Mineral&gt;,它是Bigger&lt;Rock&gt;,这与Bigger&lt;Mineral&gt; 不兼容,因为即使MineralRock,Java 的泛型是不变的。它必须是Bigger&lt;Rock&gt;,因为Rock 是如何定义的——实现Bigger&lt;Rock&gt;——并且DescendingList 将类型参数A 声明为Bigger&lt;A&gt;

    因为它是一个消费者(类型参数作为方法参数),类型参数A的声明需要一个下限(super)。

    class DescendingList<A extends Bigger<? super A>> // ...
    

    这样Mineral 将在它自己的范围内。

    顺便说一句,您在BasicList 中实现Iterable 的原始形式;你应该在那里提供一个类型参数。

    【讨论】:

      猜你喜欢
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多