方法参数不采用实现接口的泛型

时间:2018-01-19 13:43:11

标签: java generics interface implements

我似乎在这里遇到了一个奇怪的问题。我有一个名为Sortable的界面。然后我有另一个班级,如下:

public class LeftSort {

    private List<Sortable> list;

    public <T extends Sortable> LeftSort(List<T> list) {
        this.list = list;
    }

}

然而,当我去创建另一个名为Foo的课程时,就像这样:

public class Foo implements Sortable {}

在JUnit测试中执行以下操作时:

List<Foo> list = new ArrayList<Foo>();
// Initialise... blah blah.

LeftSort sorter = new LeftSort(list);

我收到以下错误:

  

构造函数LeftSort(List&lt; Foo&gt;)未定义。

我发誓你能像我一样在泛型中使用接口。我在这里做错了什么吗?

我也一直在做private List<? extends Sortable> list;,但无济于事。

编辑:请在将来注意检查您在投诉之前实际导入的课程与我一样。我只是导入了错误的类(Foo就是我在网上给它的名字,实际上是Test,我这么聪明地决定使用......)

3 个答案:

答案 0 :(得分:3)

请注意,您的构造函数实际上没有编译:

public <T extends Sortable> LeftSort(List<T> list) {
    this.list = list;
}

要接受Sortable的任何子类,请使用Upper Bounded Wildcard <? extends Sortable>

public class LeftSort {

    private List<? extends Sortable> list;

    public LeftSort(List<? extends Sortable> list) {
        this.list = list;
    }

}

答案 1 :(得分:2)

这不是我得到的错误when I try to compile it

Main.java:13: error: incompatible types: List<T> cannot be converted to List<Sortable>
        this.list = list;
                    ^
  where T is a type-variable:
    T extends Sortable declared in constructor <T>LeftSort(List<T>)
1 error

这是我所期望的,因为List<? extends Sortable>不是List<Sortable>

你必须采取清单的防御性副本:

this.list = new ArrayList<>(list);

或制作有界类型的list字段:

private List<? extends Sortable> list;

答案 2 :(得分:1)

通常为整个类定义泛型类型,如下所示:

public class LeftSort<T extends Sortable> {
    private List<T> list;
    public LeftSort(List<T> list) {
        this.list = list;
    }
}

这样您可以使用LeftSort实例化new ListSort<>(list)(假设您正在使用Java 7 +)。