-3

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

Kenji
  • 61
  • 6
  • 2
    you can read [this](https://stackoverflow.com/questions/27902219/nested-wildcards/58631449#58631449) for an extensive read. but the simple answer is `public void printNames(List extends Animal> list){ ... }` – Eugene Sep 01 '21 at 17:05
  • But is `Dog` an `Animal` type in your code ? – cruisepandey Sep 01 '21 at 17:06
  • Yes it is, I refer to the setup of the related answer – Kenji Sep 01 '21 at 19:46

2 Answers2

2

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());
   }
}
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
markspace
  • 10,621
  • 3
  • 25
  • 39
1

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){
Andy Turner
  • 137,514
  • 11
  • 162
  • 243