1

I have a protected Map<String, List<Animal>> animals; in my class. In my constructor, I have

animals.put("dogs", new ArrayList<Animal>());
animals.put("cats", new ArrayList<Animal>());

and eveything works, as expected. If I want a Dog or a Cat, I have only to it get from map and cast.

But, what if I should want

animals.put("dogs", new ArrayList<Dog>());

Java does not allow me this. I read also it in this SO answers But I need it, since I'm using JSF and I need in the EL expression of the page a method of Dog that Animal doesn't have.

Since I created a factory for Animal I thought to use the factory to get the right object type, but it seems me a little weird.

Is there some way I can use animals.put("dogs", new ArrayList<Dog>()); or some other alternatives?

PS: I'm using Java 7

Marco Sulla
  • 15,299
  • 14
  • 65
  • 100
  • 4
    Well, you could use `Map> animals;` which would allow you to do `animals.put("dogs", new ArrayList());` but you'd still not be able to get a `ArrayList` out of that map without casting. After all, the map could consist other types for other keys so how should the compiler even know what type to return here? You'd need to provide that cast, maybe using specific methods like `List getDogs() { return (List)animals.get("dogs"); }` (the raw cast would be necessary so the compiler doesn't complain. – Thomas Jun 30 '21 at 09:30
  • The generics of a map support values of **all the same type**, and you have a map where the values are subtly different types. It sounds like you should be using a `Map>`, but if you want to retrieve your list of dogs as a `List`, rather than a `List extends Animal>`, you will have to cast it. You can't avoid casting somewhere. – khelwood Jun 30 '21 at 09:35
  • You probably have incorrectly designed inheritance hierarchy if you have that problems. – M. Dudek Jun 30 '21 at 09:38

1 Answers1

0

Ok, it seems absurd but the problem was in the JSF code:

<ui:repeat var="animal" value="#{bean.animals.get('dogs')}" varStatus="status">

I don't know why, but changing var="animal" to anything else works. I do not need any cast.

Marco Sulla
  • 15,299
  • 14
  • 65
  • 100