• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Most confusing generic error

 
Rancher
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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?
 
Ranch Hand
Posts: 781
Netbeans IDE Ubuntu Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
 
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To further clarify, wizard.getClass() returns Class<? extends Inventor>, whereas Inventor.class returns Class<Inventor>.
 
Pat Farrell
Rancher
Posts: 4803
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic