1. 程式人生 > >關於對Java中回撥函式的理解

關於對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()方法;