Java 8中“功能接口”的精确定义


73

最近,我开始探索Java 8,但我不太了解Java的lambda表达式实现所必需的“功能接口”的概念。Java中有关于lambda函数的相当全面的指南,但是我陷入了为功能接口的概念定义的章节中。定义如下:

更准确地说,功能接口定义为具有一种抽象方法的任何接口。

然后他继续进行示例,其中一个是Comparator接口:

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
} 

我能够测试是否可以使用lambda函数代替Comparator参数,并且它可以工作(即Collections.sort(list, (a, b) -> a-b))。

但是在Comparator界面中,compareequals方法都是抽象的,这意味着它具有两个抽象方法。那么,如果定义要求一个接口仅具有一个抽象方法,那么这将如何工作?我在这里想念什么?

Answers:


66

同一页面上,您链接到

接口Comparator之所以有用,是因为尽管它声明了两个抽象方法,但其中一个(等于)具有与Object中的公共方法相对应的签名。接口总是声明与Object的公共方法相对应的抽象方法,但它们通常是隐式的。无论隐式还是显式声明,此类方法均不包括在内。

我真的不能说得更好。


1
但是,既然我们不能拥有一个原始的extends东西,因为它们不是对象,而且因为它是用Java创建的任何类extends Object,那么拥有它的目的是boolean equals(Object obj);什么?无论如何,任何实现都可以访问该方法。纯粹是要强调以下事实:对于某些Comparable实现而言,此方法非常适合对其进行修改?
payne

11

@FunctionalInterface页面中给出了另一种解释:

从概念上讲,功能接口仅具有一种抽象方法。由于默认方法具有实现,因此它们不是抽象的。如果接口声明的抽象方法覆盖的公共方法之一java.lang.Object,则该方法也不会计入接口的抽象方法计数,因为该接口的任何实现都将具有来自java.lang.Object其他地方的实现。

您可以测试哪个接口是正确的功能接口使用 @FunctionalInterface

例如:

  • 这有效

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals(Object o);
    
    }
    
  • 这会产生一个错误:

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals();
    
    }
    

    接口FunctionalInterf中的多个非覆盖抽象方法


3

问:但是在Comparator界面中,compare()和equals()方法都是抽象的,这意味着它有两个抽象方法。那么,如果定义要求一个接口仅具有一个抽象方法,那么这将如何工作?我在这里想念什么?

一种。

功能接口可以指定Object定义的任何公共方法,例如equals(),而不会影响其“功能接口”状态。公共对象方法被视为功能接口的隐式成员,因为它们由功能接口的实例自动实现。


您是否有报价来源的链接?谢谢!
uvsmtid


0

一个功能接口只有一个抽象方法,但可以有多个默认和静态方法。

由于默认方法不是抽象的,因此您可以随意向功能接口添加任意数量的默认方法。

@FunctionalInterface
public interface MyFuctionalInterface 
{
public void perform();

default void perform1(){
//Method body
}

default void perform2(){
//Method body
}
}

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

比较器是一个功能接口,即使它声明了两个抽象方法。因为这些抽象方法“ equals()”之一具有与Object类中的公共方法相同的签名。例如,下面的接口是有效的功能接口。

@FunctionalInterface
    public interface MyFuctionalInterface 
    {
    public void perform();
 
    @Override
    public String toString();                //Overridden from Object class
 
    @Override
    public boolean equals(Object obj);        //Overridden from Object class
    }

-1

Java文档说:

请注意,不重写Object.equals(Object)始终是安全的。但是,在某些情况下,重写此方法可以通过允许程序确定两个不同的比较器施加相同的顺序来提高性能。

也许比较器很特别?也许,即使它是一个接口,也可以通过某种方式实现equals()该调用的默认实现compare()?从算法上讲,这是微不足道的。

我认为接口中声明的所有方法都是抽象的(即没有默认实现)。但是也许我想念一些东西。


2
Comparator没什么特别的 创建新Comparator对象时,它将继承自Object,包括具体equals方法。您关于接口中声明的所有方法都是抽象的评论通常不再适用,但对于中的equals方法则适用Comparator。我对Mark Peters答案的评论进一步说明了这一点,或者在Lambda常见问题解答页面上查看语法评论lambdafaq.org/what-is-a-functional-interface
Maurice Naftalin 2013年

-1

定义:

如果一个接口仅包含一个抽象方法,则这种类型的接口称为功能接口。

用法:

  1. 一旦我们编写Lambda表达式“->”以调用其功能,则在这种情况下,我们需要功能接口。
  2. 我们可以使用功能接口引用来引用Lambda表达式。
  3. 在功能接口内部,我们可以有一个抽象方法和n个默认/静态方法。

关于继承的功能接口:

如果接口扩展了Functional接口,并且子接口不包含任何抽象方法,则该子接口也被视为Functional Interface。

功能接口对于Java来说并不是新手,它已经在以下接口API中使用:

  1. Runnable:仅包含run()方法。
  2. Callable:仅包含call()方法。
  3. 可比较:仅包含compareTo()方法。

-1

在Java 8之前,接口只能声明一个或多个方法,也称为抽象方法(没有实现的方法,只有签名)。从Java 8开始,接口还可以实现一个或多个方法(称为接口默认方法)和静态方法以及抽象方法的实现。接口默认方法标记为默认关键字。

所以问题是,什么是功能接口?具有单一抽象方法(SAM)的接口称为功能接口。

意思是 -

  1. 具有单一抽象方法的接口是功能接口
  2. 具有单个抽象方法和零个或多个默认方法以及零个或多个静态方法的接口也是有效的功能接口。

使用示例代码https://readtorakesh.com/functional-interface-java8/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.