我正在研究需要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
:)