java回調函數,java回調函數例子

本文目錄一覽:

java設計模式-回調、事件監聽器、觀察者模式

轉自( )

背景

關於設計模式,之前筆者寫過工廠模式,最近在使用gava ListenableFuture時發現事件監聽模型特別有意思,於是就把事件監聽、觀察者之間比較了一番,發現這是一個非常重要的設計模式,在很多框架里扮演關鍵的作用。

回調函數

為什麼首先會講回調函數呢?因為這個是理解監聽器、觀察者模式的關鍵。

什麼是回調函數

所謂的回調,用於回調的函數。 回調函數只是一個功能片段,由用戶按照回調函數調用約定來實現的一個函數。 有這麼一句通俗的定義:就是程序員A寫了一段程序(程序a),其中預留有回調函數接口,並封裝好了該程序。程序員B要讓a調用自己的程序b中的一個方法,於是,他通過a中的接口回調自己b中的方法。

舉個例子:

這裡有兩個實體:回調抽象接口、回調者(即程序a)

回調接口(ICallBack )

public interface ICallBack {

public void callBack();

}

回調者(用於調用回調函數的類)

public class Caller {

}

回調測試:

public static void main(String[] args) {

Caller call = new Caller();

call.call(new ICallBack(){

控制台輸出:

start…

終於回調成功了!

end…

還有一種寫法

或實現這個ICallBack接口類

class CallBackC implements ICallBack{

@Override

public void callBack() {

System.out.println(“終於回調成功了!”);

}

}

有沒有發現這個模型和執行一個線程,Thread很像。 沒錯,Thread就是回調者,Runnable就是一個回調接口。

new Thread(new Runnable(){

@Override

public void run() {

System.out.println(“回調一個新線程!”);

}}).start();

Callable也是一個回調接口,原來一直在用。 接下來我們開始講事件監聽器

事件監聽模式

什麼是事件監聽器

監聽器將監聽自己感興趣的事件一旦該事件被觸發或改變,立即得到通知,做出響應。例如:android程序中的Button事件。

java的事件監聽機制可概括為3點:

java的事件監聽機制涉及到 事件源,事件監聽器,事件對象 三個組件,監聽器一般是接口,用來約定調用方式

當事件源對象上發生操作時,它將會調用事件監聽器的一個方法,並在調用該方法時傳遞事件對象過去

事件監聽器實現類,通常是由開發人員編寫,開發人員通過事件對象拿到事件源,從而對事件源上的操作進行處理

舉個例子

這裡我為了方便,直接使用jdk,EventListener 監聽器,感興趣的可以去研究下源碼,非常簡單。

監聽器接口

public interface EventListener extends java.util.EventListener {

//事件處理

public void handleEvent(EventObject event);

}

事件對象

public class EventObject extends java.util.EventObject{

private static final long serialVersionUID = 1L;

public EventObject(Object source){

super(source);

}

public void doEvent(){

System.out.println(“通知一個事件源 source :”+ this.getSource());

}

}

事件源

事件源是事件對象的入口,包含監聽器的註冊、撤銷、通知

public class EventSource {

//監聽器列表,監聽器的註冊則加入此列表

private VectorEventListener ListenerList = new VectorEventListener();

//註冊監聽器

public void addListener(EventListener eventListener){

ListenerList.add(eventListener);

}

//撤銷註冊

public void removeListener(EventListener eventListener){

ListenerList.remove(eventListener);

}

//接受外部事件

public void notifyListenerEvents(EventObject event){

for(EventListener eventListener:ListenerList){

eventListener.handleEvent(event);

}

}

}

測試執行

public static void main(String[] args) {

EventSource eventSource = new EventSource();

}

控制台顯示:

通知一個事件源 source :openWindows

通知一個事件源 source :openWindows

doOpen something…

到這裡你應該非常清楚的了解,什麼是事件監聽器模式了吧。 那麼哪裡是回調接口,哪裡是回調者,對!EventListener是一個回調接口類,handleEvent是一個回調函數接口,通過回調模型,EventSource 事件源便可回調具體監聽器動作。

有了了解後,這裡還可以做一些變動。 對特定的事件提供特定的關注方法和事件觸發

public class EventSource {

public void onCloseWindows(EventListener eventListener){

System.out.println(“關注關閉窗口事件”);

ListenerList.add(eventListener);

}

}

public static void main(String[] args) {

EventSource windows = new EventSource();

/**

* 另一種實現方式

*/

//關注關閉事件,實現回調接口

windows.onCloseWindows(new EventListener(){

}

這種就類似於,我們的窗口程序,Button監聽器了。我們還可以為單擊、雙擊事件定製監聽器。

觀察者模式

什麼是觀察者模式

觀察者模式其實原理和監聽器是一樣的,使用的關鍵在搞清楚什麼是觀察者、什麼是被觀察者。

觀察者(Observer)相當於事件監器。有個微博模型比較好理解,A用戶關注B用戶,則A是B的觀察者,B是一個被觀察者,一旦B發表任何言論,A便可以獲得。

被觀察者(Observable)相當於事件源和事件,執行事件源通知邏輯時,將會回調observer的回調方法update。

舉個例子

為了方便,同樣我直接使用jdk自帶的Observer。

一個觀察者

public class WatcherDemo implements Observer {

@Override

public void update(Observable o, Object arg) {

if(arg.toString().equals(“openWindows”)){

System.out.println(“已經打開窗口”);

}

}

}

被觀察者

Observable 是jdk自帶的被觀察者,具體可以自行看源碼和之前的監聽器事件源類似。

主要方法有

addObserver() 添加觀察者,與監聽器模式類似

notifyObservers() 通知所有觀察者

類Watched.java的實現描述:被觀察者,相當於事件監聽的事件源和事件對象。又理解為訂閱的對象 主要職責:註冊/撤銷觀察者(監聽器),接收主題對象(事件對象)傳遞給觀察者(監聽器),具體由感興趣的觀察者(監聽器)執行

/**

}

測試執行

public static void main(String[] args) {

Watched watched = new Watched();

WatcherDemo watcherDemo = new WatcherDemo();

watched.addObserver(watcherDemo);

watched.addObserver(new Observer(){

@Override

public void update(Observable o, Object arg) {

if(arg.toString().equals(“closeWindows”)){

System.out.println(“已經關閉窗口”);

}

}

});

//觸發打開窗口事件,通知觀察者

watched.notifyObservers(“openWindows”);

//觸發關閉窗口事件,通知觀察者

watched.notifyObservers(“closeWindows”);

控制台輸出:

已經打開窗口

已經關閉窗口

總結

從整個實現和調用過程來看,觀察者和監聽器模式基本一樣。

有興趣的你可以基於這個模型,實現一個簡單微博加關注和取消的功能。 說到底,就是事件驅動模型,將調用者和被調用者通過一個鏈表、回調函數來解耦掉,相互獨立。

“你別來找我,有了我會找你”。

整個設計模式的初衷也就是要做到低耦合,低依賴。

再延伸下,消息中間件是什麼一個模型? 將生產者+服務中心(事件源)和消費者(監聽器)通過消息隊列解耦掉. 消息這相當於具體的事件對象,只是存儲在一個隊列里(有消峰填谷的作用),服務中心回調消費者接口通過拉或取的模型響應。 想必基於這個模型,實現一個簡單的消息中間件也是可以的。

還比如gava ListenableFuture,採用監聽器模式就解決了future.get()一直阻塞等待返回結果的問題。

有興趣的同學,可以再思考下觀察者和責任鏈之間的關係, 我是這樣看的。

同樣會存在一個鏈表,被觀察者會通知所有觀察者,觀察者自行處理,觀察者之間互不影響。 而責任鏈,講究的是擊鼓傳花,也就是每一個節點只需記錄繼任節點,由當前節點決定是否往下傳。 常用於工作流,過濾器web filter。

在java中回調函數怎麼理解,android中的回調函數和java中有區別嗎?

可以理解為一種邏輯的延伸。例如在java中已onXXX開頭的方法。

這些方法通常是一種信息的延伸。預示着某些事件發生了。這些信息通常是某些大邏輯的一部分。而其他部分不需要開發者考慮。

比如onCreate方法,了解了生命周期就會知道他是整個activity第一個執行的代碼。那麼他究竟是誰調用的。這個一般不需要考慮。只需要了解系統在調用即可。 而這個方法在執行的時候。需要你去補充這個方法的實現。 所以相當於你完成了事件的餘下部分。

比如早晨需要在鬧鈴響之後起床。那麼你可以設置一個timer來記時或者是一個線程來跑。當發現到的時候。需要把這個事件拋出去。至於誰來處理。這不是鬧鈴考慮的範圍。他的作用就是觸發事件.至於處理。那麼需要處理這個事件的。可以用很多方法來建立關聯的句柄。

比如。通過接口的實現。繼承。或者像android里的廣播。

回調函數描述的是一種模式。這個和語言或平台無關。所以android中和java中是一樣的。C++中也有。

java中怎樣定義回調函數

程序員A寫了一段程序(程序a),其中預留有回調函數接口,並封裝好了該程序。程序員B要讓a調用自己的程序b中的一個方法,於是,他通過a中的接口回調自己b中的方法。目的達到。在C/C++中,要用回調函數,被掉函數需要告訴調用者自己的指針地址,但在JAVA中沒有指針,怎麼辦?我們可以通過接口(interface)來實現定義回調函數。

假設我是程序員A,以下是我的程序a:

[java] view plaincopyprint?

public class Caller

{

public MyCallInterface mc;

public void setCallfuc(MyCallInterface mc)

{

this.mc= mc;

}

public void call(){

this.mc.method();

}

}

還需要定義一個接口,以便程序員B根據我的定義編寫程序實現接口。

public interface MyCallInterface

{

public void method();

}

於是,程序員B只需要實現這個接口就能達到回調的目的了:

public class B implements MyCallInterface

{

public void method()

{

System.out.println(“回調”);

}

public static void main(String args[])

{

Caller call = new Caller();

call.setCallfuc(new B());

call.call();

}

}

Java中什麼是接口回調?

可以把使用某一接口的類創建的對象的引用賦給該接口聲明的接口變量,那麼該接口變量就可以調用被類實現的接口的方法。

實際上,當接口變量調用被類實現的接口中的方法時,就是通知相應的對象調用接口的方法,這一過程稱為對象功能的接口回調。

Java語言特點

Java看起來設計得很像C++,但是為了使語言小和容易熟悉,設計者們把C++語言中許多可用的特徵去掉了,這些特徵是一般程序員很少使用的。

例如,Java不支持go to語句,代之以提供break和continue語句以及異常處理。Java還剔除了C++的操作符過載(overload)和多繼承特徵,並且不使用主文件,免去了預處理程序。因為Java沒有結構,數組和串都是對象,所以不需要指針。 

Java 什麼是回調

所謂回調,就是客戶程序Client調用服務程序Service中的某個方法A,然後Service又在某個時候反過來調用Client中的某個方法B,對於Client來說,這個B便叫做回調函數

回調實現的步驟

1、定義回調接口和回調方法

2、Client實現回調接口和回調方法,並在Client中包含Service引用,通過引用調用Servie中的方法並且必須傳入一個當前對象Client(因為當前對象實現了CallBack接口所以也屬於接口對象)

3、在Service中定義一個接口對象並在方法中對初始化(將Client傳過來的當前對象賦值給接口對象),通過接口對象調用接口中方法(調用的Client實現的接口方法)

4、測試

原創文章,作者:HXND,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/135225.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
HXND的頭像HXND
上一篇 2024-10-04 00:11
下一篇 2024-10-04 00:11

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Python中capitalize函數的使用

    在Python的字符串操作中,capitalize函數常常被用到,這個函數可以使字符串中的第一個單詞首字母大寫,其餘字母小寫。在本文中,我們將從以下幾個方面對capitalize函…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • 三角函數用英語怎麼說

    三角函數,即三角比函數,是指在一個銳角三角形中某一角的對邊、鄰邊之比。在數學中,三角函數包括正弦、餘弦、正切等,它們在數學、物理、工程和計算機等領域都得到了廣泛的應用。 一、正弦函…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29

發表回復

登錄後才能評論