日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 消息机制之回调详解

發布時間:2025/3/20 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 消息机制之回调详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 概述

Java 中的回調機制是一個比較常見的機制,只是有可能在你的程序中使用得比較少,在一些大型的框架中回調機制隨處可見。而在之前的博文《Java設計模式——觀察者模式》及 Android 中對 ListView 的相關操作也有回調身影。本文就通過一些具體的實例,慢慢走近 Java 的回調機制。


2. 版權說明

著作權歸作者所有。
商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
本文作者:Q-WHai
發表日期: 2016年4月24日
本文鏈接:http://blog.csdn.net/lemon_tree12138/article/details/51231841
來源:CSDN
更多內容:分類 >> Thinking in java


3. 目錄

文章目錄

  • 1. 概述
  • 2. 版權說明
  • 3. 目錄
    • @[toc]
  • 4. 回調
    • 4.1 同步回調
    • 4.2 異步回調
    • 4.3 閉包與回調
      • 4.3.1 普通調用
      • 4.3.2 回調初試
      • 4.3.3 閉包回調
  • 5. Ref
  • 6.征集

4. 回調

所謂回調:就是A類中調用B類中的某個方法C,然后B類中反過來調用A類中的方法D,D這個方法就叫回調方法。實際在使用的時候,也會有不同的回調形式,比如下面的這幾種。

4.1 同步回調

這里我假設這樣的一種情況。
A 公司的總監 B 跟他的下屬(項目經理 C)說要做一個調研,不過不用 C 自己親力親為。可以讓經理 C 去安排他下面的程序員 D 去完成。
經理 C 找到了程序員 D,并告訴他,現在要完成一個調研任務。并且把調研的結果告訴經理 C。如果有問題,還是要繼續的。
因為這里是 C 讓 D 去做一件事情,之后 D 還是要將結果與 C 進行溝通。這樣就是回調的模型了。下面是一般回調的類圖:

首先我們要有一個回調的接口 CallbackInterface
CallbackInterface.java

public interface CallbackInterface {public boolean check(int result); }

背景里,程序員 D 是要將結果與項目經理 C 進行溝通的,所以這里項目經理需要實現上面的回調接口:
Manager.java

public class Manager implements CallbackInterface {private Programmer programmer = null;public Manager(Programmer _programmer) {this.programmer = _programmer;}/*** 用于 Boss 下達的委托*/public void entrust() {arrange();}// 進行安排下屬進行 study 工作private void arrange() {System.out.println("Manager 正在為 Programmer 安排工作");programmer.study(Manager.this);System.out.println("為 Programmer 安排工作已經完成,Manager 做其他的事情去了。");}@Overridepublic boolean check(int result) {if (result == 5) {return true;}return false;}}

對于程序員 D 來說他需要持有一個經理 C 的引用,以便與他溝通。不過,這里是總監 B 讓 經理 C 去安排的任務。也就是說這里也可以讓其他的經理,比如說經理 B1, B2等等。因為經理都實現了回調的接口,所以這里就可以直接讓程序員 D 持有這個接口就可以了。如下:
Programmer.java

public class Programmer {public void study(CallbackInterface callback) {int result = 0;do {result++;System.out.println("第 " + result + " 次研究的結果");} while (!callback.check(result));System.out.println("調研任務結束");} }

對于總監來說就更簡單明了了,因為這相當于一個 Client 測試:
Boss.java

public class Boss {public static void main(String[] args) {Manager manager = new Manager(new Programmer());manager.entrust();} }

運行結果

Manager 正在為 Programmer 安排工作 第 1 次研究的結果 第 2 次研究的結果 第 3 次研究的結果 第 4 次研究的結果 第 5 次研究的結果 調研任務結束 為 Programmer 安排工作已經完成,Manager 做其他的事情去了。

4.2 異步回調

還是上面的例子,你的項目經理不可能要一直等你調研的結果。而是把這個任務交給你之后,他就不管了,他做他的,你做你的。所以,這里需要對回調的函數進行異步處理。
所以,這里我們需要修改 Programmer 類的代碼,修改如下:
Programmer.java

public class Programmer {public Programmer() {}public void study(CallbackInterface callback) {new StudyThread(callback).start();}// --------------------------- Programmer 正在做的工作 ---------------------------class StudyThread extends Thread {CallbackInterface callback = null;public StudyThread(CallbackInterface _callback) {callback = _callback;}@Overridepublic void run() {int result = 0;do {result++;System.out.println("第 " + result + " 次研究的結果");} while (!callback.check(result));System.out.println("調研任務結束");}} }

運行結果

Manager 正在為 Programmer 安排工作 為 Programmer 安排工作已經完成,Manager 做其他的事情去了。 第 1 次研究的結果 第 2 次研究的結果 第 3 次研究的結果 第 4 次研究的結果 第 5 次研究的結果 調研任務結束

4.3 閉包與回調

閉包(closure)是一個可調用的對象,它記錄了一些信息,這些信息來自于創建它的作用域。

這一部分的內容主要是參見于《Java 編程思想》一書,具體細節大家可以參見此書。
可能很多人在閱讀《Java 編程思想》的時候有一些小迷糊,迷糊的原因可能多種多樣。只是書中的代碼展示部分的確有一些頭痛,沒有什么結構可言(這個只是我個人的閱讀習慣,無關書籍本身的經典性),所以閱讀起來不是很給力吧。下面就我閱讀時的一個小總結。

4.3.1 普通調用

首先,我們可以看看在正常情況下的調用是怎么進行的。
Incrementable.java

interface Incrementable {void increment(); }

這是一個普通的接口(在普通調用里只是普通接口,在回調中就是回調接口,這一點應該很好理解吧)。

Callee1.java

class Callee1 implements Incrementable {private int i = 0;@Overridepublic void increment() {i++;System.out.println(i);}}

Callbacks.java

public class Callbacks {public static void main(String[] args) {Callee1 callee1 = new Callee1();callee1.increment();} }

Callbacks 是一個測試客戶端類,沒啥好說的,直接看上面的代碼。

4.3.2 回調初試

上面的普通調用也沒啥好說的,因為這對于一個正常的 Java 程序員來說都應該是想都不用想就可以搞定的事情。
現在如果要構成回調,那么對于程序的結構或是邏輯的思維上都不可能只有一個被調用者(被回調的對象 Callee1),還需要一個調用者對象。調用者可以像下面這樣來編寫:
Caller.java

class Caller {private Incrementable callbackReference;public Caller(Incrementable _callbackReference) {callbackReference = _callbackReference;}void go() {callbackReference.increment();} }

這里 Caller 持有一個回調接口的引用 callbackReference,就像在上面說到的程序員需要持有一個項目經理的引用,這樣就可以通過這個引用來與項目經理溝通。這里的 callbackReference 也正是起到了這個作用。
現在我們來看看測試類的編寫:
Callbacks.java

public class Callbacks {public static void main(String[] args) {Callee1 callee1 = new Callee1(); Caller caller1 = new Caller(callee1);caller1.go();} }

對于到目前為止的程序代碼,完全可以對比上面項目經理安排程序員調研技術難題的代碼。有異曲同工之妙。

4.3.3 閉包回調

相比于正常的回調,閉包回調的核心自然是在于閉包,也就是對作用域的控制。
現在假設有一個用戶(其他程序員)自定義了一個 MyInCrement 類,同時包含了一個 increment 的方法。如下:

class MyInCrement {public void increment() {System.out.println("MyCrement.increment");}static void f(MyInCrement increment) {increment.increment();} }

另外有一個類 Callee2 繼承自上面這個類:

class Callee2 extends MyInCrement {private int i = 0;public void increment() {super.increment();i++;System.out.println(i);} }

顯而易見這里如果要調用 increment() 方法,就變成了一般的函數調用了。所以這里我們需要修改上面的 Callee2 類,修改的目標就是讓 Callee2 類可以兼容 MyInCrement 類的 increment() 方法和 Incrementable 的 increment() 方法。修改后:

class Callee2 extends MyInCrement {private int i = 0;public void increment() {super.increment();i++;System.out.println(i);}private class Closure implements Incrementable {@Overridepublic void increment() {Callee2.this.increment();}}Incrementable getCallbackReference() {return new Closure();} }

注意,這里的 Closure 類是一個私有的類,這是一個閉包的要素。因為 Closure 類是私有的,那么就要有一個對外開放的接口,用來對 Closure 對象的操作,這里就是上面的 getCallbackReference() 方法。 Caller 類則沒有改變。
對于測試客戶端就直接看代碼吧:

public class Callbacks {public static void main(String[] args) { Callee2 callee2 = new Callee2();Caller caller2 = new Caller(callee2.getCallbackReference());caller2.go();} }

5. Ref

  • http://blog.csdn.net/pi9nc/article/details/23169357
  • http://blog.csdn.net/xiaanming/article/details/8703708/
  • 《Java 編程思想》

6.征集

如果你也需要使用ProcessOn這款在線繪圖工具,可以使用如下邀請鏈接進行注冊:
https://www.processon.com/i/56205c2ee4b0f6ed10838a6d

總結

以上是生活随笔為你收集整理的Java 消息机制之回调详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。