@FunctionalInterface
的作用
@FunctionalInterface
是 Java 8 引入的一个注解,用来标识一个接口为 函数式接口。函数式接口是指仅包含一个抽象方法的接口(除了 Object
类的 public
方法以外)。
- 明确意图:通过这个注解,开发者可以明确地表示该接口是一个函数式接口。
- 编译时检查:如果被标注为
@FunctionalInterface
的接口不符合函数式接口的定义(包含多于一个抽象方法),编译器会报错。
函数式接口的定义
一个典型的函数式接口示例如下:
@FunctionalInterface
public interface MyFunctionalInterface {
void doSomething();
}
如果试图定义多个抽象方法,编译器会报错:
@FunctionalInterface
public interface InvalidFunctionalInterface {
void method1();
void method2(); // 编译错误:函数式接口只能有一个抽象方法
}
函数式接口的特点
-
单一抽象方法
函数式接口只能有一个抽象方法,但允许有多个默认方法或静态方法:@FunctionalInterface public interface Example { void abstractMethod(); // 抽象方法 default void defaultMethod() { System.out.println("This is a default method."); } static void staticMethod() { System.out.println("This is a static method."); } }
-
与 Lambda 表达式结合
函数式接口是 Lambda 表达式的基础,Lambda 可以直接实现函数式接口:Example example = () -> System.out.println("Implementing abstractMethod via Lambda!"); example.abstractMethod();
-
继承其他接口
如果函数式接口继承了另一个接口,只要继承的接口中没有新的抽象方法,依然符合函数式接口的定义。
应用场景
-
Lambda 表达式
函数式接口是 Lambda 表达式的核心应用场景。常见的标准函数式接口包括:Runnable
:无返回值、无参数。Callable<V>
:有返回值。Comparator<T>
:用于比较两个对象。- Java 8 提供的
java.util.function
包中的接口(如Function
、Predicate
、Consumer
等)。
示例:
Runnable runnable = () -> System.out.println("Running in a thread!"); new Thread(runnable).start();
-
方法引用
函数式接口可以配合方法引用使用:@FunctionalInterface interface Printer { void print(String message); } public class MethodReferenceExample { public static void main(String[] args) { Printer printer = System.out::println; printer.print("Hello, Method Reference!"); } }
-
自定义回调机制
函数式接口可以用作回调参数,使得代码更加灵活:@FunctionalInterface interface Callback { void execute(); } public class CallbackExample { public static void performTask(Callback callback) { System.out.println("Task started..."); callback.execute(); System.out.println("Task finished..."); } public static void main(String[] args) { performTask(() -> System.out.println("Performing the callback!")); } }
-
简化集合操作
函数式接口配合Stream
API 可以简化集合的处理:List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); names.stream() .filter(name -> name.startsWith("A")) .forEach(System.out::println);
常见的 Java 标准函数式接口
Java 8 引入了一些常用的函数式接口,大部分在 java.util.function
包中:
接口 | 描述 | 方法签名 |
---|---|---|
Predicate<T> | 接受一个参数,返回 boolean | boolean test(T t) |
Function<T, R> | 接受一个参数,返回一个结果 | R apply(T t) |
Consumer<T> | 接受一个参数,没有返回值 | void accept(T t) |
Supplier<T> | 不接受参数,返回一个结果 | T get() |
BiFunction<T, U, R> | 接受两个参数,返回一个结果 | R apply(T t, U u) |
UnaryOperator<T> | 接受一个参数,返回与参数类型相同的结果 | T apply(T t) |
BinaryOperator<T> | 接受两个参数,返回与参数类型相同的结果 | T apply(T t1, T t2) |
总结
@FunctionalInterface
是一个声明性注解,明确告诉编译器和开发者某个接口是函数式接口。- 它广泛应用于 Lambda 表达式、方法引用、回调机制等现代 Java 编程中,能简化代码,提高可读性。
- 使用场景集中在需要单一行为抽象的地方,比如异步任务、事件处理、集合操作等。