2016-06-26 27 views
8

Le risposte trovate a Java 8 lambdas, Function.identity() or t->t sembrano implicare che Function.identity() equivalga quasi sempre a t -> t. Tuttavia, nel banco di prova visualizzato di seguito, la sostituzione di t -> t per Function.identity() genera un errore del compilatore. Perché?Perché Function.identity() interrompe la reimpostazione del tipo ma t -> t no?

public class Testcase { 

    public static <T, A, R, K, V> Collector<T, A, R> comparatorOrdering(
      Function<? super T, ? extends K> keyMapper, 
      Function<? super T, ? extends V> valueMapper, 
      Comparator<? super K> keyComparator, 
      Comparator<? super V> valueComparator) { 
     return null; 
    } 

    public static void main(String[] args) {  
     Map<Integer, String> case1 = Stream.of(1, 2, 3). 
       collect(comparatorOrdering(t -> t, t -> String.valueOf(t), 
         Comparator.naturalOrder(), Comparator.naturalOrder())); 
     Map<Integer, String> case2 = Stream.of(1, 2, 3). 
       collect(comparatorOrdering(Function.identity(), t -> String.valueOf(t), 
         Comparator.naturalOrder(), Comparator.naturalOrder())); 
    } 
} 

Caso 1 compila bene, ma caso 2 non riesce con:

method comparatorOrdering in class Testcase cannot be applied to given types; 
       collect(comparatorOrdering(Function.identity(), t -> String.valueOf(t), 
    required: Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V> 
    found: Function<Object,Object>,(t)->Strin[...]Of(t),Comparator<T#2>,Comparator<T#3> 
    reason: inferred type does not conform to upper bound(s) 
    inferred: Object 
    upper bound(s): Comparable<? super T#4>,T#4,Object 
    where T#1,A,R,K,V,T#2,T#3,T#4 are type-variables: 
    T#1 extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>) 
    A extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>) 
    R extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>) 
    K extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>) 
    V extends Object declared in method <T#1,A,R,K,V>comparatorOrdering(Function<? super T#1,? extends K>,Function<? super T#1,? extends V>,Comparator<? super K>,Comparator<? super V>) 
    T#2 extends Comparable<? super T#2> 
    T#3 extends Comparable<? super T#3> 
    T#4 extends Comparable<? super T#4> declared in method <T#4>naturalOrder() 

Il mio ambiente è Windows 10, 64-bit, Oracle JDK 1.8.0_92 costruire-B14.

UPDATE: Visto che questo è compilato in ecj, ho una domanda di follow-up: Si tratta di un bug in javac? Che cosa ha da dire il JLS su questo caso?

+0

Puoi condividere alcuni dettagli sul tuo ambiente? Questo compila bene sul mio. – Mureinik

+3

Posso riprodurlo con Java 1.8.0_92. (OpenJDK) –

+0

@StephenC quale build di 1.8.0_92? Sto usando 1.8.0_92-b14 e non posso riprodurre. – Mureinik

risposta

4

Ecj è in grado di infere l'argomento di tipo (?) Corretto (Intero) per abbinare i vincoli. Javac per qualche ragione ha un risultato diverso.

Questa non è la prima volta che javac/ecj si comporta in modo diverso per l'inferenza dei parametri di tipo.

In tal caso, è possibile fornire a javac un suggerimento con Function. < Numero intero > identity() per renderlo compilabile con javac.

Per la differenza tra Function.identity() e t-> t:

  • Function.identity() è la funzione < T, T >
  • t-> t in questo caso è Funzione < ? super intero,? extends Integer >

Quindi t-> t è più flessibile nei metodi a cui può corrispondere.

+1

compila bene con 'javac 1.8.0_60' dopo aver specificato il tipo Intero – Saravana

+0

Ho aggiunto una domanda di follow-up. – Gili