我在 Google 上搜索以了解如何创建自定义事件和事件侦听器。在阅读了一些关于它的文章后,我仍然感到困惑。我想请你们回顾一下制作自定义事件(非 GUI 相关事件)和处理程序的方法。有人可以提供有关如何创建自定义事件和侦听器的简单说明吗?
2 回答
您基本上创建一个接口作为侦听器,例如
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());
}
}
我已经编写了很多基于事件的系统(非 gui),并且在实现自己的系统时有很多陷阱。一些经典的事情是线程和内存泄漏。
线程/进程控制仅仅意味着当你触发一个事件时,什么时候调用监听器——立即还是稍后?如果您立即触发,您最终可能会得到一个性能非常差的系统,该系统会不断对在调用侦听器后立即更改的事件做出反应。这里没有简单的答案,这实际上取决于您的需要。一般来说,如果您可以推迟事件的触发,您将拥有一个性能更好的系统(因为它可能避免为同一事件多次调用侦听器 - 或导致同一事件的事件循环)
第二个大问题是内存泄漏。Java 中没有删除是一件很可爱的事情,但听众是一把绑在你脚上的巨大枪。如果您有一个附加到使用大量内存的实例的侦听器,只要另一个对象包含对该侦听器的引用,该内存就会一直存在。有很多解决方案,例如 WeakReferences,但总的来说,在测试应用程序时需要非常小心并检查侦听器的数量,并确保它们优雅地分离(取消侦听?:))。
简而言之,如果我是你,我会考虑使用类似:http ://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/eventbus/package-summary.html http:// codingjunkie.net/guava-eventbus/ 的开发考虑了许多这些问题。