This week's giveaway is in the EJB and other Java EE Technologies forum.
We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line!
See this thread for details.
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 EJB 3 in Action this week in the EJB and other Java EE Technologies 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: 4637
    
    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: 3371
    
    9
To further clarify, wizard.getClass() returns Class<? extends Inventor>, whereas Inventor.class returns Class<Inventor>.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4637
    
    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: 3371
    
    9
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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Most confusing generic error
 
Similar Threads
Another confusing generic error
JLS Types, Values, Variables - Error?
generics / adding to wildcard Collection
Generics driving me crazy, for the fourth time
Generics - Bounded Type Parameters - Query