The code below compiles and runs ok in Java 7 but fails to compile in Java 1.8.0 u25:
public class GenericTest {
public static class GenericClass<T> {
T value;
public GenericClass(T value) {
this.value = value;
}
}
public static class SecondGenericClass<T> {
T value;
public SecondGenericClass(T value) {
this.value = value;
}
}
public static<T >void verifyThat(SecondGenericClass<T> actual, GenericClass<T> matcher) {
}
public static<T >void verifyThat(T actual, GenericClass<T> matcher) {
}
@Test
public void testName() throws Exception {
verifyThat(new SecondGenericClass<>(""), new GenericClass<>(""));
}
}
The error message in Java 8 looks like this:
Error:(33, 9) java: reference to verifyThat is ambiguous
both method <T>verifyThat(com.sabre.ssse.core.dsl.GenericTest.SecondGenericClass<T>,com.sabre.ssse.core.dsl.GenericTest.GenericClass<T>) in com.sabre.ssse.core.dsl.GenericTest and method <T>verifyThat(T,com.sabre.ssse.core.dsl.GenericTest.GenericClass<T>) in com.sabre.ssse.core.dsl.GenericTest match
I've reviewed all the changes between:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2
But I failed to notice the exact reason for this behaviour.
Edit:
Just to answer some comments, it's quite clear that the compiler in both Java 7 and 8 will be able to handle such invocations (with signatures similar to what's left after compile time type erasure:
public static void verifyThat(SecondGenericClass actual, GenericClass matcher) {
}
public static void verifyThat(Object actual, GenericClass matcher) {
}
@Test
public void testName() throws Exception {
verifyThat(new SecondGenericClass<>(""), new GenericClass<>(""));
}
The bytecode generated for both generic methods, and erased is the same, and looks like this:
public static verifyThat(Lcom/sabre/ssse/core/dsl/GenericTest$SecondGenericClass;Lcom/sabre/ssse/core/dsl/GenericTest$GenericClass;)V
public static verifyThat(Ljava/lang/Object;Lcom/sabre/ssse/core/dsl/GenericTest$GenericClass;)V
Edit2:
Compilation under javac 1.8.0_40 fails with the same error