2013-07-20 40 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”的所有成员。我只是想知道回调是什么以及它们是如何使用的,这样我就可以理解我是否应该使用它们,或者如果我可以改变我的代码的流程以便更好地使用它们。你的信息非常有用,并会为我提供很多阅读(哦,高兴)谢谢你=) –