- ntent="mp" href="https://www.toutiao.com/i6792573246827921924/?group_id=6792573246827921924" target="_blank">疫情期间“闭关修炼”,吃透这本Java核心知识,跳槽面试不心慌
- ntent="mp" href="https://www.toutiao.com/i6793297693910237700/?group_id=6793297693910237700" target="_blank">2020“闭关”跳槽季,啃透分布式三大技术:限流、缓存、通讯
- ntent="mp" href="https://www.toutiao.com/i6791757874402951684/?group_id=6791757874402951684" target="_blank">2020春招必备:MySQL(20)与Redis(20),不看答案能答对几道?
1. 引言
以上是维基百科对“回调函数”的定义。对于回调,不同的语言有不同的回调形式,例如:
- C、C++ 允许将函数指针作为参数传递;
- Javascript、Python 允许将函数名作为参数传递。
在开始之前,先介绍下本文代码示例的背景,在 main 函数中,我们异步发送一个请求,并且指定处理响应的回调函数,接着 main 函数去做其他事,而当响应到达后,执行回调函数。
2. 反射
Request 类中的 send 方法有两个参数 clazz、method,分别是Class 类型和 Method 类型,这里的 method 参数就是待传入的回调函数,而为了通过 invoke 方法进行反射调用,还需要一个实例,所以将回调函数所在的类的 Class 对象作为参数传递进来,通过 newInstance 构造一个对象,将顺利通过 invoke 反射调用。
public class Request{ public void send(Class clazz, Method method) throws Exception { // 模拟等待响应 Thread.sleep(3000); System.out.println("[Request]:收到响应"); method.invoke(clazz.newInstance()); }}我们在 main 方法中,新开了一个线程去发送请求,并且把需要的 CallBack.class 和 processResponse 方法传递进去。
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我开个线程去异步发请求"); new Thread(() -> { try { request.send(CallBack.class, CallBack.class.getMethod("processResponse")); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:请求发完了,我去干点别的"); Thread.sleep(100000); }}我们来改写下 send 方法的参数,改为一个 CallBack 类型参数。如下:
main 函数中,我们 new 了一个 CallBack 对象作为参数传递给 send 方法。
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我开个线程去异步发请求"); CallBack callBack = new CallBack(); new Thread(() -> { try { request.send(callBack); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:请求发完了,我去干点别的"); Thread.sleep(100000); }}首先将 CallBack 类改为接口。
public interface CallBack { public void processResponse();}复制代码Request 类不变。Main 类中的 main 方法将实例化一个 CallBackImpl,然后通过 CallBack 接口传递进去。
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我开个线程去异步发请求"); CallBack callBack = new CallBackImpl(); new Thread(() -> { try { request.send(callBack); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:请求发完了,我去干点别的"); Thread.sleep(100000); }}5. Lambda表达式
我们既不用去新增实现类,也不用去实例化,只需要传递 Lambda 表达式就可以完成回调了
作者:草捏子
原文链接:https://juejin.im/post/5e4948c7e51d4526c70fa2ec

