概述
回调函数,简称回调(Callback),是指通过函数参数传递到其他代码的,某一块可执行代码的引用。
询问问题(调用对方接口),然后问题解决之后再告诉你(对方处理完再调用你,通知结果),这一过程便是回调。
其有四种实现方法
- 反射:Java 的反射机制允许我们获取类的信息,其中包括类的方法
- 直接调用;
- 接口调用;
- Lambda表达式
实现
反射
这种写法需要传递的参数十分繁琐,所以不推荐
public class CallBack {
public void processResponse() {
System.out.println("收到,做相应的处理");
}
}
public class Request{
public void send(Class clazz, Method method) throws Exception {
// 模拟等待响应
Thread.sleep(3000);
System.out.println("开始请求");
method.invoke(clazz.newInstance());
}
}
public class Main {
public static void main(String[] args) throws Exception {
Request request = new Request();
System.out.println("主线程开个线程去异步发请求");
new Thread(() -> {
try {
request.send(CallBack.class, CallBack.class.getMethod("processResponse"));
} catch (Exception e) {
e.printStackTrace();
}
}).start();
System.out.println("主线程请求发完了, 现在在执行其他的事情");
Thread.sleep(100000);
}
}
运行结果
主线程开个线程去异步发请求
主线程请求发完了, 现在在执行其他的事情
开始请求
收到,做相应的处理
直接调用
与上面反射的区别:
- request的send方法里面,没有method这个参数。
public class Request{ public void send(Class clazz, Method method) throws Exception { // 模拟等待响应 Thread.sleep(3000); System.out.println("开始请求"); method.invoke(clazz.newInstance()); } }
- 在main方法里面,将callback参数new处理,放入send方法的参数里面
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("主线程开个线程去异步发请求"); CallBack callBack = new CallBack(); new Thread(() -> { try { request.send(callBack); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("主线程请求发完了, 现在在执行其他的事情"); Thread.sleep(100000); } }
不符合修改封闭原则
:我们想要换一种“处理响应”的方法时,将必须去修改 CallBack 类的 processRequest()方法
接口调用
这个方法便可以解决直接调用出现的问题
- 将callback类改为接口
public interface CallBack { public void processResponse(); }
- 增加一个实现类,实现该接口
public class CallBackImpl implements CallBack { @Override public void processResponse() { System.out.println("收到,做相应的处理"); } }
- main方法里面实例化第二步的callbackImpl实现类
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("主线程开个线程去异步发请求"); CallBack callBack = new CallBackImpl(); new Thread(() -> { try { request.send(callBack); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("主线程请求发完了, 现在在执行其他的事情"); Thread.sleep(100000); } }
按如上操作后,便可以实现与反射一样的结果
Lambda表达式
这个方法更加简洁,不需要新增callback接口的实现类
- 将main方法改写如下
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("主线程开个线程去异步发请求"); new Thread(() -> { try { request.send(()-> System.out.println("收到,做相应的处理")); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("主线程请求发完了, 现在在执行其他的事情"); Thread.sleep(100000); } }