FULL PRODUCT VERSION :
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
Java selects the wrong method during type inference with generic-type returning objects.
See source code below. The "get" method in class "A" returns a type that extends "A". The main method then tries to assign the return value to a Collection, an interface. This compiles but will obviously throw a ClassCastException at run time. Any interface can be chosen, List, Map, anything. It will still compile. Basically the type inference mechanism is not checking if the return type can actually be assigned when an interface is concerned.
This would have caused a compile-time error in JDK 1.6 and below:
C:\Users\gendrok\Documents\NetBeansProjects\temp\src\Test.java:18: type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds java.util.Collection,Test.A
Collection c1 = new A().get();
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the source code and run it.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The source code should be prevented from being compiled.
ACTUAL -
The source code is compiled successfully.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ClassCastException: Test$A cannot be cast to java.util.Collection
at Test.main(Test.java)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test {
public static class A {
public A() {
}
public <T extends A> T get() {
return (T)this;
}
}
public static void main(String[] args) {
Collection c1 = new A().get();
List l1 = new A().get();
Set s1 = new A().get();
Map m1 = new A().get();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do not use generic-type returning methods.