File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Most confusing generic error Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Most confusing generic error" Watch "Most confusing generic error" New topic
Author

Most confusing generic error

Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4659
    
    5

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

Joined: Sep 07, 2004
Posts: 781



Retired horse trader.
 Note: double-underline links may be advertisements automatically added by this site and are probably not endorsed by me.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

To further clarify, wizard.getClass() returns Class<? extends Inventor>, whereas Inventor.class returns Class<Inventor>.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4659
    
    5

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

Joined: Sep 20, 2010
Posts: 3647
    
  17

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.
 
Consider Paul's rocket mass heater.
 
subject: Most confusing generic error