Bug 151677 - [15][compiler] javac vs. JDT: getClass() returns Class<?> vs. Class<T>
Summary: [15][compiler] javac vs. JDT: getClass() returns Class<?> vs. Class<T>
Status: VERIFIED DUPLICATE of bug 147381
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: All All
: P3 critical (vote)
Target Milestone: 3.2.1   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-07-25 06:23 EDT by Bojan Antonovic CLA
Modified: 2006-09-17 12:11 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bojan Antonovic CLA 2006-07-25 06:23:55 EDT
Calling the method getClass() inside a generic method returns different results for Sun's javac (up to 6 beta 2) and Eclipse's JDT (3.2). A compileable and warning-free program can NOT be compiled by javac.

Example valid for JDT:

   public <T> Class<? extends T> fooGetClass(final T object) {
       return object.getClass();
   }

Corrected version for javac:

   public <T> Class<? extends T> fooGetClass(final T object) {
       return (Class<? extends T>) object.getClass();
   } 

Without the cast (Class<? extends T>) javac reports:

GetClassTest.java:6: incompatible types
found   : java.lang.Class<capture of ? extends java.lang.Object>
required: java.lang.Class<? extends T>
               return object.getClass(); 

Eclipse reports for the javac version an unnecessary cast.

Eclipse 3.2 has a function "Clean Up" which removes unnecessary code. It also removes the cast, and makes the code uncompileable for javac.

I remember vaguely that the "Java Language Specification" hold an exception which gives Eclipse right. But I'm not sure.
Comment 1 Frederic Fusier CLA 2006-07-26 06:11:25 EDT
Maxime,
Can you verify if this is an identified Sun javac's bug?
Thanks
Comment 2 Frederic Fusier CLA 2006-07-26 06:16:31 EDT
Why did you set this bug severity to critical? You should not have so places where this problem occur and moreover, it is easily workaroundable (just put the cast back after the "Clean Up"). Would you agree to reduce it to normal (or major if you really use the "Clean Up" very often)?
Comment 3 Bojan Antonovic CLA 2006-07-26 08:00:55 EDT
At the moment, I have to change it in 2 of 40'000 LOC. But only because 
I wrote an auxiliary static method (like the one in the example). So 
judge yourself how frequent this can appear in a code.

I agree for a reduction of the severity as I'm an bug commiter from outside.

It's interesting to see that if you let T be a subclass of Number, javac complains in this way:

incompatible types
found   : java.lang.Class<capture of ? extends java.lang.Number>
required: java.lang.Class<? extends T>
                return object.getClass();

So javac makes erasure first. I don't see the point in differenciating between Class<? extends T> (with T extends Number) and Class<? extends Number> if the ereased return type is the type Class. Even if the return value of the method is assignable to Class<? extends Number>, why should there be internaly a restriction?

It would be nice to know what counts:

1. Class<? extends T> because this is correct if Java had no erasure
2. Class<? extends [raw type]> because Sun wants it so in javac

For me it looks like a bug in javac. If this would be the case, I don't think it was a mistake to fill this bug report. Who would expect that getClass() works wrong?
Comment 4 Maxime Daniel CLA 2006-07-26 08:37:38 EDT
Should have been more proactive on this one, sorry. See bug 147381 for further comments.

*** This bug has been marked as a duplicate of 147381 ***
Comment 5 Frederic Fusier CLA 2006-08-08 09:15:59 EDT
Verified for 3.3 M1 using build I20060807-2000.
Comment 6 Frederic Fusier CLA 2006-09-17 12:11:18 EDT
Verified for 3.2.1 using build M20060915-1045