Downcast list return type in overriden getter of child class

Viewed 66

I have the following class hierarchy:

public class U {};
public class IU extends U {};

public class A {
    private final List<? extends U> us;

    public A(Collection<? extends U> us) { 
        this.us = new ArrayList<>(us);
    }

    public List<? extends U> getUs() { return this.us; }
}

public class B extends A {
    public B(Collection<IU> ius) { super(ius); }

    @Override
    public List<IU> getUs() { return (List<IU>) super.getUs(); }
}

The A.us list will never be modified so by construction, I know that getUs() from A will return a List containing only IU when called from an object of type B (unless someone does some really messy stuff, which I don't really bother with here).

The cast in B.getUs is marked as unsafe, so my questions are:

  • Is this cast actually safe or is there some issues I did not see?
  • If so, how can I mark it as such to remove the warning?
1 Answers

Since A is a type container, the contained type should be explicit for every A (final) definition.

Then, simply change:

public class U {};
public class IU extends U {};

public class A<T extends U> {
    private final List<T> us;

    public A(Collection<T> us) {
        this.us = new ArrayList<>(us);
    }

    public List<T> getUs() { return this.us; }
}

public class B extends A<IU> {
    public B(Collection<IU> ius) { super(ius); }

    @Override
    public List<IU> getUs() { return super.getUs(); }
}

now, A works for every type you want and the correct type is enforced at compile time (without warnings).

Related