2013-07-20 36 views
0

我一直在試圖圍繞回調包裝頭,並一直在努力去理解這個概念。以下代碼是,我發現here瞭解Java中的回調

從第一開始到最後我明白的流動是這樣一個例子:

  • CallMe被實例化,從而調用構造的所述類
  • 可變en ,隨後實例化EventNotifier類並將其稱爲構造函數,該構造函數通過對對象的引用CallMe
  • 變量ie被設置爲對象01這是傳遞到構造
  • 變量設置爲false(我會承擔一些條件語句將被用來確定是否要設置的值,否則)
  • 嗯......怎麼辦?

我不明白這段代碼。 doWork如何被調用?這是如何表示一個事件?爲什麼不會簡單地從callme的構造函數調用interestingevent ....因此,爲什麼不直接調用dowork來代替somethinghappened的值呢?

嘗試我可能似乎無法理解的想法。我明白,回調主要用於表示發生了事件,例如鼠標或按鈕單擊,但它是如何使事件發生和被調用方法之間建立聯繫的?是否應該沒有檢查變化的循環,從而觸發事件?

有人可以提供一個(不是過度簡化的)在java回調的解釋,並幫助澄清如何這樣的事情可能是有用的?

public interface InterestingEvent 
{ 
    public void 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(); 
     } 
    } 
} 

public class CallMe implements InterestingEvent 
{ 
    private EventNotifier en; 
    public CallMe() 
    { 
     en = new EventNotifier (this); 
    } 

    public void interestingEvent() 
    { 
     // Wow! Something really interesting must have occurred! 
     // Do something... 
    } 
} 

編輯:請參閱覈准答案的評論...... --- this ---鏈接對我來說非常有幫助=)

回答

2

沒有main方法或靜態塊。從您發佈的代碼中沒有任何實際運行;因此,doWork()永遠不會被調用。我讀過這篇文章,看了看代碼,看起來不完整,或者可能有些代碼被遺漏了,因爲作者覺得它不需要解釋。

這裏的要點是:

我們有一個interface InterestingEvent,一個class EventNotifier,和另一個類CallMe,這implements InterestingEvent

EventNotifier在其構造函數中需要InterestingEvent,並將somethingHappened設置爲false

CallMe的構造通過使EventNotifier構造一個參照CallMe對象,本身初始化其EventNotifier實例成員。

以下內容不在代碼中,但如果我們檢測到發生了某些特定操作,我們將設置somethingHappened = true。因此在此之後,如果doWork()被稱爲EventNotifier,interestingEvent()將在EventNotifierInterestingEvent ie上被調用。我們可以做到這一點,因爲CallMe implements InterestingEvent

注意:這篇文章是從1996年開始的,自那以後發生了很大變化。你提到了如何檢測鼠標點擊事件,但這是不同的。我假設文章的要點是展示如何結合接口和布爾值來使用對象來查看是否發生了某些事情。

要實際檢測到鼠標點擊,請查看此tutorial。這是關於Writing Event Listeners的另一個教程。最後,由於您在評論中詢問了線索,因此以下是一本好書:Java Concurrency in Practice

+0

那麼我們如何檢測事件?我們會使用一個帶有循環的線程來檢測發生了什麼的信號嗎?此外,爲什麼要這樣做,如果你可以調用'interestingevent'方法而不是設置布爾值? –

+0

我不認爲這是一個很好的教程或任何解釋,除了說明接口的一些功能...我張貼另一個鏈接。 Swing和AWT爲你提供了[Listener classes](http://docs.oracle.com/javase/tutorial/uiswing/events/api.html) - 你不想重新創建輪子。你可以看一看特定類的源代碼,看看它是如何工作的,但是,聽衆會在不同的線程中等待某個特定的信號。 –

+0

所以在回調中沒有其他要點,但要檢測外部輸入?從我收集的信息來看,最大的用途是在不同線程上運行的對象之間傳遞信息,我在這裏是否正確? –

2

我通常使用回調的方式是使用PropertyChangeListeners/PropertyChangeSupport類。對於那些你可能會覺得有幫助的類,可能有很多不同的解釋。

無論如何,你的問題的重點。

首先,您需要了解您擁有的兩個類通常運行在不同的線程上。回調函數的作用是讓你獲得異步通知,在另一個線程上發生了一些事情。這允許通知的線程在重新獲得控制權時發揮作用。例如,您有一條正在接收數據的串行線路。 InterestingEvent將會有10個字符到達這一行。現在,不是隻有一個EventNotifier,而是每個串行線都有一個.CallMe實例正在執行某些操作,定期檢查是否已調用interestingEvent。 interestingEvent會設置某種標誌,以便CallMe知道它有新的數據要處理。當CallMe看到它時,它會處理任何有趣的事件,然後返回到其正常活動。

接口的要點是要有一個明確的方式來訪問CallMe的實例。如果您進一步發展,您可能想要管理訪問您的CallMe實例的其他實例。那就是閱讀前面提到的PropertyChange的東西真的很有用。

+0

所以我可以認爲 - [this](http://stackoverflow.com/questions/17494474/java-passing-an-instance-of-this-during-instantiation/17494655?noredirect = 1#17494655) - 問題我問了一段時間回來使用回調? –

+0

沒有。該代碼不會按原樣編譯。我不知道你在做什麼。回調的全部要點是提供兩個線程之間的通信。在標準的Java GUI應用程序中,鍵盤和鼠標事件,鼠標點擊,按鍵等與主應用程序線程位於不同的線程中。回調是你如何在兩者之間進行溝通。 – wjr

+0

我知道代碼不能編譯,其思想是通過將「this」傳入一個對象中,可以訪問所有對象中的「this」的所有成員。我只是想知道回調是什麼以及它們是如何使用的,這樣我就可以理解我是否應該使用它們,或者如果我可以改變我的代碼的流程以便更好地使用它們。你的信息非常有用,並會爲我提供很多閱讀(哦,高興)謝謝你=) –