This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes Java in General and the fly likes Java 6 instanceof compile error with generics - works fine in Java 5 Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Java 6 instanceof compile error with generics - works fine in Java 5" Watch "Java 6 instanceof compile error with generics - works fine in Java 5" New topic
Author

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

Andrew Matthews
Greenhorn

Joined: Jul 02, 2009
Posts: 4
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.

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

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


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Andrew Matthews
Greenhorn

Joined: Jul 02, 2009
Posts: 4
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!
Adam Michalik
Ranch Hand

Joined: Feb 18, 2008
Posts: 128
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

Joined: Jul 02, 2009
Posts: 4
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

Joined: Jul 02, 2009
Posts: 4
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

Joined: Feb 18, 2008
Posts: 128
Good job with tracking it down! Seems that we need to use a reflective workaround: Class.isAssignableFrom() and Class.cast()
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40


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

Henry
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Java 6 instanceof compile error with generics - works fine in Java 5