Home > front end >  List of Dogs List of animals... What is the solution?
List of Dogs List of animals... What is the solution?

Time:09-17

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){
  • Related