您的位置:首页 > 编程语言 > Java开发

Java回调函数的理解

2012-04-18 07:54 323 查看
所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B姓甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数R告诉S自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。Web
Service以及Java的RMI都用到回调机制,可以访问远程服务器程序。重新举个例子来理解回调:

我遇到了一个问题,便用家里的固话打给我的同事,他说不太清楚,稍后给我回复。我说我一会要出去,你想到了之后打我手机吧。没过多久,我同事就打手机过来告诉了我答案。

下面是代码:

1.先定义一个接口,规定回答问题的条件是打我手机

public interface CallBack {
//通过手机回答
void CallIphone();
}


2.调用者(我):

public class Me {

public void askQuestion(){
System.out.println("拨打固话问1+1=?");
}

}


3.被调用者(同事):

public class You {

public void answer(CallBack callBack){
//进行回调
callBack.CallIphone();
}

public static void main(String[] args) throws InterruptedException {
new Me().askQuestion();
Thread.sleep(3000);
new You().answer(new CallBack() {
//实现接口,即回答问题的方式
public void CallIphone() {
System.out.println("拨打手机回答等于2");
}
});
}
}


4.显示结果

  拨打固话问1+1=?

  拨打手机回答等于2

*********************************************************************************************************************************************************************************

Java回调实现

有个这样的问题:老板(Boss)让工人(Worker)干完活告诉他干的情况如何。

实际上是一个典型的回调问题,Java实现如下:

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2008-7-31 13:18:33

* 事件接口

*/

public interface Event {

/**

* 返回发生事件信息

*

* @return 事件信息

*/

public String happendEvent();

}

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2008-7-31 13:18:14

* 事件A

*/

public class EventAimplements Event {

/**

* 返回发生事件信息

*

* @return 事件信息

*/

public String happendEvent() {

return "发生了事件 EventA!";

}

}

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2008-7-31 13:18:21

* 事件B

*/

public class EventBimplements Event{

/**

* 返回发生事件信息

* @return 事件信息

*/

public String happendEvent() {

return "发生了事件 EventB!";

}

}

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2008-7-31 13:20:48

* 工人

*/

public class Worker {

private Event event; //事件

private String name; //工人姓名

private Boss boss; //工人所属的老板

public Worker(String name, Boss boss) {

this.name = name;

this.boss = boss;

}

/**

* 干活

*/

public void doWork() {

System.out.println(name + " is doing working...");

//工人挺辛苦,干着枯燥乏味的重复工作,哈哈

for (int i = 0; i < 2000000; i++) {

int x = i / 234 + 234;

}

System.out.println(name + " was finished work.");

//向老板说明发生的情况

boss.getWorkerEvent(this, event);

}

public Event getEvent() {

return event;

}

public void setEvent(Event event) {

this.event = event;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2008-7-31 13:26:22

* 老板

*/

public class Boss {

private String name;

public Boss(String name) {

this.name = name;

}

/**

* 老板接收工人的事件

* @param worker 工人

* @param event 事件

*/

public void getWorkerEvent(Worker worker, Event event) {

System.out.println("老板接收到事件信息: "+worker.getName() +": " + event.happendEvent());

}

}

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2008-7-31 13:35:38

* 测试类

*/

public class Test {

public staticvoid main(String args[]){

//初始化老板和工人

Boss boss = new Boss("老板");

Worker worker1= new Worker("张三",boss);

Worker worker2= new Worker("李四",boss);

//捏造两个事件

Event event1 = new EventA();

Event event2 = new EventB();

//事件是工人发出的

worker1.setEvent(event1);

worker2.setEvent(event2);

//工人干活,干完了通知老板干的情况如何

worker1.doWork();

worker2.doWork();

}

}

运行结果:
张三 is doing working...

张三 was finished work.

老板接收到事件信息: 张三: 发生了事件 EventA!

李四 is doing working...

李四 was finished work.

老板接收到事件信息: 李四: 发生了事件 EventB!

Process finished with exit code 0

*********************************************************************************************************************************************************************************

下面使用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()方法就可以实现回调功能

*********************************************************************************************************************************************************************************

回调方法是把功能定义和功能实现分离的一种手段,是一种松耦合的设计思想。

Android中的控件响应就是利用了回调方法。话不多说,直接上代码。

回调方法的接口:

[java]
view plaincopy

public interface ICallBack {
// 回调方法
public void callBackMethod();
}

回调方法的实现类(监听类):

[java]
view plaincopy

/**
* 监听类
* @author zuolongsnail
*/
public class CallBackListener implements ICallBack {

@Override
public void callBackMethod() {
System.out.println("回调");
}
}

回调方法的调用类:

[java]
view plaincopy

/**
* 调用类
* @author zuolongsnail
*/
public class Caller {

private CallBackListener callBack;

public void setCallBack(CallBackListener callBack){
this.callBack = callBack;
}
public void call(){
this.callBack.callBackMethod();
}
}

业务处理类:

[java]
view plaincopy

/**
* 业务处理类
* @author zuolongsnail
*/
public class Main {

public static void main(String[] args) {
Caller caller = new Caller();
caller.setCallBack(new CallBackListener());
// 在业务处理的时候调用
caller.call();
}
}

熟悉Android中Button点击事件处理的同学应该都知道跟上面是一样的。

ICallBack------->OnClickListener接口

CallBackListener--------->实现OnClickListener接口的类

Caller-------->Button对象

Main-------->业务处理类(Activity)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: