Java 8中功能接口的定义

Dee*_*mar 7 java java-8 functional-interface

Java 8中功能接口的定义说:

功能性接口被定义为具有任何接口恰好 一个明确声明的抽象方法.(鉴定是必要的,因为接口可能具有非抽象的默认方法.)这就是为什么功能接口曾经被称为单抽象 方法(SAM)接口,这个术语有时仍然可见.

那么我们怎么会这样:

List<Double> temperature = 
   new ArrayList<Double>(Arrays.asList(new Double[] { 20.0, 22.0, 22.5 }));
temperature.sort((a, b) -> a > b ? -1 : 1);
Run Code Online (Sandbox Code Playgroud)

由于sort方法List是:

default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }
Run Code Online (Sandbox Code Playgroud)

lambda表达式说:

Lambda表达式应该可以分配给功能接口

Comparator接口有两个抽象方法,它们是compareequals用它们注释的@FunctionalInterface.这是否违反了只有一个抽象方法的功能接口的定义?

Tun*_*aki 14

确实,该Comparator接口有2个抽象方法.但其中一个是equals,它会覆盖类中equals定义的方法Object,并且此方法不计算在内.

来自@FunctionalInterface:

如果接口声明覆盖其中一个公共方法的抽象方法java.lang.Object,那么也不会计入接口的抽象方法计数,因为接口的任何实现都将具有来自java.lang.Object其他地方的实现.

因此,这使得Comparator界面成为功能方法所在的功能界面compare(o1, o2).

lambda表达式(a, b) -> a > b ? -1 : 1符合该契约:它声明了2个参数并返回一个int.

  • 如果我们这样做,应该强调的是,这个定义与问题引用中的声明不同,不需要明确声明抽象方法. (2认同)
  • 并且应该提到的是,虽然这个lambda表达式符合函数的*shape*,因此被编译器接受,但它违反了`Comparator`接口的*contract*并且可能在运行时导致任意混乱...... (2认同)