1.简介在计算机编程中,回调函数,简称回调(Callback),是指将函数参数传递给其他代码。对可执行代码块的引用。这种设计允许低级代码调用在高级定义的子程序。以上是维基百科对“回调函数”的定义。对于回调,不同的语言有不同的回调形式,例如:C和C++允许函数指针作为参数传递;JavaScript和Python允许将函数名作为参数传递。本文将介绍Java中四种写回调的方式:反射;直接调用;接口调用;拉姆达表达式。在开始之前,先介绍一下本文代码示例的背景。在主函数中,我们异步发送一个请求,并指定一个回调函数来处理响应。然后main函数做其他事情,当response到达时,执行回调函数。2.反射Java的反射机制可以让我们获取到类的信息,包括类的方法。我们将使用Method类型获取回调函数,然后将其传递给请求函数。示例如下:Request类中的send方法有两个参数clazz和method,分别是Class类型和Method类型。这里的方法参数是要传入的回调函数,为了通过invoke方法进行反射调用,需要一个实例,所以传入回调函数所在类的Class对象作为参数,并且通过newInstance构造一个对象,通过invoke反射成功调用。publicclassRequest{publicvoidsend(Classclazz,Methodmethod)throwsException{//模拟等待响应Thread.sleep(3000);System.out.println("[请求]:收到响应");方法.invoke(clazz.newInstance());}}CallBack类非常简单,只有一个processResponse方法,作为处理响应的回调函数。publicclassCallBack{publicvoidprocessResponse(){System.out.println("[CallBack]:处理响应");}}在main方法中,我们新开了一个线程发送请求,把需要的CallBack.class和processResponse方法传入。publicclassMain{publicstaticvoidmain(String[]args)throwsException{Requestrequest=新请求();System.out.println([Main]:我开一个线程异步发送请求");newThread(()->{尝试{request.send(CallBack.class,CallBack.class.getMethod("processResponse"));}catch(Exceptione){e.printStackTrace();}}).start();系统。out.println([Main]:请求完成,我要去干点别的事情了");线程.睡眠(100000);}}/**输出:[Main]:我开一个线程异步发送请求[Main]:发送请求后,我会做其他事情[Request]:收到响应[CallBack]:处理响应*/这种写法需要传递的参数非常繁琐。下面介绍一种简单的写法,直接调用。3.直接调用我们重写send方法的参数,改成CallBack类型的参数。如下:在send方法中,我们没有使用反射,而是直接通过对象调用方法。publicclassRequest{publicvoidsend(CallBackcallBack)throwsException{//模拟等待响应Thread.sleep(3000);System.out.println("[请求]:收到响应");callBack.processResponse();在main函数中,我们新建一个CallBack对象作为参数并将其传递给send方法。publicclassMain{publicstaticvoidmain(String[]args)throwsException{Requestrequest=newRequest();System.out.println([Main]:我开一个线程异步发送请求");回调callBack=newCallBack();newThread(()->{try{request.send(callBack);}catch(Exceptione){e.printStackTrace();}}).start();System.out.println("[Main]:请求完成,我去干点别的事情");线程.睡眠(100000);}}这个实现很简单,但是问题是不符合修饰闭包的原则。也就是说,当我们要改变“处理响应”的方法时,我们将不得不修改CallBack类的processRequest()方法。而如果我们把CallBack类改成一个接口,我们只需要替换CallBack的实现即可。请看下面如何编写接口调用。4.接口调用首先把CallBack类改成一个接口。publicinterfaceCallBack{publicvoidprocessResponse();}复制代码,添加一个CallBack接口的实现类CallBackImpl。publicclassCallBackImplimplementsCallBack{@OverridepublicvoidprocessResponse(){System.out.println("[CallBack]:ProcessResponse");}}请求类不变。Main类中的main方法会实例化一个CallBackImpl,通过CallBack接口传入。publicclassMain{publicstaticvoidmain(String[]args)throwsException{Requestrequest=newRequest();System.out.println([Main]:我开一个线程异步发送请求");回调callBack=newCallBackImpl();newThread(()->{try{request.send(callBack);}catch(Exceptione){e.printStackTrace();}}).start();System.out.println("[Main]:发送请求后,我会做其他事情");线程.睡眠(100000);}}5.以上Lambda表达式的方法已经介绍的差不多了,最后再介绍一种更简洁的写法,使用Lambda表达式,不需要再增加CallBack接口的实现类。请看下面重写的main方法:publicclassMain{publicstaticvoidmain(String[]args)throwsException{System.out.println([Main]:我开一个线程异步发送请求");newThread(()->{try{request.send(()->System.out.println("[CallBack]:Processingresponse"));}catch(Exceptione){e.printStackTrace();}})。开始();System.out.println([Main]:请求完成,我要去干点别的事情了");线程.睡眠(100000);}}我们不需要添加也不需要实例化实现类,只需要传递Lambda表达式即可完成回调
