維基百科上的定義:在計算機程序設計中,回調函數,或簡稱回調,是指經過函數參數傳遞到其它代碼的,某一塊可執行代碼的引用。這一設計容許了底層代碼調用在高層定義的子程序。程序員
所謂回調,就是客戶程序C調用服務程序S中的某個函數A,而後S又在某個時候反過來調用C中的某個函數B,對於C來講,這個B便叫作回調函數。通常說來,C不會本身調用B,C提供B的目的就是讓S來調用它,並且是C不得不提供。因爲S並不知道C提供的B姓甚名誰,因此S會約定B的接口規範(函數原型),而後由C提早經過S的一個函數R告訴S本身將要使用B函數,這個過程稱爲回調函數的註冊,R稱爲註冊函數。Web Service以及Java的RMI都用到回調機制,能夠訪問遠程服務器程序。回調更多的應用就是結合異步。編程
下面舉個通俗的例子:某天,我打電話向你請教問題,你一時想不出解決方法,我又不能拿着電話在那裏傻等,因而咱們約定:等你想出辦法後打手機通知我,這樣,我就掛掉電話辦其它事情去了。過了XX分鐘,個人手機響了,你興高采烈的說問題已經搞定,應該如此這般處理。故事到此結束。這個例子說明了「異步+回調」的編程模式。其中,你後來打手機告訴我結果即是一個「回調」過程;個人手機號碼必須在之前告訴你,這即是註冊回調函數;個人手機號碼應該有效而且手機可以接收到你的呼叫,這是回調函數必須符合接口規範。服務器
下面給出兩個示例。異步
示例1:ide
1. 首先定義一個類Caller,按照上面的定義就是程序員A寫的程序a,這個類裏面保存一個接口引用。函數
1 public class Caller { 2 private MyCallInterface callInterface; 3 4 public Caller() { 5 } 6 7 public void setCallFunc(MyCallInterface callInterface) { 8 this.callInterface = callInterface; 9 } 10 11 public void call() { 12 callInterface.printName(); 13 } 14 }
2. 固然須要接口的定義,爲了方便程序員B根據個人定義編寫程序實現接口。工具
1 public interface MyCallInterface { 2 public void printName(); 3 }
3. 第三是定義程序員B寫的程序b測試
1 public class Client implements MyCallInterface { 2 3 @Override 4 public void printName() { 5 System.out.println("This is the client printName method"); 6 } 7 }
4. 測試以下this
1 public class Test { 2 public static void main(String[] args) { 3 Caller caller = new Caller(); 4 caller.setCallFunc(new Client()); 5 caller.call(); 6 } 7 }
看到這裏應該明白什麼是回調了,有些文章介紹的很好,可是剛開始沒看明白,是由於把第3步的類省略,直接寫成匿名類了。spa
5. 在測試方法中直接使用匿名類,省去第3步。
1 public class Test { 2 public static void main(String[] args) { 3 Caller caller = new Caller(); 4 // caller.setCallFunc(new Client()); 5 caller.setCallFunc(new MyCallInterface() { 6 public void printName() { 7 System.out.println("This is the client printName method"); 8 } 9 }); 10 caller.call(); 11 } 12 }
示例2:
若是咱們要測試一個類的方法的執行時間,一般咱們會這樣作:
1 public class TestObject { 2 /** 3 * 一個用來被測試的方法,進行了一個比較耗時的循環 4 */ 5 public static void testMethod(){ 6 for ( int i= 0 ; i< 100000000 ; i++){ 7 8 } 9 } 10 /** 11 * 一個簡單的測試方法執行時間的方法 12 */ 13 public void testTime(){ 14 long begin = System.currentTimeMillis(); //測試起始時間 15 testMethod(); //測試方法 16 long end = System.currentTimeMillis(); //測試結束時間 17 System.out.println("[use time]:" + (end - begin)); //打印使用時間 18 } 19 20 public static void main(String[] args) { 21 TestObject test=new TestObject(); 22 test.testTime(); 23 } 24 }
你們看到了testTime()方法,就只有"//測試方法"是須要改變的,下面咱們來作一個函數實現相同功能但更靈活:
首先定一個回調接口:
1 public interface CallBack { 2 //執行回調操做的方法 3 void execute(); 4 }
而後再寫一個工具類:
1 public class Tools { 2 3 /** 4 * 測試函數使用時間,經過定義CallBack接口的execute方法 5 * @param callBack 6 */ 7 public void testTime(CallBack callBack) { 8 long begin = System.currentTimeMillis(); //測試起始時間 9 callBack.execute(); ///進行回調操做 10 long end = System.currentTimeMillis(); //測試結束時間 11 System.out.println("[use time]:" + (end - begin)); //打印使用時間 12 } 13 14 public static void main(String[] args) { 15 Tools tool = new Tools(); 16 tool.testTime(new CallBack(){ 17 //定義execute方法 18 public void execute(){ 19 //這裏能夠加放一個或多個要測試運行時間的方法 20 TestObject.testMethod(); 21 } 22 }); 23 } 24 25 }
testTime()傳入定義callback接口的execute()方法就能夠實現回調功能
參考:http://kidult.iteye.com/blog/148982
http://blog.csdn.net/allen_zhao_2012/article/details/8056665