当前位置: 首页 > 知识库问答 >
问题:

@FunctionalInterface可以有默认方法吗?

左丘弘致
2023-03-14

为什么我不能用默认的方法实现创建一个@functionInterface

@FunctionalInterface
public interface MyInterface {
    default boolean authorize(String value) {
        return true;
    }
}

共有3个答案

张可人
2023-03-14

这是因为@functioninterface可以有默认方法,可以有多少种。例如,考虑java。util。功能接口。它包含两种默认方法:compose以及。但应该只有一种非默认方法。否则,编译器如何知道哪些默认方法应该映射到lambda?

龚奕
2023-03-14

功能接口是一个具有单一抽象方法的接口。定义函数接口的全部目的是通过lambda表达式实现单个抽象方法,该表达式将有效覆盖该方法,从而使为其提供默认实现变得毫无意义。

拥有一个完全由default方法组成的接口会引发多个问题。有一个技术问题是,当有多个default方法时,编译器无法决定lambda表达式要实现哪个方法,并且存在一个语义问题,即完全由default方法组成的接口不是抽象。您无法实例化此默认行为,因为您无法实例化接口s并迫使程序员创建具体类以调用默认行为,由于接口是无状态的,因此可以由单例提供:

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

请注意,如果需要,您可以让接口扩展功能接口并提供默认方法。尽管如此,如果这导致创建一个没有抽象方法的接口,我会质疑设计。您可以与关于使用default方法的标记接口的讨论进行比较。如果子接口将具有与功能接口不同的抽象方法,那就另当别论了。这可能有真正的用例,但这些子接口还将演示为什么它们不应该与功能基础接口混合,因为lambda表达式将始终实现抽象方法。

顾正初
2023-03-14

功能接口中可以有默认方法,但其契约要求您提供一个抽象方法(或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);
}

不编译。

 类似资料:
  • 问题内容: 为什么我不能使用默认方法实现创建一个? 问题答案: 您可以在功能接口中使用默认方法,但是其约定要求您提供一个单一的抽象方法(或SAM)。由于默认方法具有实现,因此它不是抽象的。 从概念上讲,功能接口仅具有一种抽象方法。由于默认方法具有实现,因此它们不是抽象的。 和 如果使用此注释类型对类型进行注释,则编译器需要生成错误消息,除非: 该类型是接口类型,而不是注释类型,枚举或类。 带注释的

  • 所以,我一直在读C++标准,找到了[defns.Undefined](3.27,在我正在读的C++17草案中,请注意,当我在这里引用C++17时,我在其他标准中发现了类似的措辞)--这是未定义行为的定义。我注意到这样的措辞(强调我的): 注意:当本国际标准省略任何行为的明确定义时,或者当程序使用错误的构造或错误的数据时,可能会出现未定义的行为 现在,想想看,这有点道理。这有点像是说,如果标准没有给

  • 我现在正在学习,我被赋予了一个简单的(我以为是这样的)任务。我必须让这段代码工作(我不能修改它): 我认为MousePressListener应该是FunctionalInterface,但它不能扩展MouseListener。有没有办法解决这个问题,或者我是从坏的方面来处理它?

  • 主要内容:1 Java8 默认方法的介绍,2 Java8 默认方法的案例1 Java8 默认方法的介绍 Java提供了一种在接口内部创建默认方法的功能。在接口内部定义并带有默认标记的方法称为默认方法。这些方法是非抽象方法。 2 Java8 默认方法的案例 在下面的示例中,Sayable是一个功能接口,其中包含默认值和抽象方法。默认方法的概念用于定义具有默认实现的方法。您还可以覆盖默认方法,以为该方法提供更具体的实现。 输出结果为:  

  • 问题内容: 我们正在使用 PropertyPlaceholderConfigurer 在我们的Spring配置中使用java属性(此处有详细信息) 例如: 我们想添加一个附加属性,但是要有一个分布式系统,现有实例都可以使用默认值。通过在Spring config中为未定义覆盖属性值的默认值指示默认值,是否有办法避免更新所有属性文件? 问题答案: 您是否正在寻找此处记录的PropertyOverri

  • 问题内容: 我可以在AngularJS中设置路由参数的默认值吗?有没有有办法,并通过相同的途径来处理? 我希望重构现有的代码,如下所示: 它可以工作,但不是很优雅。有没有更好的办法 ? 问题答案: 不允许使用路由参数的默认值。 但是(中的)路由 不应具有默认参数。 资源可以具有默认参数。 在如果你想使用一个可选的参数的路线,这实际上是两个不同的路线。 为什么? 路线应该很简单 路由不允许参数的正则