如何将泛型类型限制为类的子类型?

时间:2016-11-22 22:14:55

标签: java generics

我有以下类层次结构:

class ListItem<T> {
}

abstract class ListView<T> {
    abstract void render(final ListItem<T> item);
}

现在,我想创建一个ListView的通用实现,它接受Consumer的实例。我的尝试如下:

class CommonListView<T> extends ListView<T> {

    private final Consumer<ListItem<T>> itemConsumer;

    CommonListView(Consumer<ListItem<T>> itemConsumer) {
        this.itemConsumer = itemConsumer;
    }

    @Override
    void render(ListItem<T> item) {
        itemConsumer.accept(item);
    }
}

interface Consumer<E> {

    void accept(E item);
}

它几乎可以满足我的需求,但是我想将E中的Consumer限制为ListItem的子类型。遗憾的是,添加<E extends ListItem<E>>失败了。

2 个答案:

答案 0 :(得分:1)

Consumer上的泛型更改为:

interface Consumer<T, E extends ListItem<T>> {
  void accept(E item);
}

然后在声明此类型的变量时添加额外的类型变量,例如:

static class CommonListView<T> extends ListView<T> {

  private final Consumer<T, ListItem<T>> itemConsumer;

  CommonListView(Consumer<T, ListItem<T>> itemConsumer) {
    this.itemConsumer = itemConsumer;
  }

  @Override
  void render(ListItem<T> item) {
    itemConsumer.accept(item);
  }
}

答案 1 :(得分:1)

<E extends ListItem<E>>沿着正确的行,但不太正确,看起来实际上是周期性的。

如果你不关心ListItem是什么,你可以这样做:

  <E extends ListItem<?>>

然而,正如Andy所说的更加正确的版本将添加一个额外的类型参数,如下所示:

class ListItem<T> {
}

abstract class ListView<T> {
  abstract void render(final ListItem<T> item);
}

class CommonListView<T> extends ListView<T> {

  private final Consumer<T, ListItem<T>> itemConsumer;

  CommonListView(Consumer<T, ListItem<T>> itemConsumer) {
    this.itemConsumer = itemConsumer;
  }

  @Override
  void render(ListItem<T> item) {
    itemConsumer.accept(item);
  }
}

interface Consumer<T, E extends ListItem<T>> {
  void accept(E item);
}

但是,我认为你在回答安迪时说这不起作用?你能澄清它是如何起作用的吗?