理解Java中的回调

时间:2013-07-20 04:52:15

标签: java callback listener

我一直试图绕过回调,一直在努力把握这个概念。以下代码是我找到here

的示例

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

    实例化
  • 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...
    } 
}
编辑:请看批准答案中的评论...... --- this ---链接对我很有帮助=)

2 个答案:

答案 0 :(得分:2)

没有主要方法或静态块。实际上,您发布的代码没有任何内容;因此,永远不会调用doWork()。我阅读了这篇文章并查看了代码,它似乎不完整,或者可能遗漏了一些代码,因为作者觉得它不需要解释。

这是要点:

我们有一个interface InterestingEvent,一个class EventNotifier和另一个班级CallMeimplements InterestingEvent

EventNotifier在其构造函数中使用InterestingEvent,并将somethingHappened设置为false

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

以下内容不在代码中,但如果我们检测到某些特定操作发生,我们会设置somethingHappened = true。因此,如果doWork()调用了EventNotifier,则会interestingEvent() EventNotifier上调用InterestingEvent ie。我们可以这样做,因为CallMe implements InterestingEvent

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

要实际检测鼠标点击,请查看此tutorial。这是关于Writing Event Listeners的另一个教程。最后,既然您在评论中询问了线程,那么这是一本很棒的书:Java Concurrency in Practice

答案 1 :(得分:2)

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

无论如何,至于你的问题。

首先,您需要了解您拥有的两个类通常在不同的线程上运行。回调的作用是允许您获得异步通知,告知其他线程发生了什么。这允许被通知的线程在重新获得控制时发挥作用。例如,您有一个接收数据的串行线。 InterestingEvent会在这一行上出现10个字符。现在,不是只有一个EventNotifier,而是每个串行线路都有一个.CallMe实例将运行某些操作,定期检查是否已调用interestingEvent。 interestingEvent会设置某种标志,以便CallMe知道它有新的数据需要处理。当CallMe看到它时,它会处理有趣的事件,然后再回到正常活动状态。

界面的重点是有一个明确定义的方式来访问CallMe的实例。如果您开发更多,则可能需要管理正在访问您的CallMe实例的其他实例。在那里阅读我之前提到过的PropertyChange内容非常有帮助。