<1>
callback就是回调函数,所谓的回调函数,意指先在系统的某个地方对函数进行注册,让系统知道这个函数的
存在,然后在以后,当某个事件发生时,再调用这个函数对事件进行响应。在awt或swing程序中加入监听器,
其实这个过程就是一个时间回调的过程,具体原理不好说,可以参考一下java的command设计模式,Command模
式就是回调机制的一个面向对象的替代品。
------------------------
<2>
一个类通过一种预定义的协议将自己信息注册完成后,
其他对象通过同一协议获取该类信息后,
可以生成该类型的对象直至调用生成的对象的方法。
调用的过程就是回调吧。
JAVA的CALLBACK通过接口来实现。
例:
1.class A,class B
2.class A实现接口operate
3.class B拥有一个参数为operate接口类型的函数test(operate o)
4.class A运行时调用class B中test函数,以自身传入参数
5.class B已取得A,就可以随时回调A所实现的operate接口中的方法
------------------------
<3>
回调就是在调用一个函数时我们可以传递给该方法一个参数,而这个参数是在调用方定义的一个函数,以便于
在被调用的函数中回过头来调用被作为参数传递的函数。
比如C代码如下:
#include <stdio.h>
void fun2(void){
printf("asdf");
}
void fun1(void fun2(void)){
fun2();
}
void fun3(void){
fun1(fun2);
}
void main(){
fun3();
}
如果使用java来实现可采用下面的办法:
interface I{void mA();}
public class Test{
public static void mB(I i){
i.mA();
}
public static void main(String[] args){
mA(new I(){
public void mA(){
System.out.println("asdf");
}
});
}
}
-----------------------
<4>
所谓回调就是主线程新起一个线程后,想让该线程执行完后主线程继续作某事而被新线程调用的一个方法。通
常是主线程的一个静态方法。
具体用法可以参考一下相关多线程编程书。
----------------------
<5>
记得jaxp中响应sax模型事件采用的原理就是callback
比如说解析:
<root>
<elementA>
.........
</elementA>
</root>
当解析元素<root>时,就会触发startelement事件,然后执行你在方法startelement()中所编写的代码.跟着遇上
elementA,然后又调用startelement()
在遇上</elementA>时,调用endelement()方法...遇上</root>时,又去调用
endelement()方法...
如此反复调用特定方法的过程为callback
我记得的就这么多了..
<6>
回调就是你把一个指定的方法交给其他地方调用
参阅设计模式的command模式
简单的代码示范:
定义一个接口:
interface CallbackDemo{
public void callbackMethod(){
}
}
调用的类(Demo):
CallBackDemo cd=null;
public void addCallback(CallBackDemo cd){
this.cd = cd;
}
public void execute(){
cd.callbackMethod();
}
程序入口:
Demo demo = new Demo();
demo.addCallback(new CallbackDemo(){
public void callbackMethod(){
callDetail();
}
});
...
public void callDetail(){
System.out.println("I'am called!");
}
demo.execute();
//你这里调用demo一个方法
//demo类就调用了你这里的callDetail的一个方法
//所以被称为是回调了
回调的目的是把自己的一个方法交到其他对象里面,在C里面是传递方法的地址
===========
<7>
用 Java 接口实现回调函数的等价功能 (转载自IBM)
作者:John D. Mitchell
摘要
在 Java 支持方法指针之前,Java 接口不能提供一种实现回调的好方法。如果您习惯于传递在事件驱动编程模
型中调用的函数指针,则您会喜欢本技巧。
熟悉 MS-Windows 和 X Window System 事件驱动编程模型的开发人员,习惯于传递在某种事件发生时调用(即
“回调”)的函数指针。Java 的面向对象模型目前并不支持方法指针,这样似乎就不可能使用这种很好的机制
。但我们并不是一点办法都没有!
Java 的接口支持提供了一种获得回调的等价功能的机制。其技巧就是:定义一个简单接口,并在该接口中声明
我们要调用的方法。
例如,假定我们希望在某个事件发生时得到通知。我们可以定义一个接口:
public interface InterestingEvent
{
// 这仅是一个常规方法。因此如果需要,
// 它可有返回值,也可接收参数。
public void interestingEvent ();
}
这使得我们可以控制实现该接口的类的任何对象。因此,我们不必关心任何外部类型信息。与在将 C++ 代码用
于 Motif 时使用窗口小部件的数据域来容纳对象指针的难以控制的 C 函数相比,这种方法要好得多。
发出事件信号的类必须等待实现了 InterestingEvent 接口的对象,并在适当时候调用 interestingEvent()
方法。
public class EventNotifier
{
private InterestingEvent ie;
private boolean somethingHappened;
public EventNotifier (InterestingEvent event)
{
// 保存事件对象以备后用。
ie = event;
// 还没有要报告的事件。
somethingHappened = false;
}
//...
public void doWork ()
{
// 检查在别处设置的谓词。
if (somethingHappened)
{
// 通过调用接口的这个方法发出事件信号。
ie.interestingEvent ();
}
//...
}
// ...
}
在上例中,我使用 somethingHappened 谓词来跟踪是否应触发事件。在许多情况下,调用此方法足以保证向
interestingEvent() 发出信号。
希望接收事件通知的代码必须实现 InterestingEvent 接口,并将自身引用传递给事件通知程序。
public class CallMe implements InterestingEvent
{
private EventNotifier en;
public CallMe ()
{
// 创建事件通知程序,并将自身引用传递给它。
en = new EventNotifier (this);
}
// 为事件定义实际的处理程序。
public void interestingEvent ()
{
// 噢!必定发生了感兴趣的事件!
// 执行某些操作 ...
}
//...
}
这就是所要做的全部工作。我希望这个简单的 Java 习惯用法会使您更有信心地转向 Java。
================
<8>
最后理解THINKING IN JAVA中的解释,原文:“在callback机制底下,某个对象被赋予一些信息,这些信息允许该对象在稍后某个时间点上调用原先的对象”,比较苦涩一点,呵呵。
回调函数实际上就是在调用某个函数时,将自己的一个函数(这个函数为回调函数)的地址(在JAVA中称为引用)作为参数传递给那个函数。而那个函数在需要的时候,利用传递的地址调用回调函数中的函数或成员等。Thimking in Java 第二版中文279--280页的那个程序解释得很清楚。
interface Incrementable {
void increment();
}
// Very simple to just implement the interface:
class Callee1 implements Incrementable {
private int i = 0;
public void increment() {
i++;
System.out.println(i);
}
}
class MyIncrement {
public void increment() {
System.out.println("Other operation");
}
public static void f(MyIncrement mi) {
mi.increment();
}
}
// If your class must implement increment() in
// some other way, you must use an inner class:
class Callee2 extends MyIncrement {
private int i = 0;
private void incr() {
i++;
System.out.println(i);
}
private class Closure implements Incrementable {
public void increment() { incr(); }
}
Incrementable getCallbackReference() {
return new Closure();
}
}
class Caller {
private Incrementable callbackReference;
Caller(Incrementable cbh) {
callbackReference = cbh;
}
void go() {
callbackReference.increment();
}
}
public class Callbacks {
public static void main(String[] args) {
Callee1 c1 = new Callee1();
Callee2 c2 = new Callee2();
MyIncrement.f(c2);
Caller caller1 = new Caller(c1);
Caller caller2 =
new Caller(c2.getCallbackReference());
caller1.go();
caller1.go();
caller2.go();
caller2.go();
}
} ///:~
理解一:
在这个函数中Closure就是所谓的回调函数,Caller的构造函数可接收Closuer类型,而正如本例中的Caller caller2 =
new Caller(c2.getCallbackReference());
caller2.go();
就是常用的调用回调函数的手法,caller2实质上调用的是Closuer的increment()方法!
在JAVA中,一般在事件处理中会经常用到回调函数!
理解二:
不就是两个父类有相同的方法increment(),Callee2要同时继承两个increment()则必须将其中一个放在内部类中继承,通过getCallbackReference()返回内部类对象
理解三:
MyIncrement就像曹操,有void increment() 这个东东,但却不是Incrementable(皇帝)里的那个东东
Callee2是曹丕,继承了他父亲的void increment(),当他想称帝(成为一个Incrementable)的时候,这个假的void increment()不行了,所以,他只能用一个内部类来Incrementable,内部类里的increment()才是真的