java中用函数式接口实现回调机制,核心是利用只有一个抽象方法的接口(如runnable、consumer、function等),配合lambda表达式或方法引用,把“等某事做完后要执行的操作”作为参数传入,从而解耦调用方与被调用方。

Java 中用函数式接口实现回调机制,核心是利用只有一个抽象方法的接口(如 Runnable、Consumer、Function 等),配合 Lambda 表达式或方法引用,把“等某事做完后要执行的操作”作为参数传入,从而解耦调用方与被调用方。
选对函数式接口是关键
Java 8 的 java.util.function 包提供了常用函数式接口,按需选用:
-
无参无返回值:用
Runnable,适合纯通知类回调(如“加载完成”) -
有输入无返回值:用
Consumer<t></t>,适合处理结果(如“收到数据后更新 UI”) -
有输入有返回值:用
Function<t r></t>或Supplier<r></r>,适合需要加工或生成结果的场景 -
有输入、有返回值、可能抛异常:可自定义函数式接口(加
@FunctionalInterface),例如ThrowingConsumer<t></t>
写一个带回调的工具方法
以异步下载为例,封装一个方法,允许调用者传入成功和失败的处理逻辑:
public class Downloader {
public static void download(String url,
Consumer<string> onSuccess,
Consumer<exception> onError) {
new Thread(() -> {
try {
String content = simulateDownload(url); // 模拟耗时操作
onSuccess.accept(content);
} catch (Exception e) {
onError.accept(e);
}
}).start();
}
private static String simulateDownload(String url) throws Exception {
Thread.sleep(1000);
return "Content from " + url;
}
}</exception></string>
调用时用 Lambda 表达式传入回调逻辑:
Downloader.download(
"https://api.example.com/data",
content -> System.out.println("✅ 下载成功:" + content),
err -> System.err.println("❌ 下载失败:" + err.getMessage())
);
用方法引用简化回调写法
如果已有现成方法,直接用 :: 引用,更简洁清晰:
public class UiUpdater {
public static void updateText(String text) {
System.out.println("UI 更新为:" + text);
}
public static void showError(String msg) {
System.out.println("显示错误:" + msg);
}
}
// 调用时
Downloader.download(
"data.txt",
UiUpdater::updateText,
e -> UiUpdater.showError(e.getMessage())
);
自定义函数式接口支持异常处理
标准接口不声明受检异常,若需透传异常,可自定义:
@FunctionalInterface
public interface ThrowingConsumer<t> {
void accept(T t) throws Exception;
}
// 工具方法中使用
public static <t> void safeConsume(T value, ThrowingConsumer<t> consumer) {
try {
consumer.accept(value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}</t></t></t>
这样就能在 Lambda 中直接 throw 受检异常,无需包装。
不复杂但容易忽略:回调本质是“延迟执行的函数”,Java 通过函数式接口 + Lambda 把它变成一等公民,重点不在语法多炫,而在职责分离——谁触发、谁响应,彼此不知道对方细节,只靠接口约定协作。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











