• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generic method won't accept argument  RSS feed

 
Daniel Cox
Ranch Hand
Posts: 231
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why won't the method annualCheckup() (which processes a List of Animals) accept a List of Dogs?
The compiler complains at line 18 with the following error message:
error.jpg
[Thumbnail for error.jpg]
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because a List<Dog> ISN'T‑A List<Animal>.
Imagine what would happen if List<Dog> were a subtype of List<Animal>You can explicitly cast anything to its subtype, but, if the compiler allowed line 5, you would have a List<Dog> which contains Cats and Elephants. Rather than failing to compile, which is good, your program would fail at runtime, which is bad. How many of your customers phone and complain, “Your program won't compile?”
If you want something which accepts Animal or its subtypes, declare the method as <T extends Animal>. That will accept a List<Animal>, a List<Cat>, a List<Dog> etc. Or if you want a type which is a subtype of List<Animal> use a wildcard: List<? extends Animal>. Note, as Rob Spoor explains here, you cannot add anything to the List with that declaration. More in the Java™ Tutorials (two sections).
 
Daniel Cox
Ranch Hand
Posts: 231
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Because a List<Dog> ISN'T‑A List<Animal>.

Thanks for your reply. Yes I'm aware that List<Dog> ISN'T‑A List<Animal>. My confusion is that the error message says that the method annualCheckup(List<capture#1-of ? extends Animal>) is not applicable to the argument List<Dog>. How can that be when List<Dog> IS‑A List<? extends Animal>.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Daniel Cox wrote:My confusion is that the error message says that the method annualCheckup(List<capture#1-of ? extends Animal>) is not applicable to the argument List<Dog>. How can that be when List<Dog> IS‑A List<? extends Animal>.


The way the generic class is coded, the annualCheck() method takes a List<T> that is the *same* T as the generic for the class.

In your usage of the generic class, you used a reference with a wildcard, that the T extends Animal. So, to answer your question... Yes, a List<Dog> is assignable to List<? extends Animal> reference, but there is no way that the compiler can confirm that the List you are providing to the method, has the same generic type that was assigned for your generic class instance.

Unfortunately, this is simply an artifact of using wildcards. Wildcards removes information from the compiler, making it not possible to confirm certain types, and hence, some stuff are no longer allowed.

Henry
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!