一。回调的形式
1. C、C++和Pascal允许将函数指针作为参数传递给其它函数。JavaScript,Python,和PHP允许简单的将函数名作为参数传递。
2. .NET Framework的语言中,提供了一种型别安全的引用封装,所谓的'委托',用来定义包含类型的函数指针,可以用于实现回调。
3. 使用匿名的代码块(lambda表达式),用以代替在别处定义的独立的回调函数。
4. 在缺少函数类型的参数的面向对象的程序语言中,例如Java,回调可以用传递抽象类或接口来模拟。回调的接收者会调用抽象类或接口的方法,
这些方法由调用者提供实现。这样的对象通常是一些回调函数的集合,同时可能包含它所需要的数据。这种方法在实现某些设计模式时比较有用,
例如访问者模式,观察者模式与策略模式。
二。Java回调实现
public interfaceFetcher {voidfetchData(FetcherCallback callback);
}public interfaceFetcherCallback {voidonData(String receiveString);voidonError(Throwable throwable);
}public class FetcherImpl implementsFetcher {publicWorker worker;publicFetcherImpl(Worker worker){this.worker =worker;
}
@Overridepublic void fetchData(finalFetcherCallback callback) {new Thread(newRunnable() {
@Overridepublic voidrun() {
worker.execute(callback);
}
}).start();
}
}public classWorker {private String str = "";public voidexecute(FetcherCallback callback){try{
init();
callback.onData(str);
}catch(IOException e) {
callback.onError(e);
}
}private void init() throwsIOException{
File file= new File(".\\Worker.java");
FileInputStream fis= newFileInputStream(file);byte[] fileByte = new byte[(int) file.length()];
fis.read(fileByte);
str= newString(fileByte);
}
}
在上面的代码中,我把回调函数放在其他线程上执行。
进行测试:
public classTest {public static voidmain(String[] args){
Fetcher fetcher= new FetcherImpl(newWorker());
fetcher.fetchData(newFetcherCallback() {
@Overridepublic voidonError(Throwable throwable) {
System.out.println("account error : ------------ \n" +throwable.getMessage());
}
@Overridepublic voidonData(String receiveString) {
System.out.println("receive String : ------------- \n" +receiveString );
}
});
}
}