Java接口回调实现案例
接口回调是一种常见的编程模式,允许一个对象在特定事件发生时通知另一个对象,下面通过几个具体案例来演示。

简单计算器回调
定义回调接口
// 计算结果回调接口
public interface CalculatorCallback {
void onResult(int result);
void onError(String errorMessage);
}
创建计算器类
public class Calculator {
// 执行计算并回调
public void calculate(int a, int b, String operation, CalculatorCallback callback) {
try {
int result = 0;
switch (operation) {
case "+":
result = a + b;
break;
case "-":
result = a - b;
break;
case "*":
result = a * b;
break;
case "/":
if (b == 0) {
callback.onError("除数不能为0");
return;
}
result = a / b;
break;
default:
callback.onError("不支持的运算操作");
return;
}
callback.onResult(result);
} catch (Exception e) {
callback.onError("计算异常:" + e.getMessage());
}
}
}
使用回调
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
// 方式1:匿名内部类实现
calculator.calculate(10, 5, "+", new CalculatorCallback() {
@Override
public void onResult(int result) {
System.out.println("计算结果: " + result);
}
@Override
public void onError(String errorMessage) {
System.err.println("错误: " + errorMessage);
}
});
// 方式2:Lambda表达式实现(Java 8+)
calculator.calculate(10, 0, "/",
result -> System.out.println("计算结果: " + result),
error -> System.err.println("错误: " + error)
);
}
}
下载进度回调
// 下载进度回调接口
public interface DownloadCallback {
void onProgress(int progress, long downloadedBytes, long totalBytes);
void onComplete(String filePath);
void onFailed(Exception e);
}
// 下载器类
public class FileDownloader {
public void download(String url, String savePath, DownloadCallback callback) {
new Thread(() -> {
try {
// 模拟下载过程
for (int i = 0; i <= 100; i += 10) {
Thread.sleep(500); // 模拟下载耗时
long totalBytes = 1024 * 1024; // 1MB
long downloadedBytes = totalBytes * i / 100;
// 回调进度
if (callback != null) {
callback.onProgress(i, downloadedBytes, totalBytes);
}
}
// 下载完成
if (callback != null) {
callback.onComplete(savePath);
}
} catch (Exception e) {
if (callback != null) {
callback.onFailed(e);
}
}
}).start();
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
FileDownloader downloader = new FileDownloader();
downloader.download("https://example.com/file.zip", "/downloads/file.zip",
new DownloadCallback() {
@Override
public void onProgress(int progress, long downloadedBytes, long totalBytes) {
System.out.printf("下载进度: %d%%, 已下载: %d/%d KB%n",
progress, downloadedBytes / 1024, totalBytes / 1024);
}
@Override
public void onComplete(String filePath) {
System.out.println("下载完成: " + filePath);
}
@Override
public void onFailed(Exception e) {
System.err.println("下载失败: " + e.getMessage());
}
}
);
System.out.println("下载任务已启动...");
}
}
按钮点击事件回调(模拟GUI)
// 点击事件监听器接口
public interface OnClickListener {
void onClick(View v);
}
// 视图类
public class View {
private OnClickListener clickListener;
public void setOnClickListener(OnClickListener listener) {
this.clickListener = listener;
}
// 模拟点击事件
public void performClick() {
System.out.println("按钮被点击了");
if (clickListener != null) {
clickListener.onClick(this);
}
}
}
// 按钮类
public class Button extends View {
private String text;
public Button(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
Button button = new Button("点击我");
// 设置点击回调
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Button btn = (Button) v;
System.out.println("按钮 \"" + btn.getText() + "\" 被点击了");
}
});
// 模拟点击
button.performClick();
// Lambda表达式方式
Button button2 = new Button("另一个按钮");
button2.setOnClickListener(v -> {
Button btn = (Button) v;
System.out.println("Lambda方式: 按钮 \"" + btn.getText() + "\" 被点击了");
});
button2.performClick();
}
}
排序完成回调
// 排序回调接口
public interface SortCallback {
void onSortComplete(int[] sortedArray);
void onProgress(int percent);
}
// 排序器类
public class ArraySorter {
public void sortAsync(int[] array, SortCallback callback) {
new Thread(() -> {
int[] temp = array.clone();
// 冒泡排序(带进度反馈)
for (int i = 0; i < temp.length - 1; i++) {
for (int j = 0; j < temp.length - 1 - i; j++) {
if (temp[j] > temp[j + 1]) {
int swap = temp[j];
temp[j] = temp[j + 1];
temp[j + 1] = swap;
}
}
// 报告进度
int progress = (i + 1) * 100 / (temp.length - 1);
if (callback != null) {
callback.onProgress(progress);
}
}
// 排序完成
if (callback != null) {
callback.onSortComplete(temp);
}
}).start();
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
int[] numbers = {64, 34, 25, 12, 22, 11, 90};
ArraySorter sorter = new ArraySorter();
sorter.sortAsync(numbers, new SortCallback() {
@Override
public void onSortComplete(int[] sortedArray) {
System.out.print("排序完成: ");
for (int num : sortedArray) {
System.out.print(num + " ");
}
System.out.println();
}
@Override
public void onProgress(int percent) {
System.out.println("排序进度: " + percent + "%");
}
});
System.out.println("主线程继续执行其他任务...");
}
}
回调模式的优势
- 解耦:调用者不需要知道具体的实现细节
- 异步处理:可以在耗时操作完成后进行回调
- 事件驱动:适用于需要响应特定事件的场景
- 灵活性:可以动态改变回调行为
注意事项
- 避免回调地狱:过多嵌套回调会使代码难以维护
- 线程安全:在异步回调中需要注意线程安全问题
- 内存泄漏:如果回调持有外部对象引用,可能导致内存泄漏
这些案例展示了接口回调在实际开发中的多种应用场景,可以根据具体需求灵活使用。