關於對Java中回撥函式的理解
先來看幾段程式:
1. 首先定義一個類Caller,這個類裡面儲存一個介面引用。
public class Caller {
private MyCallInterface callInterface;
public Caller() {
}
public void setCallFunc(MyCallInterface callInterface) {
this.callInterface = callInterface;
}
public void call() {
callInterface.printName();
}
}
2. 當然需要介面的定義,為了方便編寫程式實現介面。
public interface MyCallInterface {
public void printName();
}
3.
public class Client implements MyCallInterface {
@Override
public void printName() {
System.out.println("This is the client printName method");
}
}
4. 測試如下
public class Test {
public static void main(String[] args) {
Caller caller = new Caller();
caller.setCallFunc(new Client());
caller.call();
}
}
看到這裡應該明白什麼是回調了,有些文章介紹的很好,但是剛開始沒看明白,是因為把第3步的類省略,直接寫成匿名類了。
5. 在測試方法中直接使用匿名類,省去第3步。
public class Test {
public static void main(String[] args) {
Caller caller = new Caller();
// caller.setCallFunc(new Client());
caller.setCallFunc(new MyCallInterface() {
public void printName() {
System.out.println("This is the client printName method");
}
});
caller.call();
}
}
再來看下面這幾段程式:
例子:
Java程式碼
//回撥函式介面及方法
public interface ICallback {
public void func();
}
//回撥函式介面實現類
public class ClassWithCallbackFunction implements ICallback{
public ClassWithCallbackFunction() {
}
public void func(){
System.out.println("cccccccccccccccccc");
}
}
public class Caller {
private ICallback callback; //私有介面成員
public void setCallback(ICallback callback) {
this.callback = callback; //介面成員的實現:從外部傳入
}
public void doCallback() { //回撥介面成員的方法
callback.func();
}
}
}
public class MainClass {
public MainClass() {
}
public static void main(String[] args) {
Caller caller = new Caller();
caller.setCallback(new ClassWithCallbackFunction() {
public void func() {
System.out.println("aaaaaaaaaa");
}
});
caller.doCallback(); //實現回撥
}
}
//現實中是把doCallback()方法放在setCallback裡呼叫,以上是為了說明回撥原理
public class Caller {
ICallback callback;
public void doCallback() {
callback.func();
}
public void setCallback(ICallback callback) {
this.callback = callback;
doCallback();
}
}
下面再使用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()方法,就只有testMethod()"//測試方法"是需要改變的,下面我們來做一個函式實現相同功能但更靈活:
首先定一個回撥介面:
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()方法就可以實現回撥功能
總結:
Java中的回撥函式一般來說分為以下幾步:
宣告回撥函式的統一介面interface A,包含方法callback();
在呼叫類caller內將該介面設定為私有成員private A XXX;
在caller內提供實現A介面的public方法(將外部該介面的實現類通過形參傳入caller的XXX);
caller的某個方法dosth()中會用到XXX.callback()方法;
在caller的例項中,先實現A介面,後呼叫dosth()方法;