2016-07-20 4 views
2

2 개체를 비교하는이 람다 식 :자바 8 람다 제네릭 비교 - 컴파일러 경고

:

warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type Comparable 
(Comparator) (final Object o1, final Object o2) -> ((Comparable) o1).compareTo(o2); 
where T is a type-variable: 
T extends Object declared in interface Comparable 

이 람다 식 2 개 T 객체를 비교 :

private static final Comparator NATURAL_ORDER_COMPARATOR1 = 
     (Comparator) (final Object o1, final Object o2) -> ((Comparable) o1).compareTo(o2); 

이 컴파일 경고 생산을

private final Comparator<T> NATURAL_ORDER_COMPARATOR2 = 
     (Comparator<T>) (final T o1, final T o2) -> ((Comparable<T>) o1).compareTo(o2); 

이 컴파일 경고를 생성합니다.

0 설명/의견
warning: [unchecked] unchecked cast 
(Comparator<T>) (final T o1, final T o2) -> ((Comparable<T>) o1).compareTo(o2); 
required: Comparable<T> 
found: T 
where T is a type-variable: 
T extends Object declared in class Tree01 

귀하의 해상도는 훨씬 당신은 모두 Comparable을 구현에도 불구하고, 당신이 IntegerString을 비교할 수있는 임의의 Comparable들과 비교할 수있는 Comparator를 정의 할 수 없습니다

답변

2

감사. 비교를 위해 Comparator.compare 메소드의 두 인수가 호환되어야하는 제한 조건을 공식화하려면 유형 변수가 필요합니다.

그러나 필드를 선언 할 때 유형 매개 변수를 사용할 수 없으므로 필드를 사용하여 그러한 일반형을 정의하는 것은 불가능합니다. 되고, 주어진 JRE와 함께,이 싱글 인스턴스를 생성하는 것을 알 수있는

Comparator<Integer> ci = naturalOrder(); 
Comparator<String> cs = naturalOrder(); 
// in the current version of Oracle's JRE/OpenJDK this will print true 
System.out.println(ci==(Object)cs); 

처럼

public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { 
    return (a,b) -> a.compareTo(b); 
} 

또는

public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { 
    return Comparable::compareTo; 
} 

어떤 당신이 사용할 수 있습니다 그것은 단지 공장의 방법을 사용하여 작동 성능 측면에서 필드에 저장된 비교기와 동등합니다. 그러나 제네릭의 관점에서 볼 때 호환되지 않는 유형이 있으므로 비교기를 보유하는 단일 변수를 정의하고 동시에 IntegerString과 호환되는 것은 불가능합니다.

형 매개 변수 필드를 선언하는 불가능 제네릭 도입 또는 시도와 같은 목적을 다루는 새로운 방법 Comparator.naturalOrder()이, 방법보다는 필드 이유 때 Collections.EMPTY_LISTCollections.emptyList() 보완있어 이유입니다.

+0

고맙습니다. 홀거. 그것은 의미 있고 잘 설명됩니다 (대통령 프로그래머). – Felix