新聞中心
本篇內(nèi)容介紹了“Java實(shí)現(xiàn)回調(diào)的寫法”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
專業(yè)從事成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司,高端網(wǎng)站制作設(shè)計(jì),微信平臺(tái)小程序開(kāi)發(fā),網(wǎng)站推廣的成都做網(wǎng)站的公司。優(yōu)秀技術(shù)團(tuán)隊(duì)竭力真誠(chéng)服務(wù),采用H5技術(shù)+CSS3前端渲染技術(shù),響應(yīng)式網(wǎng)站建設(shè),讓網(wǎng)站在手機(jī)、平板、PC、微信下都能呈現(xiàn)。建站過(guò)程建立專項(xiàng)小組,與您實(shí)時(shí)在線互動(dòng),隨時(shí)提供解決方案,暢聊想法和感受。
1. 引言
在計(jì)算機(jī)程序設(shè)計(jì)中,回調(diào)函數(shù),簡(jiǎn)稱回調(diào)(Callback),是指通過(guò)函數(shù)參數(shù)傳遞到其他代碼的,某一塊可執(zhí)行代碼的引用。這一設(shè)計(jì)允許了底層代碼調(diào)用在高層定義的子程序。
以上是維基百科對(duì)“回調(diào)函數(shù)”的定義。對(duì)于回調(diào),不同的語(yǔ)言有不同的回調(diào)形式,例如:
C、C++ 允許將函數(shù)指針作為參數(shù)傳遞;
JavaScript、Python 允許將函數(shù)名作為參數(shù)傳遞。
本文將介紹 Java 實(shí)現(xiàn)回調(diào)的四種寫法:
反射;
直接調(diào)用;
接口調(diào)用;
Lambda表達(dá)式。
在開(kāi)始之前,先介紹下本文代碼示例的背景,在 main 函數(shù)中,我們異步發(fā)送一個(gè)請(qǐng)求,并且指定處理響應(yīng)的回調(diào)函數(shù),接著 main 函數(shù)去做其他事,而當(dāng)響應(yīng)到達(dá)后,執(zhí)行回調(diào)函數(shù)。
2. 反射
Java 的反射機(jī)制允許我們獲取類的信息,其中包括類的方法。我們將以 Method 類型去獲取回調(diào)函數(shù),然后傳遞給請(qǐng)求函數(shù)。示例如下:
Request 類中的 send 方法有兩個(gè)參數(shù) clazz、method,分別是Class 類型和 Method 類型,這里的 method 參數(shù)就是待傳入的回調(diào)函數(shù),而為了通過(guò) invoke 方法進(jìn)行反射調(diào)用,還需要一個(gè)實(shí)例,所以將回調(diào)函數(shù)所在的類的 Class 對(duì)象作為參數(shù)傳遞進(jìn)來(lái),通過(guò) newInstance 構(gòu)造一個(gè)對(duì)象,將順利通過(guò) invoke 反射調(diào)用。
public class Request{ public void send(Class clazz, Method method) throws Exception { // 模擬等待響應(yīng) Thread.sleep(3000); System.out.println("[Request]:收到響應(yīng)"); method.invoke(clazz.newInstance()); }}
CallBack 類很簡(jiǎn)單,只有一個(gè) processResponse 方法,用于當(dāng)作回調(diào)函數(shù),處理響應(yīng)。
public class CallBack { public void processResponse() { System.out.println("[CallBack]:處理響應(yīng)"); }}
我們?cè)?main 方法中,新開(kāi)了一個(gè)線程去發(fā)送請(qǐng)求,并且把需要的 CallBack.class 和 processResponse 方法傳遞進(jìn)去。
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我開(kāi)個(gè)線程去異步發(fā)請(qǐng)求"); new Thread(() -> { try { request.send(CallBack.class, CallBack.class.getMethod("processResponse")); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:請(qǐng)求發(fā)完了,我去干點(diǎn)別的"); Thread.sleep(100000); }}/** Output:[Main]:我開(kāi)個(gè)線程去異步發(fā)請(qǐng)求[Main]:請(qǐng)求發(fā)完了,我去干點(diǎn)別的[Request]:收到響應(yīng)[CallBack]:處理響應(yīng)*/
這種寫法需要傳遞的參數(shù)十分繁瑣。下面介紹一種簡(jiǎn)單的寫法,直接調(diào)用。
3. 直接調(diào)用
我們來(lái)改寫下 send 方法的參數(shù),改為一個(gè) CallBack 類型參數(shù)。如下:
在 send 方法中我們不使用反射,改為直接通過(guò)對(duì)象來(lái)調(diào)用方法。
public class Request{ public void send(CallBack callBack) throws Exception { // 模擬等待響應(yīng) Thread.sleep(3000); System.out.println("[Request]:收到響應(yīng)"); callBack.processResponse(); }}
main 函數(shù)中,我們 new 了一個(gè) CallBack 對(duì)象作為參數(shù)傳遞給 send 方法。
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我開(kāi)個(gè)線程去異步發(fā)請(qǐng)求"); CallBack callBack = new CallBack(); new Thread(() -> { try { request.send(callBack); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:請(qǐng)求發(fā)完了,我去干點(diǎn)別的"); Thread.sleep(100000); }}
這種實(shí)現(xiàn)方式十分簡(jiǎn)單,但是存在的問(wèn)題是不符合修改封閉原則。也就是說(shuō)當(dāng)我們想要換一種“處理響應(yīng)”的方法時(shí),將必須去修改 CallBack 類的 processRequest()方法。而如果將 CallBack 類改為接口,我們就可以僅更換 CallBack 的實(shí)現(xiàn)了。下面請(qǐng)看接口調(diào)用的寫法。
4. 接口調(diào)用
首先將 CallBack 類改為接口。
public interface CallBack { public void processResponse();}復(fù)制代碼
再新增一個(gè) CallBack 接口的實(shí)現(xiàn)類 CallBackImpl。
public class CallBackImpl implements CallBack { @Override public void processResponse() { System.out.println("[CallBack]:處理響應(yīng)"); }}
Request 類不變。Main 類中的 main 方法將實(shí)例化一個(gè) CallBackImpl,然后通過(guò) CallBack 接口傳遞進(jìn)去。
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我開(kāi)個(gè)線程去異步發(fā)請(qǐng)求"); CallBack callBack = new CallBackImpl(); new Thread(() -> { try { request.send(callBack); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:請(qǐng)求發(fā)完了,我去干點(diǎn)別的"); Thread.sleep(100000); }}
5. Lambda表達(dá)式
上述方法已經(jīng)介紹的差不多了,最后我們?cè)俳榻B一種更加簡(jiǎn)潔的寫法,通過(guò)使用 Lamda 表達(dá)式,將不用新增一個(gè) CallBack 接口的實(shí)現(xiàn)類。下面請(qǐng)看改寫的 main 方法:
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我開(kāi)個(gè)線程去異步發(fā)請(qǐng)求"); new Thread(() -> { try { request.send(()-> System.out.println("[CallBack]:處理響應(yīng)")); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:請(qǐng)求發(fā)完了,我去干點(diǎn)別的"); Thread.sleep(100000); }}
我們既不用去新增實(shí)現(xiàn)類,也不用去實(shí)例化,只需要傳遞 Lambda 表達(dá)式就可以完成回調(diào)了
“Java實(shí)現(xiàn)回調(diào)的寫法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
新聞標(biāo)題:Java實(shí)現(xiàn)回調(diào)的寫法
瀏覽地址:http://www.dlmjj.cn/article/igshoe.html