2017-04-12 70 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修饰符的接口方法是隐式抽象的,所以其主体由分号,而不是一个块表示它是允许的。 ,但不鼓励作为风格的问题,冗长地指定这种方法声明的抽象修饰符。“