维基百科上的定义:在计算机程序设计中,回调函数,或简称回调,是指经过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计容许了底层代码调用在高层定义的子程序。程序员
所谓回调,就是客户程序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