java回调
2016-03-10 00:00
357 查看
回调的定义:
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口(有待商榷);异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。
一般在 API 中使用回调。
回调允许调用者主动调用客户程序的代码。
它的触发机制类似抛出事件。
举个例子:当你要系统枚举系统中的所有窗口,使用回调后,系统每找到一个窗口就把控制权交给你,由你的回调程序处理这个窗口,这样大大简化了程序。
再比如:一个端口监听程序,如果使用回调,当有数据时,才需要运行主程序的代码。而不用回调,则主程序每隔一定时间都要去判断是否有数据到达,程序不但复杂,而且浪费资源。
回调程序在API的地位相当于DOS的中断处理程序。
回调程序的实质是提供一个参数作为回调函数的入口地址。由调用的函数根据地址反过来调用客户程序。
下面是
John D. Mitchell的举例说明:
在MS-Windows或者X-Window系统的事件驱动模型中,当某些事件发生的时候,开发人员已经熟悉通过传递函数指针来调用处理方法。而在Java的面向对象的模型中,不能支持这种方法,因而看起来好像排除了使用这种比较舒服的机制,但事实并非如此。
Java的接口提供了一种很好的机制来让我们达到和回调相同的效果。这个诀窍就在于定一个简单的接口,在接口之中定义一个我们希望调用的方法。
举个例子来说,假设当一个事件发生的时候,我们想它被通知,那么我们定义一个接口:
这就给我们一个控制实现了该接口的所有类的对象的控制点。因此,我们不需要关心任何和自己相关的其它外界的类型信息。这种方法比C函数更好,因为在C++风格的代码中,需要指定一个数据域来保存对象指针,而Java中这种实现并不需要。
发出事件的类需要对象实现InterestingEvent接口,然后调用接口中的interestingEvent ()方法。
在这个例子中,我们使用了somethingHappened这个标志来跟踪是否事件应该被激发。在许多事例中,被调用的方法能够激发interestingEvent()方法才是正确的。
希望收到事件通知的代码必须实现InterestingEvent接口,并且正确的传递自身的引用到事件通知器。
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口(有待商榷);异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。
一般在 API 中使用回调。
回调允许调用者主动调用客户程序的代码。
它的触发机制类似抛出事件。
举个例子:当你要系统枚举系统中的所有窗口,使用回调后,系统每找到一个窗口就把控制权交给你,由你的回调程序处理这个窗口,这样大大简化了程序。
再比如:一个端口监听程序,如果使用回调,当有数据时,才需要运行主程序的代码。而不用回调,则主程序每隔一定时间都要去判断是否有数据到达,程序不但复杂,而且浪费资源。
回调程序在API的地位相当于DOS的中断处理程序。
回调程序的实质是提供一个参数作为回调函数的入口地址。由调用的函数根据地址反过来调用客户程序。
下面是
John D. Mitchell的举例说明:
在MS-Windows或者X-Window系统的事件驱动模型中,当某些事件发生的时候,开发人员已经熟悉通过传递函数指针来调用处理方法。而在Java的面向对象的模型中,不能支持这种方法,因而看起来好像排除了使用这种比较舒服的机制,但事实并非如此。
Java的接口提供了一种很好的机制来让我们达到和回调相同的效果。这个诀窍就在于定一个简单的接口,在接口之中定义一个我们希望调用的方法。
举个例子来说,假设当一个事件发生的时候,我们想它被通知,那么我们定义一个接口:
public interface InterestingEvent { // This is just a regular method so it can return something or // take arguments if you like. public void interestingEvent (); } |
发出事件的类需要对象实现InterestingEvent接口,然后调用接口中的interestingEvent ()方法。
public class EventNotifier { private InterestingEvent ie; private boolean somethingHappened; public EventNotifier (InterestingEvent event) { // Save the event object for later use. ie = event; // Nothing to report yet. somethingHappened = false; } public void doWork () { // Check the predicate, which is set elsewhere. if (somethingHappened) { ie.interestingEvent (); } //... } // ... } |
希望收到事件通知的代码必须实现InterestingEvent接口,并且正确的传递自身的引用到事件通知器。
public class CallMe implements InterestingEvent { private EventNotifier en; public CallMe () { // Create the event notifier and pass ourself to it. en = new EventNotifier (this); } // Define the actual handler for the event. public void interestingEvent () { // Wow! Something really interesting must have occurred! // Do something... } //... } |
相关文章推荐
- 用JAVA实现堆栈(数组篇)
- javassist:增强型的java反射工具,获取方法参数名
- 小议 java:comp/env
- Java排序汇总
- java.util.ResourceBundle使用详解
- java获取服务器一些信息的方法
- 验证日期的Java正则表达式
- Eclipse插件Ant里运用ftp遇到的问题
- java中获取文件路径的几种方式
- Struts2权限控制
- eclipse 设置启动时选择打开工作空间 删除无用工作空间
- Java操作数据库的元数据
- ECLIPSE取消自动更新
- Java 1.5中显示数组
- Eclipse launch configuration----Eclipse运行外部工具
- 怎么看java程序的运行时间
- Java 多态
- java你可能不知道的事(2)--堆和栈
- spring bean生命周期
- Eclipse中使用recyclerview时出现Caused by: java.lang.NoClassDefFoundError: android.support.v7.recyclerview.R$styleable