Community
Participate
Working Groups
With both 3.1M4 and 3.1M5a the following code compiles without any problems. public interface MyIface { public <T> void foo(T p); } public class MyClass implements MyIface{ public <T extends Integer> void foo(T p) { //does something } } However, javac 1.5 gives me: MyClass.java:1: MyClass is not abstract and does not override abstract method <T>foo(T) in MyIface public class MyClass implements MyIface{ ^ 1 error Additionally, the code underneath produces the following output with the eclipse compiler: Base: 1 Sub: 1 Exception in thread "main" java.lang.ClassCastException: java.lang.String And this output with javac: Base: 1 Sub: 1 Exception in thread "main" java.lang.ClassCastException: java.lang.String This seems to be a consistent and well-thought implementation given these two simple examples. Does someone else know more details about this issue? Coconha public class Signature { public Signature() { super(); Sub s = new Sub(); s.foo(new Integer(1)); s.foo("as"); } public class Base { public <T> void foo(T a) { System.out.println("Base: " + a); } } public class Sub extends Base { public <T extends Integer> void foo(T a) { super.foo(a); System.out.println("Sub: " + a); } } public static void main(String[] args) { new Signature(); } } I opened the Signature$Sub.class generated both by javac and Eclipse with jclasslib bytecode viewer and found: javac version ==> has only one method entry: - foo(java.lang.Integer) with a "public" access flag. The class file looks exactly the same if I compile it after manually applying Erasure. eclipse version ==> has 2 entries: - foo(java.lang.Integer) with a "public" access flag - foo(java.lang.Object) with a "public bridge synthetic" access flag The class file looks exactly the same as in the javac version if I compile it after manually applying Erasure.
I am sorry, I mistyped something on previous comment: Where I said: >And this output with javac: >Base: 1 >Sub: 1 >Exception in thread "main" java.lang.ClassCastException: java.lang.String I actually meant: Base: 1 Sub: 1 Base: as
Carlos, are you sure you wanted to set severity to "critical"? IMO, it's "normal" or "minor". Click on the "Severity:" link above to see how severities are used, e.g.: Critical crashes, loss of data, severe memory leak
Markus, You are right. The reason I jumped and placed it as critical is that we started using 3.1 as our main development environment. And due to lack of experience with Erasure we coded a lot based on the assumption that MyIface/MyClass code example gets compiled without any problems. To be more specific, we defined an interface for functors: public interface UnaryFunction<S> { public <T> S execute(T p); } And we have by now more than 100 functors in our code based on this interface which are implemented in a similar way as below: public class MyClass<SS> { // more stuff here public class Func implements UnaryFunction<SS> { public <TT extends Integer> SS execute(TT s) { SS out = null; // does something return out; } } } That means that when this bug is fixed, our entire project will not compile anymore as I will to rewrite my interface to something like: public interface UnaryFunction<S,T> { public S execute(T p); } and change all functors accordingly. Taking into consideration that there might be more people out there that will be silly enough (like me! L) to fall in the same trap I think this bug was quite critical. I know the Bugzilla criteria describes critical as “crashes, loss of data,etc”. For someone like me, which is now informed about the issue, I consider this Bug as Minor or Normal, but for someone less informed, this could be a Blocker. So Critical was the compromise I found here. BTW, do you have any tips for a easier work around to my problem described above?
I would also qualify this defect as critical based on what you described. Having the compiler misbehaves, and let people write bogus code is nasty. We want to resolve this asap.
I suspect problem comes from MethodVerifier15 boolean doTypeVariablesClash(MethodBinding one, MethodBinding substituteTwo) { TypeBinding[] currentVars = one.typeVariables; TypeBinding[] inheritedVars = substituteTwo.original().typeVariables; return currentVars.length != inheritedVars.length && currentVars.length > 0; } The variable clash detection doesn't perform bound checks.
Already have a fix - just needs to be tested.
Added MethodVerify test051
The error is properly reported now. Verified in I20050510-0010