• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Most confusing generic error

 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I thought I understood Java Generics.... I can't figure out what the compiler is complaining about in a recent code snippet that I wrote.

I've got a class that wants a class as its argument.

In the sample below, the "Inventor" class implements PatentBase. So the result of the two calls to the constructor are identical, to my eyes. But the compiler thinks differently.


The specific error from the compiler is:
/Users/pfarrell/sandbox/wayserver/wayfinderlib/test/com/wayfinderdigital/struct/ContainedPboListTest.java:67: cannot find symbol
symbol : constructor ContainedPboList(java.lang.Class<capture#480 of ? extends com.wayfinderdigital.busobj.Inventor>)
location: class com.wayfinderdigital.struct.ContainedPboList<com.wayfinderdigital.busobj.Inventor,com.wayfinderdigital.busobj.Patent>
instance = new ContainedPboList<Inventor, Patent>(wizard.getClass());
1 error



I think that lines 3 and 4 are functionally identical in the second code segment. How is "Inventor.class" different from "wizard.getClass()" when the wizard is an Inventor?
 
James Sabre
Ranch Hand
Posts: 781
Java Netbeans IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Stephan van Hulst
Bartender
Pie
Posts: 5605
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To further clarify, wizard.getClass() returns Class<? extends Inventor>, whereas Inventor.class returns Class<Inventor>.
 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the quick replies, but I'm not understanding this.

public class Inventor extends Human implements PatentElement {

We have the constructor argument taking <T extends PatentElement>
So Inventor matches the generic template.

Inventor instanceof PatentElement is true.
 
Stephan van Hulst
Bartender
Pie
Posts: 5605
55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, but generics are invariant. Your constructor requires a Class<Inventor>, while you're trying to provide it a Class<? extends Inventor>. Check out the documentation for Object.getClass().

Class<? extends T> is *not* a subtype of Class<T>.

Let's compare it to the cage example:
If line 3 were allowed, we would be able to add butterflies to a cage that was designed for lions only.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic