我正在研究需要Java对象来执行事件的程序。我非常熟悉C#中的这种工作方式,因为他有足够的经验来学习这些陷阱。Java中事件处理的缺陷
在Java中使用事件有哪些缺陷?它们与C#2.0中的事件有什么不同?
示例:对象更改了事件以提示所有者对象的保存。
注:Java 1.5的
相关:C# event handling (compared to Java)
我正在研究需要Java对象来执行事件的程序。我非常熟悉C#中的这种工作方式,因为他有足够的经验来学习这些陷阱。Java中事件处理的缺陷
在Java中使用事件有哪些缺陷?它们与C#2.0中的事件有什么不同?
示例:对象更改了事件以提示所有者对象的保存。
注:Java 1.5的
相关:C# event handling (compared to Java)
如前所述,Java没有C#拥有的delegates and events。但考虑到它是Observer pattern(GoF)的“广义”实现,您可以自己实现它。
在the wikipedia page中有关于如何使用java.util.Observable
和java.util.Observer
实现该模式的示例。总体思路是让实施Observer
的课程自己订阅Observable
课程。
我通常会推出我自己的实现,因为这样做很容易,因为您只需创建一个接口来声明“observable”类调用的方法是注册的“观察者”。这里是一个观察的类,它可以在其注册SimpleObserver
对象和执行某种事件的一个简单的例子:
public class MyObservableClass {
List<SimpleObserver> observers = new ArrayList<SimpleObserver>();
/**
* Registers the observer
*/
public void addObserver(SimpleObserver observer) {
observers.add(observer);
}
/**
* Removes the registered observer (to be nice towards the
* garbage collector).
*/
public void removeObserver(SimpleObserver observer) {
observers.remove(observer);
}
/**
* Notifies the observers with the given data
*/
private void notifyObservers(String data) {
for(SimpleObserver o : observers) {
o.onEvent(data);
}
}
public void doSomething() {
// Do some stuff
String data = "Waffles and pwnies";
// Notify the observers that something happened.
notifyObservers(data)
}
}
...这里是简单的观察接口。
public interface SimpleObserver {
void onEvent(String data);
}
这可能看起来有点复杂,但它的好处是可观察到的类并不需要知道什么确切的其它目的是“听”到它(这就是为什么观察家有时也被称为听众)。它提供了两者之间的清晰分离。观察员需要向可观察者注册。
我能想到的唯一“陷阱”就是即使在像Java这样的内存管理环境中,该模式可能导致的内存泄漏。这是因为Observers和Observable之间的“参考岛”会混淆垃圾回收器,而不会试图从内存中移除对象。这是总是一个好主意,删除未使用的观察者。
Java有事件没有内置的概念,所以你最好把使用The Observer Pattern变化。
Java没有Event的专用概念。它通过沿着Observable
+ Observer
行的API来实现。据我所知,Java规范中没有专用的lambda-functer API。
事件在Java中是严格容器特定的,标准库仅提供通用接口(通常针对特定需求进行扩展)。
关于事件的唯一'gotcha'可以被认为是在Java的上下文(一般)是在Swing容器(组件)和事件调度。摆动框架是单线程的,并且您期望而不是使用事件调度线程(即回调)在事件侦听器中执行计算密集型/高延迟工作。
在C#中,你应该do like this when you fire an event:
public event SomeDelegate MyEvent;
private void FireMyEvent(MyEventArgs args)
{
var deleg = MyEvent;
if (deleg != null) deleg(args);
}
...保护自己免受并发修改(如果一个线程删除您检查MyEvent
的NULL的含量,把它之间的事件侦听器) 。在Java中,你会使用一个CopyOnWriteArrayList
,而不是保护自己免受并发修改:
private final CopyOnWriteArrayList<MyEventListener> listeners =
new CopyOnWriteArrayList<MyEventListener>();
private void fireMyEvent(MyEventArgs args){
// Iteration is performed over a snapshot of the list, concurrent
// modifications from other threads are invisible to the iterator
// and will not cause ConcurrentModificationExceptions.
for (MyEventListener listener : listeners)
listener.eventOccurred(args);
}
这是一个关于如何使用Java创建,至少文章是这么说的自定义事件的链接... link
:)