Generics compila ed esegue in Eclipse, ma non viene compilato in javac

Nota : questo è uno spin-off del contratto Comparable and Comparator rispetto a null

Questo codice viene compilato e funziona 20090920-1017 in Eclipse ( 20090920-1017 )

 import java.util.*; public class SortNull { static <T extends Comparable> Comparator nullComparableComparator() { return new Comparator() { @Override public int compare(T el1, T el2) { return el1 == null ? -1 : el2 == null ? +1 : el1.compareTo(el2); } }; } public static void main(String[] args) { List numbers = new ArrayList( Arrays.asList(3, 2, 1, null, null, 0) ); Comparator numbersComp = nullComparableComparator(); Collections.sort(numbers, numbersComp); System.out.println(numbers); // "[null, null, 0, 1, 2, 3]" List names = new ArrayList( Arrays.asList("Bob", null, "Alice", "Carol") ); Comparator namesComp = nullComparableComparator(); Collections.sort(names, namesComp); System.out.println(names); // "[null, Alice, Bob, Carol]" } } 

Eppure non si compila su javac 1.6.0_17 . Questo è il messaggio di errore:

 SortNull.java:17: incompatible types; no instance(s) of type variable(s) T exist so that java.util.Comparator conforms to java.util.Comparator found : java.util.Comparator required: java.util.Comparator Comparator numbersComp = nullComparableComparator(); SortNull.java:25: incompatible types; no instance(s) of type variable(s) T exist so that java.util.Comparator conforms to java.util.Comparator found : java.util.Comparator required: java.util.Comparator Comparator namesComp = nullComparableComparator(); 2 errors 

Qualcuno può spiegare perché la discrepanza? è un insetto? Se è così, chi ha l’errore?

Questo è un bug confermato: ID bug 6468354 . Ecco un estratto di pertinenza:

Questo problema è causato dal fatto che a volte l’implementazione di JLS3 di JLS3 15.12.2.8 ignora i limiti ricorsivi, a volte no (come in questo caso). Quando i limiti ricorsivi contengono caratteri jolly, tali limiti vengono inclusi quando si calcolano variabili di tipo non inverso. Questo rende il test (Integer <: Comparable subtyping successivo test (Integer <: Comparable dove T è una variabile di tipo da dedurre).

Verrà risolto dopo 6369605

Mi è capitato su WinXP con 1.6.0_13 pure. Ah bene, mi limiterò a usare Eclipse 🙂

Puoi aggirare questo specificando esplicitamente la class generica:

 Comparator namesComp = Stack.nullComparableComparator(); 

Ho avuto un problema simile e aggiornato da jdk1.6.0_16 a jdk1.6.0_23 ed è andato via senza modifiche al codice.