0

私はコールバックに頭を悩ませようとしてきましたが、概念を理解するのに苦労しています。次のコードは、ここで見つけた例です

最初から最後まで、フローは次のようになると理解しています。

  • CallMeインスタンス化されているため、そのクラスのコンストラクターを呼び出します
  • 変数enが設定され、続いてEventNotifierクラスがインスタンス化され、オブジェクトへの参照が渡されるコンストラクターが呼び出されますCallMe
  • 変数は、コンストラクターに渡されieたオブジェクトに設定されますCallMe
  • 変数somethinghappenedは false に設定されています (それ以外の場合は値を設定するかどうかを決定するために、いくつかの条件ステートメントが使用されると思います)
  • うーん...完了?

このコードがわかりません。どのようdoWorkに呼び出されますか? これはどのようにイベントを意味しますか? ...interestingeventのコンストラクターから単純に呼び出さないのはなぜですか?callmedoworksomethinghappened

私はその考えを理解できないようです。コールバックは、主にマウスやボタンのクリックなどのイベントが発生したことを示すために使用されることは理解していますが、発生したイベントと呼び出されているメソッドとの間の接続はどのように行われますか? 変更をチェックしてイベントをトリガーするループがあってはいけませんか?

誰かが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...
    } 
}

編集: 承認された回答のコメントを参照してください... ---この--- リンクは私にとって非常に役に立ちました =)

4

2 に答える 2

2

私が通常コールバックを使用する方法は、PropertyChangeListeners/PropertyChangeSupport クラスを使用することです。これらのクラスについては、役立つと思われるさまざまな説明がおそらくたくさんあります。

とにかく、あなたの質問のポイントに。

まず、2 つのクラスが通常は異なるスレッドで実行されていることを理解する必要があります。コールバックが行うことは、他のスレッドで何かが発生したという非同期通知を取得できるようにすることです。これにより、通知されたスレッドは、制御を取り戻したときにその役割を果たすことができます。たとえば、データを受信して​​いるシリアル回線があるとします。InterestingEvent は、この行に 10 文字が到着したようなものになります。ここで、EventNotifier を 1 つだけ持つのではなく、入ってくるシリアル ラインごとに 1 つ持つことになります。CallMe インスタンスが実行されて何かを実行し、interestingEvent が呼び出されたかどうかを定期的にチェックします。InterestingEvent は、処理する新しいデータがあることを CallMe が認識できるように、ある種のフラグを設定します。CallMe がそれを確認すると、

インターフェイスの要点は、CallMe のインスタンスにアクセスするための明確な方法を持つことです。これをさらに開発すると、CallMe のインスタンスにアクセスしている他のインスタンスを管理したくなるでしょう。ここで、先に述べた PropertyChange の内容を読むと非常に役立ちます。

于 2013-07-20T05:24:57.183 に答える
2

メイン メソッドや静的ブロックはありません。投稿したコードから実際には何も実行されません。したがって、doWork()呼び出されることはありません。記事を読んでコードを見たところ、不完全なように見えます。または、作者が説明する必要がないと感じたために一部のコードが省略されている可能性があります。

要点は次のとおりです。

interface InterestingEventclass EventNotifierおよび別のクラスCallMeがありimplements InterestingEventます。

EventNotifierInterestingEventコンストラクタで を受け取り、に設定somethingHappenedfalseます。

のコンストラクターは、コンストラクターにオブジェクト自体への参照を渡すことによってCallMe、そのインスタンス メンバーを初期化します。EventNotifierEventNotifierCallMe

以下はコードにはありませんが、特定のアクションが発生したことを検出した場合は、 を設定しsomethingHappened = trueます。そのため、その後、 に対してdoWork()が呼び出された場合EventNotifierinterestingEvent()がその に対して呼び出されEventNotifierますInterestingEvent ie。から、これを行うことができますCallMe implements InterestingEvent

注: この記事は 1996 年のもので、それ以来多くの変更が加えられています。マウスクリックイベントを検出する方法について言及しましたが、これは異なります。この記事のポイントは、インターフェイスやブール値と組み合わせてオブジェクトを使用して、何かが発生したかどうかを確認する方法を示すことだったと思います。

実際にマウスのクリックを検出するには、このチュートリアルをご覧ください。イベント リスナーの記述に関する別のチュートリアルを次に示します。最後に、コメントでスレッド化について質問されたので、ここにすばらしい本があります: Java Concurrency in Practice

于 2013-07-20T05:15:11.177 に答える