5

我在 Google 上搜索以了解如何创建自定义事件和事件侦听器。在阅读了一些关于它的文章后,我仍然感到困惑。我想请你们回顾一下制作自定义事件(非 GUI 相关事件)和处理程序的方法。有人可以提供有关如何创建自定义事件和侦听器的简单说明吗?

4

2 回答 2

6

您基本上创建一个接口作为侦听器,例如

public interface EatListener {

    ...

}

在 EatListener 类中,您拥有使用事件作为方法参数调用的方法;如

public void onEat(EatEvent);

然后你可以有一个像 Human 这样的类来实现或实例化 EatListener;如

public class Human {

    private EatListener listener;

    public void eatFood(Food food) {
        if(listener != null) {
            listener.onEat(new EatEvent(food));
        }
    }

}

那么你需要有实际的 EatEvent;它可以像食物包装一样简单,可能还有一些额外的数据。

与 java 上的任何 GUI 一样,您可以从该接口创建匿名内部类:

new EatListener() {
    public void onEat(EatEvent event) {
        System.out.println("I just ate " + event.getFood().getName());
    }
}
于 2012-10-15T15:28:45.907 回答
1

我已经编写了很多基于事件的系统(非 gui),并且在实现自己的系统时有很多陷阱。一些经典的事情是线程和内存泄漏。

线程/进程控制仅仅意味着当你触发一个事件时,什么时候调用监听器——立即还是稍后?如果您立即触发,您最终可能会得到一个性能非常差的系统,该系统会不断对在调用侦听器后立即更改的事件做出反应。这里没有简单的答案,这实际上取决于您的需要。一般来说,如果您可以推迟事件的触发,您将拥有一个性能更好的系统(因为它可能避免为同一事件多次调用侦听器 - 或导致同一事件的事件循环)

第二个大问题是内存泄漏。Java 中没有删除是一件很可爱的事情,但听众是一把绑在你脚上的巨大枪。如果您有一个附加到使用大量内存的实例的侦听器,只要另一个对象包含对该侦听器的引用,该内存就会一直存在。有很多解决方案,例如 WeakReferences,但总的来说,在测试应用程序时需要非常小心并检查侦听器的数量,并确保它们优雅地分离(取消侦听?:))。

简而言之,如果我是你,我会考虑使用类似:http ://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/eventbus/package-summary.html http:// codingjunkie.net/guava-eventbus/ 的开发考虑了许多这些问题。

于 2012-10-15T15:41:00.107 回答