@FunctionalInterfaces可以有默认方法吗?

mem*_*und 38 java java-8

为什么我不能@FunctionalInterface使用默认方法实现创建?

@FunctionalInterface
public interface MyInterface {
    default boolean authorize(String value) {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_* C. 45

您可以在功能界面中使用默认方法,但其合同要求您提供一个抽象方法(或SAM).由于默认方法具有实现,因此它不是抽象的.

从概念上讲,功能界面只有一种抽象方法.由于默认方法具有实现,因此它们不是抽象的.

如果使用此批注类型对类型进行批注,则编译器需要生成错误消息,除非:

类型是接口类型,而不是注释类型,枚举或类.

带注释的类型满足功能接口的要求.

在这里,您不满足功能接口的要求,因此您需要提供一个抽象方法.例如:

@FunctionalInterface
interface MyInterface {

    boolean authorize(int val);

    default boolean authorize(String value) {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您声明一个抽象方法覆盖Object类中的一个公共方法,则它不计算,因为此接口的任何实现都将通过至少Object类的方式实现这些方法.例如:

@FunctionalInterface
interface MyInterface {

    default boolean authorize(String value) {
        return true;
    }

    boolean equals(Object o);
}
Run Code Online (Sandbox Code Playgroud)

不编译.

  • @mjalil,除了“default”方法不能是“protected”或“final”。而且,正如已经说过的,来自像“Object”这样的具体类的方法优先于接口方法。 (2认同)

Hol*_*ger 12

功能接口是一个interface具有单一的抽象方法.定义功能接口的全部目的是通过lambda表达式实现单个抽象方法,这将有效地覆盖该方法,这使得default为它提供实现毫无意义.

拥有一个interface完全由default方法提出了多个问题.存在技术问题,当存在多个default方法并且存在interface完全由default方法组成的语义问题时,编译器不能决定lambda表达式实现哪个方法abstract.您无法实例化此默认行为,因为您无法实例化interfaces并强制程序员创建具体类只是为了调用默认行为,因为接口是无状态的,可以由单例提供:

@FunctionalInterface
public interface MyInterface {
    static MyInterface DEFAULT = s->true;
    boolean authorize(String value);
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果需要,您可以使用扩展功能接口的接口并提供默认方法.尽管如此,如果这导致创建一个interface没有抽象方法,我会质疑设计.您可以与有关标记接口和default方法讨论进行比较.如果子接口将具有与功能接口不同的抽象方法,那么它就是一个不同的故事.可能存在实际用例,但这些子接口还将说明为什么它们不应与函数库混合,interface因为lambda表达式将始终实现抽象方法.


Tag*_*eev 7

那是因为@FunctionalInterface可以有你想要的默认方法.例如,考虑java.util.Function接口.它包含两个默认方法:composeandThen.但是应该只有一个非默认方法.否则编译器如何知道哪些默认方法应该映射到lambda?