Java中的CallBack机制
callback的官方解释是,“将一段代码作为参数传递,而这段代码将会在某个时刻被执行。”
程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序。程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法。
下面是程序员A写的程序a:
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只需要实现接口就能达到回调的目的,程序b如下:
public class B implements MyCallInterface{
public void method() {
System.out.println("如果打印这句话,说明class B 通过class caller中的接口调用了自己中的方法");
}
public static void main(String args[]) {
Caller call = new Caller();
call.setCallfuc(new B());
call.call();
}
}
举个通俗的例子:
某天,我打电话向你请教问题,当然是个难题,:),你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。
这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。
下面一段代码,测试了一个类的方法的执行时间:
public class TestProject {
/**
* 用来被测试的方法,此方法进行的是耗时操作
*/
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("所需时间:"+(end - begin)+"毫秒");
}
public static void main(String args[]){
TestProject test = new TestProject();
test.testTime();
}
}
下面的程序同样能实现上面的功能,但更灵活,上面的“//测试方法”是需要改变的。首先定义一个接口CallBack :
public interface CallBack {
void execute();
}
再写一个工具类,代码如下:
public class Tools {
/**
* 测试函数使用时间,通过callback中的execute方法
*/
public void testTime(CallBack callback){
long begin = System.currentTimeMillis();//测试起始时间
callback.execute();//进行回调操作
long end = System.currentTimeMillis();//测试终止时间
System.out.println("所需时间:"+(end - begin)+"毫秒");
}
public static void main(String args[]){
Tools tool = new Tools();
tool.testTime(new CallBack() {
//定义execute()方法
public void execute() {
TestProject.testMethod();
}
});
}
}
如上所示,testTime()传入定义callback接口的execute()方法就可以实现回调功能,调用了TestProject类中的testMethod()方法。