I stumbled across the same problem as this guy in the related question: Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?
Though I do understand why it is not possible to pass a List<Dog>
to a method which accepts List<Animal>
, as explained in the answers; I wonder what is ultimately the solution? Suppose I want the method to print the names of the objects in the list, like
public void printNames(List<Animal> list){
for(Animal a : list){
System.out.println(a.getName());
}
}
Given that Animal implements getName(), this method would be safe to call with whatever list of animals or subtypes of that class. Since I can't do that, what is the best way to provide this functionality for whatever list of (sub)animals I might have?
I can say what does not work, which is the obvious way:
public void printNames(List<Dog> list){
for(Dog d : list){
System.out.println(d.getName());
}
}
Because that throws nameClash: Both methods have same erasure
CodePudding user response:
It depends on what you intend to do with the result. Study "PECS" it will help. In this case you can use a wildcard to solve it, but also generic methods and other techniques might be involved.
public void printNames(List<? extends Animal> list){
for(Animal a : list){
System.out.println(a.getName());
}
}
You could also just use the toString()
method, which might be better.
public void printAnything(List<?> list){
for(Object a : list){
System.out.println(a.toString());
}
}
CodePudding user response:
I wonder what is ultimately the solution?
A wildcard:
public void printNames(List<? extends Animal> list){
Or, if you need to do something like put things into list
that you took out of it, a type variable:
public <A extends Animal> void printNames(List<A> list){