0

我一直在努力解决回调问题,并且一直在努力掌握这个概念。以下代码是我在此处找到的示例

从头到尾我理解流程是这样的:

  • CallMe被实例化,从而调用所述类的构造函数
  • 设置变量en,随后实例化EventNotifier类并调用它的构造函数,该构造函数被传递给对象的引用CallMe
  • 变量ie设置为CallMe传递给构造函数的对象
  • 变量somethinghappened设置为 false(我假设将使用一些条件语句来确定是否设置该值)
  • 嗯……完成了吗?

我不明白这段代码。如何doWork被调用?这如何表示一个事件?为什么不简单地interestingevent从 ... 的构造函数调用。callme为此,为什么不直接调用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...
    } 
}

编辑:请查看已批准答案中的评论...---这个---链接对我很有帮助=)

4

2 回答 2

2

我通常使用回调的方式是使用 PropertyChangeListeners/PropertyChangeSupport 类。对于那些你可能会觉得有帮助的类,可能有很多不同的解释。

无论如何,就你的问题而言。

首先,您需要了解您拥有的两个类通常在不同的线程上运行。回调的作用是让您获得异步通知,说明另一个线程发生了某些事情。这允许被通知的线程在重新获得控制权时尽其所能。例如,您有一条正在接收数据的串行线路。InterestingEvent 就像 10 个字符已经到达这一行。现在,不再只有一个 EventNotifier,而是为每条进入的串行线路设置一个。CallMe 实例将运行做某事,定期检查是否调用了interestingEvent。有趣的事件会设置某种标志,以便 CallMe 知道它有新数据要处理。当 CallMe 看到时,

该接口的重点是有一个明确定义的方式来访问 CallMe 的实例。如果您对此进行更多开发,您可能会想要管理正在访问您的 CallMe 实例的其他实例。这就是阅读我之前提到的 PropertyChange 内容的真正有用之处。

于 2013-07-20T05:24:57.183 回答
2

没有主要方法或静态块。您发布的代码实际上没有运行任何内容;因此,doWork()永远不会被调用。看了文章,看了下代码,貌似不全,也可能是因为作者觉得不需要解释,所以遗漏了一些代码。

这是要点:

我们有一个interface InterestingEvent、一个class EventNotifier和另一个类CallMe,其中implements InterestingEvent

EventNotifierInterestingEvent在其构造函数中接受一个,并设置somethingHappenedfalse.

构造函数通过向构造函数传递对对象本身的引用来CallMe初始化其实例成员。EventNotifierEventNotifierCallMe

以下内容不在代码中,但如果我们检测到发生了某些特定操作,我们设置somethingHappened = true. 所以在那之后, ifdoWork()被调用一个EventNotifier,interestingEvent()将被调用 that EventNotifier's InterestingEvent ie。我们可以这样做,因为CallMe implements InterestingEvent.

注意:这篇文章是 1996 年的,从那以后发生了很大变化。您提到了如何检测鼠标单击事件,但这是不同的。我认为这篇文章的重点是展示如何将对象与接口和布尔值结合使用,以查看是否发生了某些事情。

要实际检测鼠标点击,请查看本教程这是另一个关于编写事件监听器的教程。最后,既然您在评论中询问了线程,这里有一本很棒的书:Java Concurrency in Practice

于 2013-07-20T05:15:11.177 回答