I have an interface in Java 6 that compiles correctly:
public interface IMultiMap extends Map> {
public int valueSize(
I ran the reflection code on Java 6.
Here's the code:
public static void main(String[] args) {
Class<IMultiMap> immClass = IMultiMap.class;
Method[] methods = immClass.getMethods();
for (Method method : methods) {
if (method.getName().equals("put"))
System.out.println(method.toString());
}
}
Here are the method signatures for the class:
public abstract boolean IMultiMap.put(java.lang.Object,java.lang.Object)
public abstract java.lang.Object java.util.Map.put(java.lang.Object,java.lang.Object)
Or more concisely:
boolean put(Object, Object)
Object put(Object, Object)
So they are erased to the same parameters with a different return type. I guess it's a bug an unspecified edge case in the Java 6 JLS then, as per assylias' answer. I wonder how Java 6 managed to resolve these methods correctly on runtime?
Edit: According to x4u's comment, the calling bytecode maintains a reference to the entire signature when it's compiled, so that's why the correct method was being called by the JVM. Since the compiler was probably capable of telling which method I was calling due to its access to the source (and thus to the generics information), the compiler probably linked it to the correct method via the entire signature. Interesting to know!
I think it's a bug in 1.6 that was fixed in 1.7. Extract from this page:
Synopsis: A Class Cannot Define Two Methods with the Same Erased Signature but Two Different Return Types
Description: A class cannot define two methods with the same erased signature, regardless of whether the return types are the same or not. This follows from the JLS, Java SE 7 Edition, section 8.4.8.3. The JDK 6 compiler allows methods with the same erased signature but different return types; this behavior is incorrect and has been fixed in JDK 7.
Example:
class A {
int m(List<String> ls) { return 0; }
long m(List<Integer> ls) { return 1; }
}
This code compiles under JDK 5.0 and JDK 6, and is rejected under JDK 7.