Community
Participate
Working Groups
There are three main classes, an class called UserClass which is parameterized based on KeyClass, and a child class that extends UserClass concretized with a child inner class: abstract public class UserClass<K extends KeyClass> { protected class DataHolder { private final Map<K, Object> singleData = new HashMap<K,Object>(); public void put(K key, Object value) {this.singleData.put(key, value); } } private final DataHolder data = new DataHolder(); public Object get(K key) { return data.singleData.get(key); } protected void loadHook(DataHolder data) {} } abstract public class KeyClass { public abstract String getName(); public static class Named extends KeyClass { private final String paramName; protected Named(String paramName) {this.paramName = paramName;} @Override public final String getName() {return this.paramName; } } } public class ChildClass extends UserClass<ChildClass.Key> { public static class Key extends KeyClass.Named { public static final Key instance = new Key("1"); private Key(String n) { super(n); } } @Override protected void loadHook(DataHolder data) { } } The @Override in the last class causese Name clash: The method loadHook(UserClass<ChildClass.Key>.DataHolder) of type ChildClass has the same erasure as loadHook(UserClass.DataHolder) of type UserClass<K> but does not override it If you remove the @Override, it works but gives a warning. It compiles correctly in javac. This behavior is a regression from M6.
Your example doesn't compile for quite a few other errors. Syntax error, unexpected static modifiers. Please correct your testcase to only expose the issue described in this PR; then reopen.
I had assumed incorrectly that you would have pasted each of the classes into three separate files, which would automatically add in the import. You cannot reproduce the bug in a single class because of its use of statics. I.e. if you place them all in the same class, it works correctly. Here is the example that works correctly: // Reduction.java import java.util.*; public class Reduction { abstract static public class UserClass<K extends KeyClass> { protected class DataHolder { private final Map<K, Object> singleData = new HashMap<K,Object>(); public void put(K key, Object value) {this.singleData.put(key, value); } } private final DataHolder data = new DataHolder(); public Object get(K key) { return data.singleData.get(key); } protected void loadHook(DataHolder data) {} } abstract static public class KeyClass { public abstract String getName(); public static class Named extends KeyClass { private final String paramName; protected Named(String paramName) {this.paramName = paramName;} @Override public final String getName() {return this.paramName; } } } public static class ChildClass extends UserClass<ChildClass.Key> { public static class Key extends KeyClass.Named { public static final Key instance = new Key("1"); private Key(String n) { super(n); } } @Override protected void loadHook(DataHolder data) { } } } However, when it is placed in three separate files, it doesn't work //UserClass.java import java.util.*; abstract public class UserClass<K extends KeyClass> { protected class DataHolder { private final Map<K, Object> singleData = new HashMap<K,Object>(); public void put(K key, Object value) {this.singleData.put(key, value); } } private final DataHolder data = new DataHolder(); public Object get(K key) { return data.singleData.get(key); } protected void loadHook(DataHolder data) {} } //KeyClass.java abstract public class KeyClass { public abstract String getName(); public static class Named extends KeyClass { private final String paramName; protected Named(String paramName) {this.paramName = paramName;} @Override public final String getName() {return this.paramName; } } } //ChildClass.java public class ChildClass extends UserClass<ChildClass.Key> { public static class Key extends KeyClass.Named { public static final Key instance = new Key("1"); private Key(String n) { super(n); } } @Override protected void loadHook(DataHolder data) { } }
This works fine when compiled from source... its a binary issue with parameterized types. The testcase can be reduced to 2 files: public class UserClass<K> { protected class DataHolder {} protected void loadHook(DataHolder data) {} } public class ChildClass extends UserClass<Object> { @Override protected void loadHook(DataHolder data) {} } When ChildClass is compiled & picks up UserClass as a binary, we end up comparing 2 parameterized types: protected class DataHolder extends NULL TYPENULL SUPERINTERFACES enclosing type : UserClass<java.lang.Object>NULL FIELDSNULL METHODS and for the inherited method: protected class DataHolder extends NULL TYPENULL SUPERINTERFACES enclosing type : UserClass#RAWNULL FIELDSNULL METHODS
Feels my bug.
Seems similar to bug 96085
Added GenericTypeTest#test709. Problem was along the same line as bug 96085, but on a different path. Fixed by using LookupEnvironment#convertToRawType(...) during UnresolvedReferenceBinding resolution. Fixed
Verified for 3.1 RC2 using build N20050607-0010 +JDT/Core HEAD
Verified with I20050610-0010