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

歡迎訪問 生活随笔!

生活随笔

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

java

Java 回调函数

發布時間:2023/12/9 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 回调函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 什么是回調函數
回調函數(callback Function),顧名思義,用于回調的函數。 回調函數只是一個功能片段,由用戶按照回調函數調用約定來實現的一個函數。回調函數是一個工作流的一部分,由工作流來決定函數的調用(回調)時機。回調函數包含下面幾個特性:
1、屬于工作流的一個部分;
2、必須按照工作流指定的調用約定來申明(定義);
3、他的調用時機由工作流決定,回調函數的實現者不能直接調用回調函數來實現工作流的功能;

2. 回調機制
回調機制是一種常見的設計模型,他把工作流內的某個功能,按照約定的接口暴露給外部使用者,為外部使用者提供數據,或要求外部使用者提供數據。

=======================================================

java回調機制:

軟件模塊之間總是存在著一定的接口,從調用方式上,可以把他們分為三類:同步調用、回調和異步調用。

?

同步調用:一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;

回 調:一種雙向調用模式,也就是說,被調用方在接口被調用時也會調用對方的接口;

異步調用:一種類似消息或事件的機制,不過它的調用方向剛好相反,接口的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的接口)。

回調和異步調用的關系非常緊密:使用回調來實現異步消息的注冊,通過異步調用來實現消息的通知。

========================================================

?

用Java里的例子:

?

package callbackexample; public interface ICallBack { //需要回調的方法 public void postExec(); }

?

另外的一個類:

package callbackexample; public class FooBar { //組合聚合原則 private ICallBack callBack; public void setCallBack(ICallBack callBack) { this.callBack = callBack; doSth(); } public void doSth() { callBack.postExec(); } }

?

?

第二個類在測試類里面,是一個匿名類:

package callbackexample; public class Test { public static void main(String[] args) { FooBar foo = new FooBar(); foo.setCallBack(new ICallBack() { public void postExec() { System.out.println("在Test類中實現但不能被Test的對象引用,而由FooBar對象調用"); } }); } }

上訴的代碼:

1.兩個類:匿名類和FooBar

2.匿名類實現接口ICallBack(在test測試的main方法中用匿名類的形式實現)

3.FooBar 擁有一個參數為ICallBack接口類型的函數setCallBack(ICallBack o)

4.匿名類運行時調用FooBar中setCallBack函數,以自身傳入參數

5.FooBar已取得匿名類,就可以隨時回調匿名類中所實現的ICallBack接口中的方法

==================================

1。首先回調方法的概念與“構造方法”的概念是不一樣的,它不是指java中某個具有特殊意義或用途的方法。
2。稱它為方法的“回調”更恰當一些 ,它是指方法的一種調用方式。任何一個被“回調”的方法,皆可稱之為“回調方法”
3。方法的回調通常發生在“java接口”和“抽象類”的使用過程中。
假設有接口名為 ICallBack 其中有方法名為postExec()
有類Myclass 實現了該接口,也就是一定實現了postExec()這個方法。現在有另一個類FooBar它有個方法 setCallBack(ICallBack callBack) ,并且setCallBack方法調用了callBack的postExec()方法。
如果現在,我們使用一個Myclass 的實例myClass,將它作為參數帶入到setCallBack(ICallBack callBack)方法中,我們就說setCallBack(ICallBack callBack)方法回調了myClass的postExec()方法。

?

以下轉自:http://kidult.javaeye.com/blog/148982

下面使用java回調函數來實現一個測試函數運行時間的工具類:
如果我們要測試一個類的方法的執行時間,通常我們會這樣做:
java 代碼
public?? class TestObject {??
??? /**??
???? * 一個用來被測試的方法,進行了一個比較耗時的循環??
???? */???
??? public?? static?? void testMethod(){??
??????? for ( int i= 0 ; i< 100000000 ; i++){??
??????????????
??????? }??
??? }??
??? /**??
???? * 一個簡單的測試方法執行時間的方法??
???? */???
??? public?? void testTime(){??
??????? long begin = System.currentTimeMillis(); //測試起始時間???
??????? testMethod(); //測試方法???
??????? long end = System.currentTimeMillis(); //測試結束時間???
??????? System.out.println("[use time]:" + (end - begin)); //打印使用時間???
??? }??
??????
??? public?? static?? void main(String[] args) {??
??????? TestObject test=new TestObject();??
??????? test.testTime();??
??? }??
}??


大家看到了testTime()方法,就只有"//測試方法"是需要改變的,下面我們來做一個函數實現相同功能但更靈活:
首先定一個回調接口:
java 代碼
public?? interface CallBack {??
??? //執行回調操作的方法???
??? void execute();??
}??


然后再寫一個工具類:
java 代碼
public?? class Tools {??
??????
??? /**??
???? * 測試函數使用時間,通過定義CallBack接口的execute方法??
???? * @param callBack??
???? */???
??? public?? void testTime(CallBack callBack) {??
??????? long begin = System.currentTimeMillis(); //測試起始時間???
??????? callBack.execute(); ///進行回調操作???
??????? long end = System.currentTimeMillis(); //測試結束時間???
??????? System.out.println("[use time]:" + (end - begin)); //打印使用時間???
??? }??
??????
??? public?? static?? void main(String[] args) {??
??????? Tools tool = new Tools();??
??????? tool.testTime(new CallBack(){??
??????????? //定義execute方法???
??????????? public?? void execute(){??
??????????????? //這里可以加放一個或多個要測試運行時間的方法???
??????????????? TestObject.testMethod();??
??????????? }??
??????? });??
??? }??
}??

大家看到,testTime()傳入定義callback接口的execute()方法就可以實現回調功能

==============================================================

如果說匿名內部類的方式不容易理解,可以看下面的例子

其技巧就是:定義一個簡單接口,并在該接口中聲明我們要調用的方法。

下面舉一個例子:

假定我們希望在某個事件發生時得到通知。我們可以定義一個接口:

/*
* 在某個事件發生時得到通知.
*/
public interface InterestingEvent {
   public void interestingEvent();
}

此接口中的方法,是個沒有返回值的也沒有任何參數,如果您愿意也可以有返回值,也可以帶參數.這就要看具體需求而定.

這使得我們可以控制實現該接口的類的任何對象。因此,我們不必關心任何外部類型信息。與在將 C++ 代碼用于Motif 時使用窗口小部件的數據域來容納對象指針的難以控制的 C 函數相比,這種方法要好得多。

實現接口的代碼如下:

public class CallMe implements InterestingEvent {
??????? public CallMe() {
   }

   public void interestingEvent() {
?????    System.out.println("發生了打印事件,哈哈");
  }

}

public class CallYou implements InterestingEvent {
?????? public CallYou() {
??   }

public void interestingEvent() {
??
????? System.out.println("發生了查詢事件,哈哈");
}

}

發出事件信號的類必須等待實現了 InterestingEvent 接口的對象,并在適當時候調用 interestingEvent() 方法。

public class EventNotifier {
private InterestingEvent ie;
private boolean somethingHappened ;
public EventNotifier() {
?? somethingHappened = true ;
}
public void setInterestingEvent(InterestingEvent ie){
?? this.ie = ie ;
}
public void doWork(){
?? if(somethingHappened){
??? ie.interestingEvent();
?? }
}

}

下面做一下測試.

public class Test {

/**
* @param args
*/
public static void main(String[] args) {
?? CallMe cm = new CallMe();
?? CallYou cy = new CallYou();
?? EventNotifier en = new EventNotifier();

?? en.setInterestingEvent(cm);
?? en.doWork();
?? en.setInterestingEvent(cy);
?? en.doWork();
}

}

此測試在發生指定的調用CalMe事件時,就掃行CallMe下的命令,如發生CallYou事件時,就調用CallYou下的命令.此種方法可以結合Command模式.實現MS-Windows 和 X Window System 事件驅動編程模型.

?

?

?

回調方法另一測試用例:

熟悉MS-Windows和X Windows事件驅動設計模式的開發人員,通常是把一個方法的指針傳遞給事件源,當某一事件發生時來調用這個方法(也稱為“回調”)。Java的面向對象的模型目前不支持方法指針,似乎不能使用這種方便的機制。

Java支持interface,通過interface可以實現相同的回調。其訣竅就在于定義一個簡單的interface,申明一個被希望回調的方法。


例如,假定當某一事件發生時會得到通知,我們可以定義一個interface:
public interface InterestingEvent {
??? // 這只是一個普通的方法,可以接收參數、也可以返回值
??? public void interestingEvent();
}

這樣我們就有了任何一個實現了這個接口類對象的手柄grip。

當一事件發生時,需要通知實現InterestingEvent 接口的對象,并調用interestingEvent() 方法。
class EventNotifier {
??? private InterestingEvent ie;
??? private boolean somethingHappened;

??? public EventNotifier(InterestingEvent event) {
??? ??? ie = event;
??? ??? somethingHappened = false;
??? }

??? public void doWork() {
??? ??? if (somethingHappened) {
??? ??? ??? // 事件發生時,通過調用接口的這個方法來通知
??? ??? ??? ie.interestingEvent();
??? ??? }??? ???
??? }
}

在這個例子中,用somethingHappened 來標志事件是否發生。

希望接收事件通知的類必須要實現InterestingEvent 接口,而且要把自己的引用傳遞給事件的通知者。
public class CallMe implements InterestingEvent {
??? private EventNotifier en;

??? public CallMe() {
??? ??? // 新建一個事件通知者對象,并把自己傳遞給它
??? ??? en = new EventNotifier(this);
??? }

??? // 實現事件發生時,實際處理事件的方法
??? public void interestingEvent() {
??? ??? // 這個事件發生了,進行處理
??? }
}

以上是通過一個非常簡單的例子來說明Java中的回調的實現。

當然,也可以在事件管理或事件通知者類中,通過注冊的方式來注冊多個對此事件感興趣的對象。

1. 定義一個接口InterestingEvent ,回調方法nterestingEvent(String event) 簡單接收一個String 參數。

interface InterestingEvent {
??? public void interestingEvent(String event);
}

2. 實現InterestingEvent接口,事件處理類

class CallMe implements InterestingEvent {
??? private String name;
??? public CallMe(String name){
??? ??? this.name = name;
??? }???
??? public void interestingEvent(String event) {
??? ??? System.out.println(name + ":[" +event? + "] happened");
??? }
}

3. 事件管理者,或事件通知者

class EventNotifier {
??? private List<CallMe> callMes = new ArrayList<CallMe>();
???
??? public void regist(CallMe callMe){
??? ??? callMes.add(callMe);
??? }
???
??? public void doWork(){
??? ??? for(CallMe callMe: callMes) {
??? ??? ??? callMe.interestingEvent("sample event");
??? ??? }
??? }???
}

4. 測試

public class CallMeTest {
??? public static void main(String[] args) {
??? ??? EventNotifier ren = new EventNotifier();
??? ??? CallMe a = new CallMe("CallMe A");
??? ??? CallMe b = new CallMe("CallMe B");

??? ??? // regiest
??? ??? ren.regist(a);
??? ??? ren.regist(b);
??? ???
??? ??? // test
??? ??? ren.doWork();??? ???
??? }
}

總結

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

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