2017-04-22 119 views
1

文件GenericInterface.java:Java如何在通用接口的泛型方法中捕獲類型變量?

import java.lang.Comparable; 
import java.util.function.Function; 

public class GenericInterface { 
} 

interface Comparator<T> { 
    int compare(T o1, T o2); 

    static <T, U extends Comparable<?>> //comment out this line 
    //static <T, U extends Comparable<? super U>> //and uncomment this line to pass compiling 
    Comparator<T> Comparing(Function<? super T, ? extends U> mapper) { 
    return new Comparator<T>() { 
     @Override 
     public int compare(T o1, T o2) { 
     return mapper.apply(o1).compareTo(mapper.apply(o2)); 
     } 
    }; 
    } 

    //... 
} 

然後通過javac GenericInterface.java -Xdiags:verbose與JDK 1.8編譯它,從而導致出現以下錯誤:

GenericInterface.java:16: error: method compareTo in interface 
Comparable<T#2> cannot be applied to given types; 
     return mapper.apply(o1).compareTo(mapper.apply(o2)); 
          ^
    required: CAP#1 
    found: CAP#2 
    reason: argument mismatch; U cannot be converted to CAP#1 
    where U,T#1,T#2 are type-variables: 
    U extends Comparable<?> declared in method <T#1,U>Comparing(Function<? super T#1,? extends U>) 
    T#1 extends Object declared in method <T#1,U>Comparing(Function<? super T#1,? extends U>) 
    T#2 extends Object declared in interface Comparable 
    where CAP#1,CAP#2 are fresh type-variables: 
    CAP#1 extends Object from capture of ? 
    CAP#2 extends U from capture of ? extends U 
1 error 

我可以通過修改這一行編譯

static <T, U extends Comparable<?>> 

至此

static <T, U extends Comparable<? super U>> 

但我不知道爲什麼:

CAP#1 extends Object from capture of ? 
CAP#2 extends U from capture of ? extends U 

應該不封頂#1和#CAP 2是U extends Comparable<?>?任何人都可以告訴我,Java是如何在像上面那樣的通用接口的泛型方法中捕獲類型變量的?

回答

1

如果您有U extends Comparable<?>compareTo函數將爲int compareTo(? o)?是瘋狂的,所以唯一有效的論據是null

相反,如果您有U extends Comparable<? super U>您將有int compareTo(? super U o),它將採取任何U

舉例來說,如果我是宣佈

class Thing extends Comparable<String> { 
    int compareTo(String o) { return 0; } 
} 

然後調用

Comparator.<Date,Thing>Comparing(myFunc) 

我們有一個問題Thing.compareTo(String)是帶一個Thing說法。

(打定符號,很明顯。)

+0

爲什麼 「?是野生所以唯一有效的參數爲空」,因爲 「在的compareTo功能將是int的compareTo(?O)」?爲什麼不是有效的參數是「對象」? – Robert

+1

'?'可以是任何東西。它沒有在本地定義。如果在提供的對象中有一個「String」(比如在我的例子中),並提供了一個不可能正確的「Thing」。 –