为什么在 Java 8 中使用 @FunctionalInterface 注解

use*_*985 9 java-8 functional-interface

如果我们的接口中只有一个抽象方法,那么默认情况下它是函数式接口。任何人都可以解释@FunctionalInterface 注释带来的额外优势吗?

我知道如果我们添加@FunctionalAnnotation,它不会允许有人在接口中添加另一个抽象方法,因为它会给出编译错误,但我的意思是即使你不使用@FucntionalInterface注解,那么还有,如果有人会添加另一个抽象方法,它会破坏代码中所有现有的 lambda 表达式,编译器会抱怨。

例如:

如果我有以下界面:

public interface User {

    Integer fetchData(Integer userId);
}
Run Code Online (Sandbox Code Playgroud)

具有以下实现:

public class UserImpl implements User{

    @Override
    public Integer fetchData(Integer userId) {
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

和以下用法:

公共类 TestFunctionalInterface {

public static void main(String[] args) {
    User user = a -> a*2;
    System.out.println("FetchedData:"+user.fetchData(2));
}
Run Code Online (Sandbox Code Playgroud)

}

现在,如果我尝试在界面中添加另一个方法,如下所示:

public interface User {

    Integer fetchData(Integer userId);

    Integer fetchLoginDetails(Integer userId);

}
Run Code Online (Sandbox Code Playgroud)

编译器在下面的代码中抱怨:

public class TestFunctionalInterface {

    public static void main(String[] args) {
        User user = a -> a*2;
        System.out.println("FetchedData:"+user.fetchData(2));
    }

}
Run Code Online (Sandbox Code Playgroud)

在线用户 user = a -> a*2;

带有消息“此表达式的目标类型必须是功能接口”。

小智 5

如果不同的模块正在使用该接口,则不会发生编译错误,例如,如果该接口通过依赖项可用。使用您的模块的人可以安全地在 lambda 中使用该函数,而不必担心以后的更新会破坏他们的代码。


mar*_*tow 5

功能接口只能有一个抽象方法。如果您有两个抽象方法,那么您的接口将不再起作用。

如果您有一种抽象方法,则可以使用 lambda 表达式。

如果您看到 @FunctionalInterface 注释,您就知道不应添加任何新方法,因为它会破坏设计。

如果向任何 Java 接口添加新的抽象方法,无论如何它都会破坏代码,因为您需要为具体类提供实现


Arn*_*lec 2

保护接口的主要优点@FunctionalInterface是使用 lambda 实例化它们。

Lambda 声明只能声明一个代码块,因此如果您的接口没有保护,并且有些代码会添加抽象方法,那么您的 Lambda 就不再有意义......

这就是为什么强烈建议不要使用 lambda 实现一些隐式函数接口。

因此,如果您想通过 lambda 方式实现此接口,我鼓励您添加 sa security. 如果你不想要这种实现,或者你的界面会改变或者有夜间改变的风险,那么就不要这样做。