2009-12-14 59 views
2

我正在研究需要Java对象来执行事件的程序。我非常熟悉C#中的这种工作方式,因为他有足够的经验来学习这些陷阱。Java中事件处理的缺陷

在Java中使用事件有哪些缺陷?它们与C#2.0中的事件有什么不同?

示例:对象更改了事件以提示所有者对象的保存。

注:Java 1.5的

相关:C# event handling (compared to Java)

回答

1

如前所述,Java没有C#拥有的delegates and events。但考虑到它是Observer pattern(GoF)的“广义”实现,您可以自己实现它。

the wikipedia page中有关于如何使用java.util.Observablejava.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之间的“参考岛”会混淆垃圾回收器,而不会试图从内存中移除对象。这是总是一个好主意,删除未使用的观察者

1

Java没有Event的专用概念。它通过沿着Observable + Observer行的API来实现。据我所知,Java规范中没有专用的lambda-functer API。

0

事件在Java中是严格容器特定的,标准库仅提供通用接口(通常针对特定需求进行扩展)。

关于事件的唯一'gotcha'可以被认为是在Java的上下文(一般)是在Swing容器(组件)和事件调度。摆动框架是单线程的,并且您期望而不是使用事件调度线程(即回调)在事件侦听器中执行计算密集型/高延迟工作。

3

在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); 
} 
0

这是一个关于如何使用Java创建,至少文章是这么说的自定义事件的链接... link

:)