• 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

Java 6 instanceof compile error with generics - works fine in Java 5

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,

I'm hoping someone can explain this to me, I have a piece of code that builds and runs fine in eclipse using v6 JRE, eclipse using v5 JRE and javac using a v5 compiler. However it won't build on the command line using v6 compiler.

This example code is a simple 2 object setup with generics and inheritance, the superclass is abstract and there is one subclass that provides the concrete implementation:

AbstractSuperClass is defined as:



ConcreteObject is defined as:


I then wrote a simple test case that creates an instance of ConcreteObject and then passes it to this method:



However when I try and build the code with Java 6 I get the following compile error from javac:

InstanceofTest.java:41: inconvertible types
found : genericstest.AbstractSuperClass<capture#671 of ?>
required: genericstest.ConcreteObject
if (object instanceof ConcreteObject) {
^
InstanceofTest.java:42: inconvertible types
found : genericstest.AbstractSuperClass<capture#274 of ?>
required: genericstest.ConcreteObject
ConcreteObject concrete = (ConcreteObject) object;
^
2 errors


I've looked into generics and I just don't understand what the problem here is. If I use AbstractSuperClass without the <?> in the method arguments then it builds and works fine (apart from the warnings about using a raw type). If someone can explain what is going on and why it is wrong that would be great . I don't understand why instance of is complaining when the ConcreteObject is a subclass of AbstractSuperClass.

 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I'm hoping someone can explain this to me, I have a piece of code that builds and runs fine in eclipse using v6 JRE, eclipse using v5 JRE and javac using a v5 compiler. However it won't build on the command line using v6 compiler.




Taking a quick look at your code, I don't see how it can "build and run fine" in any of those JREs. At minimum, you have an abstract class that is trying to extend from itself. And you may have a name conflict in the concrete class as well -- although not sure if the second is an issue.

Henry
 
Andrew Matthews
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:

I'm hoping someone can explain this to me, I have a piece of code that builds and runs fine in eclipse using v6 JRE, eclipse using v5 JRE and javac using a v5 compiler. However it won't build on the command line using v6 compiler.




Taking a quick look at your code, I don't see how it can "build and run fine" in any of those JREs. At minimum, you have an abstract class that is trying to extend from itself. And you may have a name conflict in the concrete class as well -- although not sure if the second is an issue.

Henry



It build just fine . It isn't extending itself, only the generic definition is extending itself:



This means that ObjectType, where used in the abstract class, must be a type of AbstractSuperClass. This means you can have superclass implementations that use methods from the AbstractSuperClass in their implementation.

For example, I could extend my definition further:



Without defining the generics as <ObjectType extends AbstractSuperClass><ObjectType> ObjectType is not a type of AbstractSuperClass so you cannot reference its methods. This is a very useful use of generics when creating powerful abstract classes, and as far as I know is completely valid - at least it was in Java 5.

I'm not sure what you mean about a name conflict in the concrete class, could you elaborate?

edit: fixing weird formatting error that got the <> wrong in places. Code is copied and pasted from my test example so I'm sure it works!
 
Ranch Hand
Posts: 128
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can confirm the problem - you are right Andrew, the code compiles and runs fine under Eclipse, but fails using Sun's compiler. Here's my test in a single file:



I tried substituting <?> with <T> or any other combination with no luck. What I understand from the error, the compiler says something like: "Hey, there's no way the object parameter can be an instance of ConcreteObject". We get the same when the checkInstance method looks as silly as this:

where it is impossible for the object to be a String.
The easier example is:

Here again, Eclipse says it's OK, but Sun disallows the second assignment.
So it appears that downcasting from a wildcarded generic is prohibited. I wonder why... I'll try to search for it, but the wildcarded generics is one of the most confusing areas of Java knowledge ;)
 
Andrew Matthews
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Adam Michalik wrote:I can confirm the problem - you are right Andrew, the code compiles and runs fine under Eclipse, but fails using Sun's compiler. Here's my test in a single file:



Phew thanks Adam! At least I'm not going mad! Much more obvious example as a single file, thank you, I'm so ingrained with 1 class per file that I didn't think of that .

I too have tried various different way using <T> etc. to no avail.

What is very odd is that you can replace the checkInstanceOf() method with this and it works fine (apart from the raw type warning):

 
Andrew Matthews
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah ha!

JDK bug

Is exactly this issue.

Says "Release Fixed: 7(b40)" which I guess means it isn't fixed until Java 7
 
Adam Michalik
Ranch Hand
Posts: 128
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Good job with tracking it down! Seems that we need to use a reflective workaround: Class.isAssignableFrom() and Class.cast()
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Oops.... sorry.... next time when I do a "quick look", I'll make sure that it isn't that quick...

Henry
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic