【发布时间】:2015-07-21 19:16:54
【问题描述】:
为什么我不能使用默认方法实现创建@FunctionalInterface?
@FunctionalInterface
public interface MyInterface {
default boolean authorize(String value) {
return true;
}
}
【问题讨论】:
为什么我不能使用默认方法实现创建@FunctionalInterface?
@FunctionalInterface
public interface MyInterface {
default boolean authorize(String value) {
return true;
}
}
【问题讨论】:
您可以在 functional interface 中使用默认方法,但它的合同要求您提供一个抽象方法(或 SAM)。由于默认方法有一个实现,所以它不是抽象的。
从概念上讲,函数式接口只有一个抽象方法。 由于默认方法有一个实现,它们不是抽象的。
和
如果一个类型被这个注解类型注解,编译器是 需要生成错误消息,除非:
该类型是接口类型而不是注解类型、枚举或 类。
带注释的类型满足函数式的要求 界面。
这里不满足函数式接口的要求,需要提供一个抽象方法。例如:
@FunctionalInterface
interface MyInterface {
boolean authorize(int val);
default boolean authorize(String value) {
return true;
}
}
请注意,如果您声明一个抽象方法覆盖了 Object 类中的公共方法之一,则它不计算在内,因为此接口的任何实现都将至少通过 Object 的类来实现这些方法。例如:
@FunctionalInterface
interface MyInterface {
default boolean authorize(String value) {
return true;
}
boolean equals(Object o);
}
不编译。
【讨论】:
java.lang.Object 中声明的方法匹配的抽象方法”。重要的一点是,具体类中的 声明 具有优先权,即使子类使用 abstract 方法覆盖它也是如此。非interface 类的abstract 方法仍然优先于interface 方法,即使后者不是abstract。
java.lang.Object 就像一个带有一些 default 方法的接口
default 方法不能是protected 也不能是final。而且,正如已经说过的,来自像Object 这样的具体类的方法优先于接口方法。
功能接口是一个interface,具有一个抽象方法。定义功能接口的全部目的是通过 lambda 表达式实现单个抽象方法,这将有效地覆盖该方法,这使得为其提供 default 实现毫无意义。
拥有一个完全由default 方法组成的interface 会引发多个问题。当存在多个 default 方法时,编译器无法为 lambda 表达式决定实现哪个方法,并且存在完全由 default 方法组成的 interface 不是 @987654330 的语义问题@。您无法实例化此默认行为,因为您无法实例化 interfaces 并且强制程序员创建具体类只是为了调用默认行为,由于接口是无状态的,因此可以由单例提供:
@FunctionalInterface
public interface MyInterface {
static MyInterface DEFAULT = s->true;
boolean authorize(String value);
}
请注意,如果需要,您可以让接口扩展功能接口并提供默认方法。尽管如此,如果这导致创建一个没有抽象方法的interface,我会质疑这个设计。您可以与discussion about marker interfaces with default methods 进行比较。如果子接口与函数接口有不同的抽象方法,那就另当别论了。这可能有真正的用例,但这些子接口也将说明为什么它们不应该与函数基 interface 混合,因为 lambda 表达式将始终实现 abstract 方法。
【讨论】:
default 函数式接口中的方法并非毫无意义。它can be used 处理非抛出接口的检查异常,例如Supplier。
那是因为@FunctionalInterface 可以有默认方法,只要你想就可以。例如,考虑java.util.Function 接口。它包含两个默认方法:compose 和 andThen。但是应该只有一种非默认方法。否则编译器怎么知道你的哪些默认方法应该映射到 lambda?
【讨论】:
我只是想再补充几点。
我们可以在 FuntionalInterface 中拥有任意数量的 Abstract 方法。
我们还可以在 FuntionalInterface 中拥有任意数量的 Static 方法。
我们也可以声明一个抽象方法,覆盖对象类中的一个公共方法,但这个功能接口中还必须有一些其他自定义抽象方法,如下面的代码所示
@FunctionalInterface 公共接口 SAM { 公共无效 helloSam();
default void xyz() {
System.out.println("xyz");
}
static void abc() {
System.out.println("abc");
}
static void abc1() {
System.out.println("abc1");
}
default void xyz1() {
System.out.println("xyz1");
}
boolean equals(Object o);
}
【讨论】: