Java - generics clarification

Viewed 101

I have following code:

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;
    }
}

And the problem is last Error:(36, 35) java: type argument DC is not within bounds of type-variable C.

Inside container group, I can store containers with both type IDs. I assume that there is no better way to store this than ? In runtime, I will have to use instanceof to test for Id1 or Id2 in order to access that getB() getter. If this was behaviour (and not data) I could have common method in Id interface, but since this is data only present in Id2, I suppose downcasting is only way?

UPDATE

Actually this solves the ERROR, but don't know why first solution does not work:

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