Spring注解之@FunctionalInterface详解(函数式接口)

 更新时间:2025年09月03日 15:05:54   作者:minh_coo  
@FunctionalInterface是Java8注解,标识仅含一个抽象方法的函数式接口,支持Lambda,编译检查确保符合定义,提升可读性,非强制,继承方法需注意计数,Object方法不计入

@FunctionalInterface函数式接口

@FunctionalInterface 是Java 8引入的注解,表明一个接口是函数式接口。函数式接口,即只包含一个抽象方法的接口。

目的就是告诉别人,这个接口就一个核心抽象方法,是用来写Lambda 表达式的。

1、函数式接口定义

  • 是一个接口;
  • 有且仅有一个抽象方法;
  • 可以包含任意数量的默认方法(default方法);
  • 可以包含任意数量的静态方法(static方法);
  • 可以包含从java.lang.Object类继承来的公共方法(如toString(), equals(), hashCode()),这些方法不被计入抽象方法的数量。

如下是一个合格的函数式接口:

@FunctionalInterface
interface ValidFI {
    void execute();
    boolean equals(Object obj); // 覆盖 Object 的方法,不计入
    String toString();        // 覆盖 Object 的方法,不计入
    static void helper() {}   // 静态方法,允许
    default void log() {}     // 默认方法,允许
}

2、作用

(1)编译时检查

当给一个接口添加了 @FunctionalInterface 注解时,编译器会强制检查该接口是否严格符合函数式接口的定义(即只有一个抽象方法)。

如果接口不符合条件(例如没有抽象方法、或者有多个抽象方法),编译器会立即报错。这有助于在开发阶段就发现错误,避免运行时出现问题

(2)提升代码可读性,明确意图

在代码中使用 @FunctionalInterface 可以清晰地告诉阅读者:“这个接口是设计用来作为函数式接口使用的,它只有一个核心抽象方法,目的是为了支持 Lambda 表达式或方法引用。”

它提升了代码的可读性和可维护性,是一种良好的文档实践。

注意:

  • @FunctionalInterface 不是强制性的。即使一个接口没有添加 @FunctionalInterface 注解,只要它事实上只包含一个抽象方法,它仍然是一个函数式接口。Lambda 表达式和方法引用仍然可以用在这个接口上。
  • 继承的抽象方法会被记入。如果一个接口继承另一个接口,而子接口添加了新的抽象方法,这时在子接口使用@FunctionalInterface,编译器会报错。
  • Object 类方法不计入抽象方法,不影响函数式接口定义。

3、代码示例

// 1. 定义函数式接口
@FunctionalInterface
interface TextTransformer {
    // 单一抽象方法 (函数式接口核心)
    String transform(String input);

    // 默认方法 1
    default String transformToUpper(String input) {
        return transform(input).toUpperCase();
    }

    // 默认方法 2
    default void printTransformation(String input) {
        String result = transform(input);
        System.out.println("原始文本: " + input);
        System.out.println("转换结果: " + result);
    }

    // 静态方法 (不影响函数式接口性质)
    static void printInfo() {
        System.out.println("这是一个文本转换器接口");
    }
}

// 2. 传统实现类
class ReverseTransformer implements TextTransformer {
    @Override
    public String transform(String input) {
        return new StringBuilder(input).reverse().toString();
    }
}

public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        // 3. 使用传统实现类
        TextTransformer reverser = new ReverseTransformer();
        System.out.println("反转文本: " + reverser.transform("Hello"));
        reverser.printTransformation("Java");
        System.out.println("大写反转: " + reverser.transformToUpper("World"));
        
        // 调用接口静态方法
        TextTransformer.printInfo();
        System.out.println("-------------------");
        
        // 4. 使用Lambda表达式实现函数式接口
        TextTransformer doubler = input -> input + " " + input;
        doubler.printTransformation("Repeat");
        System.out.println("大写重复: " + doubler.transformToUpper("Twice"));
        System.out.println("-------------------");
        
        // 5. 使用方法引用实现函数式接口
        TextTransformer trimmer = String::trim;  // 等价于 input -> input.trim()
        trimmer.printTransformation("   Trim this text   ");
        System.out.println("-------------------");
        
        // 6. 作为方法参数传递
        processText("Functional", input -> "[" + input + "]");
    }
    
    // 方法接受函数式接口作为参数
    public static void processText(String text, TextTransformer transformer) {
        System.out.println("处理结果: " + transformer.transform(text));
        
        // 使用接口的默认方法
        transformer.printTransformation(text);
        
        // 链式调用默认方法
        System.out.println("链式转换: " + 
            transformer.transformToUpper(text).replace("A", "@"));
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • OpenFeign实现携带请求头方案详细介绍

    OpenFeign实现携带请求头方案详细介绍

    这篇文章主要介绍了OpenFeign实现携带请求头方案,在通过 ​​OpenFeign​​​进行服务调用的过程中,我们需要将用户的​​user-token​​​、​​lang​​等信息放入请求header中。在分布式系统中,往往一个业务接口内部会发生多次RPC调用
    2022-11-11
  • java list 比较详解及实例

    java list 比较详解及实例

    这篇文章主要介绍了java list 比较详解及实例的相关资料,需要的朋友可以参考下
    2017-05-05
  • Java面试题及答案集锦(基础题122道,代码题19道)

    Java面试题及答案集锦(基础题122道,代码题19道)

    本文是小编收集整理的关于java基础面试题及答案集锦,基础题目有122道,代码题目有19道,非常不错,值得收藏,需要的朋友参考下
    2017-01-01
  • SpringBoot自定义maven-plugin插件整合asm代码插桩

    SpringBoot自定义maven-plugin插件整合asm代码插桩

    本文主要介绍了SpringBoot自定义maven-plugin插件整合asm代码插桩,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • SpringBoot中的异常处理与参数校验的方法实现

    SpringBoot中的异常处理与参数校验的方法实现

    这篇文章主要介绍了SpringBoot中的异常处理与参数校验的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • Java生成读取条形码和二维码的简单示例

    Java生成读取条形码和二维码的简单示例

    条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的规则排列,用来表示一组信息的图形标识符,而二维码大家应该都很熟悉了,这篇文章主要给大家介绍了关于Java生成读取条形码和二维码的相关资料,需要的朋友可以参考下
    2021-07-07
  • Mybatis的resultMap返回map问题

    Mybatis的resultMap返回map问题

    这篇文章主要介绍了Mybatis的resultMap返回map问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java 对象深拷贝工具类的实现

    Java 对象深拷贝工具类的实现

    本文主要介绍了Java 对象深拷贝工具类的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • springBoot动态加载jar及如何将类注册到IOC

    springBoot动态加载jar及如何将类注册到IOC

    在SpringBoot项目中动态加载jar文件并将其类注册到IOC容器是一种高级应用方式,,这种方法为SpringBoot项目提供了更灵活的扩展能力,使得项目可以在不修改原有代码的基础上增加新的功能模块,感兴趣的朋友一起看看吧
    2024-11-11
  • 详解基于Spring Data的领域事件发布

    详解基于Spring Data的领域事件发布

    这篇文章主要介绍了详解基于Spring Data的领域事件发布,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04

最新评论