Java回呼機制介紹
模組間呼叫
#在一個應用系統中,無論使用何種語言開發,必然存在著模組之間的調用,調用的方式分為幾種:
(1)同步調用
#同步調用是最基本且最簡單的一種呼叫方式,類別A的方法a()呼叫類別B的方法b(),一直等待b()方法執行完畢,a()方法繼續往下走。 這種呼叫方式適用於方法b()執行時間不長的情況,因為b()方法執行時間一長或直接阻塞的話,a()方法的餘下程式碼是無法執行下去的,這樣會造成整個流程的阻塞。
(2)非同步呼叫
非同步呼叫是為了解決同步呼叫可能會出現阻塞,導致整個流程卡住而產生的一種呼叫方式。 類別A的方法方法a()透過新起執行緒的方式呼叫類別B的方法b(),程式碼接著直接往下執行#,這樣無論方法b()執行時間多久,都不會阻塞住方法a()的執行。
但是這種方式,由於方法a()不等待方法b()的執行完成,在方法a()需要方法b()執行結果的情況下(視具體業務而定,有些業務例如啟非同步執行緒發個微信通知、刷新一個快取這種就沒必要),必須透過一定的方式對方法b()的執行結果進行監聽。
(3)回呼
#最後是回呼,回呼的想法是:
- #類別A的a()方法呼叫類別B的b()方法
- #類別B的b()方法執行完畢主動呼叫類A的callback()方法
這樣一種呼叫方式組成了上圖,也就是一種雙向的呼叫方式。
程式碼範例
#接下來看一下回呼的程式碼範例,程式碼模擬的是這樣一個場景:老師問學生問題,學生思考完畢回答老師。
先定義一個回呼接口,只有一個方法tellAnswer(int answer),也就是學生思考完畢告訴老師答案:
/** * 回调接口,原文出处http://www.cnblogs.com/xrq730/p/6424471.html */ public interface Callback { public void tellAnswer(int answer); }
定義一個老師對象,實作Callback介面:
/** * 老师对象,原文出处http://www.cnblogs.com/xrq730/p/6424471.html */ public class Teacher implements Callback { private Student student; public Teacher(Student student) { this.student = student; } public void askQuestion() { student.resolveQuestion(this); } @Override public void tellAnswer(int answer) { System.out.println("知道了,你的答案是" + answer); } }
老師對像有兩個public方法:
(1)回呼介面tellAnswer(int answer),也就是學生回答完畢問題之後,老師要做的事情
(2)問問題方法askQuestion(),即向學生問問題
接著定義一個學生接口,學生當然是解決問題,但是接收一個Callback參數,這樣學生就知道解決完畢問題向誰報告:
/** * 学生接口,原文出处http://www.cnblogs.com/xrq730/p/6424471.html */ public interface Student { public void resolveQuestion(Callback callback); }
最後定義一個具體的學生叫Ricky:
/** * 一个名叫Ricky的同学解决老师提出的问题,原文出处http://www.cnblogs.com/xrq730/p/6424471.html */ public class Ricky implements Student { @Override public void resolveQuestion(Callback callback) { // 模拟解决问题 try { Thread.sleep(3000); } catch (InterruptedException e) { } // 回调,告诉老师作业写了多久 callback.tellAnswer(3); } }
在解決完畢問題之後,第16行向老師報告答案。
寫一個測試類,比較簡單:
/** * 回调测试,原文出处http://www.cnblogs.com/xrq730/p/6424471.html */ public class CallbackTest { @Test public void testCallback() { Student student = new Ricky(); Teacher teacher = new Teacher(student); teacher.askQuestion(); } }
程式碼運行結果就一行:
<span style="color: #000000;">知道了,你的答案是3<br></span>
簡單總結、分析這個例子是:
(1)老師呼叫學生介面的方法resolveQuestion,向學生提問
(2)學生解決完畢問題之後呼叫老師的回呼方法tellAnswer
這樣一套流程,構成了一種雙向調用的關係。
程式碼分析
分析上面的程式碼,上面的程式碼我這裡做了兩層的抽象:
# (1)將老師進行抽象
- 將老師進行抽象之後,對於學生來說,就不需要關心到底是哪位老師詢問我問題,只要我根據詢問的問題,得出答案,然後告訴提問的老師就可以了,即使老師換了一茬又一茬,對我學生而言都是沒有任何影響的
(2)將學生進行抽象
- 將學生進行抽象之後,對於老師這邊來說就非常靈活,因為老師未必對一個學生進行提問,可能同時對Ricky、Jack、Lucy三個學生進行提問,這樣就可以將成員變數Student改為List
,這樣在提問的時候遍歷Student列表進行提問,然後得到每個學生的回答即可
這個例子是一個典型的體現接口作用的例子,之所以這麼說是因為我想到有些朋友可能不太明白接口的好處,不太明白接口好處的朋友可以重點看一下這個例子,多多理解。
總結起來,回呼的核心就是回呼方將本身即this傳遞給呼叫方,這樣呼叫方就可以在調用完畢之後告訴回調方它想要知道的資訊。回調是一種想法、是一種機制,至於具體如何實現,如何透過程式碼將回呼實現得優雅、實現得可擴展性比較高,一看開發者的個人水平,二看開發者對業務的理解程度。
同步回呼與非同步回呼
#上面的例子,可能有人會提出這樣的疑問:
這個例子需要用什麼回呼啊,使用同步呼叫的方式,學生對象回答完畢問題之後直接把回答的答案回傳給老師對像不就好了?
這個問題的提出沒有任何問題,可以從兩個角度去理解這個問題。
首先,老師不只是想要得到學生的答案怎麼辦?
可能這個老師是個更喜歡聽學生解題思路的老師,在得到學生的答案之前,老師更想先知道學生姓名和學生的解題思路,當然有些人可以說,那我可以定義一個對象,裡面加上學生的姓名和解題思路不就好了。這個說法在我看來有兩個問題:
(1)如果老師想要的資料越來越多,那麼傳回的物件得越來越大,而使用回呼則可以進行資料分離,將一批資料放在回調方法中處理,至於哪些資料依具體業務而定,如果需要增加返回參數,直接在回調方法中增加即可
(2)無法解決老師希望得到學生姓名、學生解題思路先於學生回答的答案的問題
因此我認為簡單的返回某個結果確實沒有必要使用回調而可以直接使用同步調用,但是如果有多種數據需要處理且資料有主次之分,使用回呼會是一種更合適的選擇,優先處理的資料放在回呼方法中先處理掉。
另外一個理解的角度則更加重要,就是標題說的同步回調和非同步回調了。例子是同步回調的例子,意思是老師問Ricky問題,Ricky給答案,老師問下一個同學,得到答案之後繼續問下一個同學,這是正常的場景,但是如果我把場景改一下:
老師並不想One-By-One這樣提問,而是同時向Ricky、Mike、Lucy、Bruce、Kate五位同學提問,讓同學自己思考,哪位同學思考好了就直接告訴老師答案即可。
這種場景相當於是說,同學思考完畢完畢問題要有一個辦法告訴老師,有兩個解決方案:
(1)使用Future Callable的方式,等待非同步執行緒執行結果,這相當於就是同步呼叫的一種變種,因為其本質還是方法返回一個結果,即學生的回答
(2)使用非同步回調,同學回答完畢問題,呼叫回調介面方法告訴老師答案即可。由於老師物件被抽象化成了Callback接口,因此這種做法的擴展性非常好,就像之前說的,即使老師換了換了一茬又一茬,對於同學來說,只關心的是調用Callback接口回傳必要的資訊即可
更多相關知識請關注java基礎教學欄位
以上是Java回呼機制介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。
