2013-10-16 52 views

回答

21

回調是一段代碼,您將其作爲參數傳遞給其他代碼,以便它執行它。由於Java尚不支持函數指針,因此它們被實現爲Command對象。類似於

public class Test { 
    public static void main(String[] args) throws Exception { 
     new Test().doWork(new Callback() { // implementing class    
      @Override 
      public void call() { 
       System.out.println("callback called"); 
      } 
     }); 
    } 

    public void doWork(Callback callback) { 
     System.out.println("doing work"); 
     callback.call(); 
    } 

    public interface Callback { 
     void call(); 
    } 
} 

回調通常會引用一些實際有用的狀態。

通過使回調實現具有對代碼的所有依賴關係,您可以在代碼和執行回調的代碼之間獲得間接性。

+1

這是一個很好的例子,我想添加下列內容:一個回調方法可以是任何類的任何方法;對某個類的實例的引用在其他類中進行維護,並且在其他類中發生某個事件時,它會從第一個類中調用該方法。唯一使它成爲回調的區別於其他任何方法調用的唯一方法就是將對象的引用交給對象,以便讓對象稍後調用方法,通常是在某個事件上調用方法。 – arcy

+0

對不起,我是新來的java。這可以在沒有匿名課程的情況下完成嗎?它是否必須是回調界面?您是否可以提供一個不使用Callback接口的示例,如果有方法可以不使用此Callback接口? –

+0

@ImtiazAhmad不,匿名課程是爲了縮短例子。你可以創建一個'公共類MyCallbackImpl實現回調'。 –

3

java中的回調方法是一種當發生事件(稱爲E)時被調用的方法。通常情況下,您可以通過將一個特定接口的實現傳遞給負責觸發事件E(參見示例1)的系統來實現該功能。

在更大和更復雜的系統中,您只需註釋一個方法,系統將識別所有註釋的方法,並在事件發生時調用它們(請參見示例2)。當然,系統定義了方法應該接收的參數和其他約束條件。

例1:

public interface Callback { 
    //parameters can be of any types, depending on the event defined 
    void callbackMethod(String aParameter); 
} 


public class CallbackImpl implements Callback { 
    void callbackMethod(String aParameter) { 
    //here you do your logic with the received paratemers 
    //System.out.println("Parameter received: " + aParameter); 

    } 
} 

//.... and then somewhere you have to tell the system to add the callback method 
//e.g. systemInstance.addCallback(new CallbackImpl()); 

例2:

//by annotating a method with this annotation, the system will know which method it should call. 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface CallbackAnnotation {} 


public class AClass { 

    @CallbackAnnotation 
    void callbackMethod(String aParameter) { 
    //here you do your logic with the received paratemers 
    //System.out.println("Parameter received: " + aParameter); 

    } 
} 

//.... and then somewhere you have to tell the system to add the callback class 
//and the system will create an instance of the callback class 
//e.g. systemInstance.addCallbackClass(AClass.class); 
1

簡單的話... 用簡單的英語,一個回調函數就像一個工人誰 「回調」 到他的經理完成任務後。

它們與從調用函數獲取某些上下文的另一個函數調用一個函數有何不同? 確實是從另一個函數調用函數,但關鍵是回調被視爲一個對象,因此您可以根據系統的狀態更改要調用的函數(如策略設計模式) 。

他們的權力如何向新手程序員解釋? 回調的力量很容易在AJAX風格的網站中看到,這些網站需要從服務器上獲取數據。下載新的數據可能需要一些時間。如果沒有回調,您的整個用戶界面將在下載新數據時「凍結」,或者您需要刷新整個頁面而不是整個頁面的一部分。通過回調,您可以插入「正在加載」的圖像,並在加載後用新數據替換它。

未經回調某些代碼:

 function grabAndFreeze() { 
    showNowLoading(true); 
    var jsondata = getData('http://yourserver.com/data/messages.json'); 
    /* User Interface 'freezes' while getting data */ 
    processData(jsondata); 
    showNowLoading(false); 
    do_other_stuff(); // not called until data fully downloaded 
     } 

     function processData(jsondata) { // do something with the data 
    var count = jsondata.results ? jsondata.results.length : 0; 
    $('#counter_messages').text(['Fetched', count, 'new items'].join(' ')); 
    $('#results_messages').html(jsondata.results || '(no new messages)'); 
     } 
     **With Callback:** 
     Here is an example with a callback, using jQuery's getJSON: 

    function processDataCB(jsondata) { // callback: update UI with results 
    showNowLoading(false); 
    var count = jsondata.results ? jsondata.results.length : 0; 
    $('#counter_messages').text(['Fetched', count, 'new items'].join(' ')); 
    $('#results_messages').html(jsondata.results || '(no new messages)'); 
      } 

` `function grabAndGo() { // and don't freeze 
    showNowLoading(true); 
    $('#results_messages').html(now_loading_image); 
    $.getJSON("http://yourserver.com/data/messages.json", processDataCB); 
    /* Call processDataCB when data is downloaded, no frozen User Interface!        
    do_other_stuff(); // called immediately 
相關問題