本文目录导读:

在Java中,自定义函数接口主要有两种方式:使用 @FunctionalInterface 注解显式定义,或者直接使用已有的函数式接口(如 Function、Consumer 等),但如果你需要完全自定义,可以按照以下步骤。
自定义函数接口的核心规则
- 接口中只能有一个抽象方法(SAM – Single Abstract Method)。
- 可以使用
@FunctionalInterface注解(可选,但推荐,编译器会检查是否满足条件)。 - 可以包含
default方法、static方法、Object类的方法。
基本示例
示例1:一个简单的转换接口
@FunctionalInterface
interface StringConverter {
String convert(String input);
}
使用方式(Lambda 表达式):
StringConverter toUpperCase = str -> str.toUpperCase();
System.out.println(toUpperCase.convert("hello")); // 输出 HELLO
带多个参数的自定义函数接口
@FunctionalInterface
interface MathOperation {
int operate(int a, int b);
}
使用:
MathOperation add = (a, b) -> a + b; System.out.println(add.operate(3, 4)); // 7
泛型自定义函数接口
@FunctionalInterface
interface Comparator<T> {
int compare(T a, T b); // 抽象方法
}
使用(Lambda + 泛型):
Comparator<String> lengthComparator = (s1, s2) -> s1.length() - s2.length();
System.out.println(lengthComparator.compare("hi", "hello")); // -3
注意:这里的
Comparator是自定义的,与java.util.Comparator无关。
包含 default 方法的函数接口
@FunctionalInterface
interface Greeting {
void sayHello(String name); // 唯一抽象方法
default void sayGoodbye(String name) {
System.out.println("Goodbye, " + name);
}
}
使用:
Greeting greet = name -> System.out.println("Hello, " + name);
greet.sayHello("Alice"); // Hello, Alice
greet.sayGoodbye("Alice"); // Goodbye, Alice
实际项目中的完整示例
假设你需要一个处理用户对象的函数接口:
@FunctionalInterface
interface UserProcessor {
void process(User user);
}
class User {
private String name;
private int age;
// 构造方法、getter/setter 省略
}
使用:
UserProcessor printName = user -> System.out.println(user.getName());
UserProcessor checkAdult = user -> {
if (user.getAge() >= 18) {
System.out.println(user.getName() + " is adult");
}
};
也可以结合方法引用:
UserProcessor printUserInfo = System.out::println; // 需要 User 有 toString
与 Java 内置函数式接口的对比
| 场景 | 内置接口 | 完全自定义的时机 |
|---|---|---|
| 参数 → 返回值 | Function<T,R> |
需要更有意义的命名,如 UrlResolver |
| 无参 → 返回值 | Supplier<T> |
业务语义不匹配时 |
| 参数 → void | Consumer<T> |
需要语义化的名称 |
| 参数 → boolean | Predicate<T> |
如 PositiveNumberChecker |
建议:优先使用内置函数接口(java.util.function 包下),除非你需要更强的语义表达或特殊的参数/返回类型组合。
一个带有异常处理的函数接口
默认的函数式接口不支持受检异常(checked exception),你可以自定义一个:
@FunctionalInterface
interface ThrowingFunction<T, R, E extends Exception> {
R apply(T t) throws E;
}
使用:
ThrowingFunction<String, Integer, IOException> parser = str -> {
if (str.isEmpty()) throw new IOException("empty string");
return Integer.parseInt(str);
};
调用时需要处理异常:
try {
int result = parser.apply("123");
} catch (IOException e) {
e.printStackTrace();
}
| 步骤 | 说明 |
|---|---|
| 1 | 定义接口,添加 @FunctionalInterface 注解 |
| 2 | 仅保留一个抽象方法 |
| 3 | 可添加 default/static 方法 |
| 4 | 支持泛型实现复用 |
| 5 | 用 Lambda 或方法引用实例化 |
实战建议:除非你需要表达特别明确的业务语义,否则优先使用 java.util.function 包中已有的接口,如果确实需要自定义,务必加上 @FunctionalInterface 注解让编译器帮你检查。