Java - 泛型澄清

时间:2017-07-27 16:14:50

标签: java generics

我有以下代码:

interface Id{
    int getA();
}
class Id1 implements Id{
    @Override
    public int getA() {
        return 0;
    }
}
class Id2 implements Id{
    @Override
    public int getA() {
        return 0;
    }
    public int getB(){
        return 2;
    }
}

interface Container<I extends Id, C extends Container<I,C>>{
    C withInt(int a);
}

class DefaultContainer<I extends Id> implements Container<I, DefaultContainer<I>>{
    @Override
    public DefaultContainer<I> withInt(int a) {
        return new DefaultContainer<>();
    }
}
class SpecialContainer<I extends Id> extends DefaultContainer<I>{
    @Override
    public SpecialContainer<I> withInt(int a) {
        return new SpecialContainer<>();
    }
}

interface ContainerGroup<C extends Container<? extends Id, C>>{
    Stream<C> getContainers();
}

class DefaultContainerGroup<DC extends DefaultContainer<? extends Id>>
        implements ContainerGroup<DC>{
    //Error:(36, 35) java: type argument DC is not within bounds of type-variable C

    @Override
    public Stream<DC> getContainers() {
        //can return:
        // [ DefaultContainer<Id>, DefaultContainer<Id2>, ... ] OR
        // [ SpecialContainer<Id>, SpecialContainer<Id2>, ... ]
        return null;
    }
}

问题出在最后错误:(36,35)java:type参数DC不在类型变量C的范围内。

在容器组内部,我可以存储具有两种类型ID的容器。我认为没有更好的方法存储这个?在运行时,我将不得不使用instanceof来测试Id1或Id2,以便访问getB()getter。如果这是行为(而不是数据),我可以在Id接口中使用通用方法,但由于这是仅存在于Id2中的数据,我认为向下转换只是方法吗?

更新

实际上这解决了ERROR,但不知道为什么第一个解决方案不起作用:

interface ContainerGroup<C extends Container<? extends Id, ? extends Container>>{
    Stream<C> getContainers();
}

1 个答案:

答案 0 :(得分:0)

我想我知道发生了什么。

DefaultContainerGroup中,DC extends DefaultContainer<? extends Id>表示“任何派生自DefaultContainer”。

ContainerGroup中,C extends Container<? extends Id, C>表示“完全 C,用作Container的参数”。

所以DefaultContainer本身是可以接受的,但是从它派生的类不是。