Java - 使用对象列表和泛型

时间:2017-08-28 17:20:36

标签: java generics

我遇到一个简单的Java代码问题。 我无法确定它是否解决了原来的目的; 写它的那个人(但是无法到达)只是告诉了我 “实现IA的对象应该是List的容器(IB) - 就像对象一样”。乍一看我认为它错了, 因为强约束(T extends IB<T>)似乎不合逻辑, 但IDE编译器未显示任何相关的错误/警告。

如果此类代码有意义, 有人可以提供这种接口的实际使用示例。

提前致谢。

import java.util.List;

public interface IA<T extends IB<T>> {
    public List<T> getList();
}

public interface IB<T> {
    public T getValue();
}

更新1 :使用具体样本类添加测试

class Bar implements IA<Foo>{

    List<Foo> list;

    @Override
    public List<Foo> getList() {
        return list;
    }

    Bar(List<Foo> foos) {
        this.list = foos;
    }
}

class Foo implements IB<Foo> {

    public Float data;

    @Override
    public Foo getValue() {
        return foo;
    }

    Foo(Float data){
        this.data = data;
    }

    public Float getV() {
        return data;
    }
}

public class DataTest {

    @Test
    public void myTest() {
        Foo f = new Foo(10F);
        List<Foo> fs = new ArrayList<>();
        fs.add(f);
        Bar bar = new Bar(fs);
        List<Foo> foos = bar.getList();
        System.out.println(foos.get(0).getV());
    }

}

这是使用IA和IB的正确方法吗?

2 个答案:

答案 0 :(得分:0)

由于T仅用于协变位置,因此可以安全使用,因此对IA的评论可能是正确的。如果IA在其某个参数中有一个接受T(如int compare(T a, T b))的方法,则会导致出现问题,因为它处于逆变位置。

答案 1 :(得分:0)

这种约束在某些情况下是有道理的。例如,如果要创建排序列表类,可以执行类似

的操作
class SortedList<T extends Comparable<? super T>>

您需要将元素类型与自身进行比较,这是您对其进行排序所必需的。 (请注意,Comparable本身在其类型参数上没有绑定,就像这里一样。)

上述内容中的super是因为ComparableT的使用者,因此根据PECS,您应该使用super通配符{{1} }}。在您的情况下,由于Comparable是与IB相关的制作人,因此如果您想使其最为通用,则可以将其设为T

对于使用此约束的实际用例,我提出的是使用约束的类:

public interface IA<T extends IB<? extends T>>

如果您有一个实现类,它本身是通用的(绑定了相同的class Bar<T extends IB<T>> implements IA<T> { T start; @Override public List<T> getList() { List<T> result = new ArrayList<T>(); for (T x = start; x; x = x.getValue()) { result.add(x); } return result; } Bar(T start) { this.start = start; } } ),它需要一个<T extends IB<T>>并生成更多T s,直到达到T },并返回这些列表。

虽然这仍然不要求接口null具有约束,所以我想它仍然没有提供一个例子,其中IA参数的绑定是必要的。