Il seguente codice compilato ed eseguito ok in Java 7, ma non riesce a compilare in Java 1.8.0 U25:Java 8 metodo ambiguo riferimento per classe generica
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<>(""));
}
}
Il messaggio di errore in Java 8 è simile al seguente:
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
ho rivisto tutte le modifiche tra:
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
Ma non sono riuscito a notare il motivo esatto per questo comportamento.
Edit:
Proprio per rispondere ad alcune osservazioni, è abbastanza chiaro che il compilatore sia in Java 7 e 8 sarà in grado di gestire tali invocazioni (con firme simile a ciò che resta dopo la compilazione tipo di tempo la cancellazione :
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<>(""));
}
il bytecode generato per entrambi i metodi generici, e cancellata è la stessa, e si presenta come segue:
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 sotto javac 1.8.0_40 viene a mancare con lo stesso errore
anche con generici reificati questo sarebbe un problema – jkschneider
Possibile duplicato: http://stackoverflow.com/questions/28466925/java-type-inference-reference-is-ambiguous-in-java-8-but-not- java-7 – assylias
sì, ma secondo JLS, il metodo più specifico dovrebbe essere scelto – xendoo