@FunctionalInterface注解

@FunctionalInterface 是 Java 8 引入的一个注解,用于标识一个函数式接口(Functional Interface)。它的核心作用是明确接口的设计意图,并让编译器帮助检查接口是否符合函数式接口的规范。


1. 什么是函数式接口?

函数式接口是指只包含一个抽象方法(但可以包含多个默认方法或静态方法)的接口。它可以用作 Lambda 表达式方法引用 的目标类型。

常见的函数式接口

  • Runnablevoid run()
  • CallableV call()
  • Comparatorint compare(T a, T b)
  • Java 8 新增的 java.util.function 包中的接口(如 PredicateFunctionConsumer 等)

2. @FunctionalInterface 的作用

(1) 明确设计意图

  • 告诉其他开发者,这个接口是专门为 Lambda 表达式设计的。
  • 避免后续误添加新的抽象方法导致接口不再是函数式接口。

(2) 编译器检查

  • 如果接口被 @FunctionalInterface 标注,但不符合函数式接口的定义(如包含多个抽象方法),编译器会报错。

示例

@FunctionalInterface
interface MyFunctionalInterface {
    void doSomething(); // 只有一个抽象方法,合法
    // void doAnother(); // 如果取消注释,编译器会报错
}

3. 函数式接口的特点

  1. 只能有一个抽象方法(但可以有 defaultstatic 方法)。
  2. 可以包含 Object 类中的方法(如 toString()equals()),这些不算抽象方法。
  3. 可以用 Lambda 表达式或方法引用实现。

示例

@FunctionalInterface
interface Calculator {
    int calculate(int a, int b); // 唯一抽象方法

    default void print() {
        System.out.println("This is a default method.");
    }

    static void info() {
        System.out.println("This is a static method.");
    }
}

public class Main {
    public static void main(String[] args) {
        // Lambda 表达式实现
        Calculator add = (a, b) -> a + b;
        Calculator subtract = (a, b) -> a - b;

        System.out.println(add.calculate(5, 3));      // 输出 8
        System.out.println(subtract.calculate(5, 3)); // 输出 2

        add.print(); // 调用 default 方法
        Calculator.info(); // 调用 static 方法
    }
}

4. 为什么需要 @FunctionalInterface

  • 代码可读性:明确表示该接口用于 Lambda 表达式。
  • 防止错误:避免因误添加抽象方法导致接口无法用于 Lambda 表达式。
  • 兼容性:即使没有 @FunctionalInterface 注解,只要接口符合函数式接口的定义,仍然可以作为 Lambda 的目标类型。但加上注解更安全。

5. 自定义函数式接口

你可以自己定义函数式接口,例如:

@FunctionalInterface
interface StringFormatter {
    String format(String input);
}

public class Main {
    public static void main(String[] args) {
        StringFormatter toUpper = str -> str.toUpperCase();
        StringFormatter addExclamation = str -> str + "!";

        System.out.println(toUpper.format("hello"));       // 输出 "HELLO"
        System.out.println(addExclamation.format("Hi"));   // 输出 "Hi!"
    }
}

6. 常见内置函数式接口

Java 8 在 java.util.function 包中提供了许多内置函数式接口,例如:

  • Predicate<T>:接收参数,返回 booleantest(T t))。
  • Function<T, R>:接收参数,返回结果(apply(T t))。
  • Consumer<T>:接收参数,无返回值(accept(T t))。
  • Supplier<T>:无参数,返回结果(get())。
  • UnaryOperator<T>:接收并返回同类型参数(apply(T t))。

示例

import java.util.function.*;

public class Main {
    public static void main(String[] args) {
        Predicate<String> isEmpty = s -> s.isEmpty();
        System.out.println(isEmpty.test("")); // true

        Function<Integer, String> intToString = i -> "Number: " + i;
        System.out.println(intToString.apply(5)); // "Number: 5"

        Consumer<String> print = System.out::println;
        print.accept("Hello, Functional Interface!");
    }
}

总结

特性 说明
@FunctionalInterface 标识接口为函数式接口,编译器会检查是否符合规范
抽象方法限制 只能有一个抽象方法(可包含 defaultstatic 方法)
Lambda 适用 可用于 Lambda 表达式或方法引用
内置接口 Java 8 提供 PredicateFunctionConsumer 等常用接口
自定义 可以自己定义函数式接口

关键点

  • 函数式接口的核心是只有一个抽象方法
  • @FunctionalInterface 是可选的,但推荐使用以提高代码可读性和安全性。
  • Lambda 表达式让函数式接口的使用更加简洁。
posted @ 2025-07-18 19:19  扶她少女卡尔玛  阅读(463)  评论(0)    收藏  举报