2016-06-26 3 views
8

Java 8 lambdas, Function.identity() or t->t에있는 답변은 Function.identity()이 거의 항상 t -> t과 동일하다는 것을 암시하는 것으로 보입니다. 그러나 아래에 표시된 테스트 케이스에서 t -> tFunction.identity()으로 바꾸면 컴파일러 오류가 발생합니다. 왜 그런가요? 윈도우 10, 64 비트, 오라클 JDK는 1.8.0_92-B14를 구축입니다Function.identity()가 형식화를 중단하지만 t -> t가 아닌 이유는 무엇입니까?

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

내 환경 :

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

사례 1은 잘 컴파일하지만, 케이스 (2)와 함께 실패합니다.

업데이트 : : ecj에서 컴파일 된 것을 볼 수 있는데, 후속 질문이 있습니다.이 버그는 javac입니까? 이 사건에 대해 JLS는 뭐라고해야합니까?

+0

env에 대한 몇 가지 정보를 공유 할 수 있습니까? 이것은 내 문제를 잘 해결합니다. – Mureinik

+3

Java 1.8.0_92에서이를 재현 할 수 있습니다. (OpenJDK) –

+0

@StephenC 빌드 1.8.0_92? 1.8.0_92-b14를 사용 중이며 재현 할 수 없습니다. – Mureinik

답변

4

Ecj는 올바른 (?) 형식 인수 (Integer)를 제한 조건에 일치시킬 수 있습니다. Javac은 어떤 이유로 든 다른 결과를 얻습니다.

처음 javac/ecj가 형식 매개 변수의 유추에서 다르게 동작합니다.

그런 경우 javac에 기능을 제공 할 수 있습니다. <Integer> javac로 컴파일 할 수 있도록하기 위해 identity(). Function.identity() 및 T-> t 간의 차이

:

  • Function.identity()는 T, T >
  • 그런 경우 함수 <>는 t T- 기능이다 < ? 슈퍼 정수,? 정수 >

그래서 t-> t는 일치 할 수있는 방법에서 더 유연합니다.

+1

타입 지정 후 'javac 1.8.0_60'으로 잘 컴파일됩니다. – Saravana

+0

후속 질문을 추가했습니다. – Gili