2016-06-26 16 views
8

Odpowiedzi znalezione pod Java 8 lambdas, Function.identity() or t->t wydają się sugerować, że Function.identity() jest prawie zawsze równoważne t -> t. Jednak w teście wymienionym poniżej zastąpienie t -> t przez Function.identity() powoduje błąd kompilatora. Dlaczego?Dlaczego funkcja rektyfikacji Function.identity() nie działa, ale t -> t nie?

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())); 
    } 
} 

Przypadek 1 kompiluje dobrze, ale nie powiedzie się z case 2:

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() 

My środowisku Windows 10, 64-bitowy, Oracle JDK zbudować 1.8.0_92-B14.

AKTUALIZACJA: Widząc, jak to kompiluje pod ecj, mam następującą odpowiedź: Czy to błąd w javac? Co JLS ma do powiedzenia na temat tej sprawy?

+0

Czy możesz podzielić się kilkoma szczegółami na temat swojego środowiska? Kompiluje to dobrze na moim. – Mureinik

+3

Mogę odtworzyć to z Java 1.8.0_92. (OpenJDK) –

+0

@StephenC, która wersja 1.8.0_92? Używam 1.8.0_92-b14 i nie mogę się reprodukować. – Mureinik

Odpowiedz

4

Ecj jest w stanie wnioskować poprawny (?) Typ argumentu (Integer), aby dopasować ograniczenia. Javac z jakiegoś powodu osiąga inny rezultat.

To nie pierwszy raz, gdy javac/ecj zachowuje się inaczej w zależności od parametrów typu.

W takim przypadku możesz podać javac podpowiedź z funkcją. <Integer> identity(), aby umożliwić kompilację za pomocą javac.

Rozróżnienie pomiędzy Function.identity() i t-> t:

  • Function.identity() to funkcja < T T >
  • t-> t w tym przypadku jest to funkcja < ? super Integer,? extegen Integer >

Tak więc t-> t jest bardziej elastyczny w metodach, do których może pasować.

+1

kompiluje się dobrze z 'javac 1.8.0_60' po określeniu typu Integer – Saravana

+0

Dodałem kolejne pytanie. – Gili