0

Consider the following code, where Feline and Animal are interfaces and Feline extends Animal.

List<Feline> miaus = foo.retrieveMiaus();
List<Animal> animals = xxxx;
bar.pet(animals);

What is the best way to cast miaus to animals - i.e the xxxx?

One way is to:

 List<Animal> animals = (List<Animal>) (List<?>)miaus;

But it has unchecked casts - and it downright looks ugly.

One can also iterate over miaus and populate the animals by casting each Feline to Animal, but this isn't ideal either.

Is there any cleaner way to do this?

mmalmeida
  • 1,037
  • 9
  • 27
  • Can you share the actual `Animal` and `Feline` code? – akortex Sep 23 '21 at 13:25
  • 2
    There is no clean way because a `List` is not a `List`. – luk2302 Sep 23 '21 at 13:26
  • 2
    `List animals = new ArrayList<>(miaus);` - it's not casting, it's constructing a new list of the right type. – Andy Turner Sep 23 '21 at 13:30
  • @akortex I think the simplest "proof of concept" is just empty interfaces `Animal` and `Feline`. – mmalmeida Sep 23 '21 at 13:48
  • @AndyTurner's answer compiles but has the same unparameterised warning (1/2) – mmalmeida Sep 23 '21 at 13:49
  • Probably because of what @luk2302 points out (2/2) – mmalmeida Sep 23 '21 at 13:50
  • 2
    @mmalmeida nope, no warnings there. The [`ArrayList` copy constructor](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ArrayList.html#%3Cinit%3E(java.util.Collection)) accepts a `Collection extends E>` as the parameter: that is, you can construct an `ArrayList` from a `List`. – Andy Turner Sep 23 '21 at 13:50
  • 1
    `List animals = Collections.unmodifiableList(miaus);` works without warnings and without copying, because the created view does not allow modifications, so you can't insert a wrong `Animal` into `animals`. – Holger Sep 25 '21 at 20:06

0 Answers0