您好,登錄后才能下訂單哦!
本篇內容介紹了“Java實現回調的寫法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在計算機程序設計中,回調函數,簡稱回調(Callback),是指通過函數參數傳遞到其他代碼的,某一塊可執行代碼的引用。這一設計允許了底層代碼調用在高層定義的子程序。
以上是維基百科對“回調函數”的定義。對于回調,不同的語言有不同的回調形式,例如:
C、C++ 允許將函數指針作為參數傳遞;
JavaScript、Python 允許將函數名作為參數傳遞。
本文將介紹 Java 實現回調的四種寫法:
反射;
直接調用;
接口調用;
Lambda表達式。
在開始之前,先介紹下本文代碼示例的背景,在 main 函數中,我們異步發送一個請求,并且指定處理響應的回調函數,接著 main 函數去做其他事,而當響應到達后,執行回調函數。
Java 的反射機制允許我們獲取類的信息,其中包括類的方法。我們將以 Method 類型去獲取回調函數,然后傳遞給請求函數。示例如下:
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()); }}
CallBack 類很簡單,只有一個 processResponse 方法,用于當作回調函數,處理響應。
public class CallBack { public void processResponse() { System.out.println("[CallBack]:處理響應"); }}
我們在 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); }}/** Output:[Main]:我開個線程去異步發請求[Main]:請求發完了,我去干點別的[Request]:收到響應[CallBack]:處理響應*/
這種寫法需要傳遞的參數十分繁瑣。下面介紹一種簡單的寫法,直接調用。
我們來改寫下 send 方法的參數,改為一個 CallBack 類型參數。如下:
在 send 方法中我們不使用反射,改為直接通過對象來調用方法。
public class Request{ public void send(CallBack callBack) throws Exception { // 模擬等待響應 Thread.sleep(3000); System.out.println("[Request]:收到響應"); callBack.processResponse(); }}
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 類的 processRequest()方法。而如果將 CallBack 類改為接口,我們就可以僅更換 CallBack 的實現了。下面請看接口調用的寫法。
首先將 CallBack 類改為接口。
public interface CallBack { public void processResponse();}復制代碼
再新增一個 CallBack 接口的實現類 CallBackImpl。
public class CallBackImpl implements CallBack { @Override public void processResponse() { System.out.println("[CallBack]:處理響應"); }}
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); }}
上述方法已經介紹的差不多了,最后我們再介紹一種更加簡潔的寫法,通過使用 Lamda 表達式,將不用新增一個 CallBack 接口的實現類。下面請看改寫的 main 方法:
public class Main { public static void main(String[] args) throws Exception { Request request = new Request(); System.out.println("[Main]:我開個線程去異步發請求"); new Thread(() -> { try { request.send(()-> System.out.println("[CallBack]:處理響應")); } catch (Exception e) { e.printStackTrace(); } }).start(); System.out.println("[Main]:請求發完了,我去干點別的"); Thread.sleep(100000); }}
我們既不用去新增實現類,也不用去實例化,只需要傳遞 Lambda 表達式就可以完成回調了
“Java實現回調的寫法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。