2017-04-12 76 views
-1

我下面一個約LAMBDA教程,在這裏我有這樣的接口:使用沒有定義它的方法?

@FunctionalInterface 
public interface Comparator<T> { 
public int compare(T t1, T t2); // What is this code??? 
public default Comparator<T> thenComparing(Comparator<T> cmp) { 
     return (p1, p2) -> compare(p1, p2) == 0 ? cmp.compare(p1, p2) : compare(p1, p2) ; 
    } 
public default Comparator<T> thenComparing(Function<T, Comparable> f) { 

     return thenComparing(comparing(f)) ; 
    } 

    public static <U> Comparator<U> comparing(Function<U, Comparable> f) { 

     return (p1, p2) -> f.apply(p1).compareTo(f.apply(p2)); 
    } 
} 

抽象方法比較(T1,T2)不被任何定義;然而,它在thenComparing(比較器cmp)方法中使用。這thenComparing方法然後用於下面的重載thenComparing()。但如果比較()沒有定義,這是什麼線的點:

return (p1, p2) -> compare(p1, p2) == 0 ? cmp.compare(p1, p2) : compare(p1, p2) ; 
+0

當你實際調用'thenComparing'時,'compare'總會被執行,因爲它只對一個實現類的具體實例有效...... –

+0

'compare(t1,t2)''不是一個抽象方法,它是一個接口中的方法聲明。小的區別真的但重要的部分是實現接口的類不能被構造,直到所有的接口方法(除了所有的抽象方法之外)都被提供了一個定義,[見這個問題](http://stackoverflow.com/questions/) 11715485 /什麼,是最差報關和清式的Java間)。 –

+0

@ KellyS.French - JLS指出接口中的非默認方法是一種抽象方法。看到我的答案。 –

回答

0

這裏是接口部分,是有關你的問題:

@FunctionalInterface 
public interface Comparator<T> { 
    public int compare(T t1, T t2); 

    public default Comparator<T> thenComparing(Comparator<T> cmp) { 
     return (p1, p2) -> compare(p1, p2) == 0 ? 
      cmp.compare(p1, p2) : compare(p1, p2) ; 
    } 

    // rest deleted ... 
} 

首先,​​3210聲明聲明摘要方法。任何具體的(即非抽象的,可實例化的)類都必須具有該方法的實現。 Java編譯器堅持這一點,JVM的類加載器也是如此。

方法thenComparing是一個默認實例方法。這意味着它將被稱爲this,它是指實施List的某個類的實例。但是,在前一段中,這意味着this對象必須具有this.compare(T, T)的實現。這是將在compare(p1, p2)調用中使用的方法。


1 - 的JLS狀態(9.4):「缺少缺省改性劑或static修飾符的接口方法是隱式抽象的,所以其主體由分號,而不是一個塊表示它是允許的。 ,但不鼓勵作爲風格的問題,冗長地指定這種方法聲明的抽象修飾符。「