簡體   English   中英

具有不同類型的變量參數?

[英]Variable arguments with different types?

我的代碼中有一個事件偵聽器列表:

private List<EventListener> listeners = new ArrayList<EventListener>();
listeners.add(new EventListener() {
    @Override
    public void someEvent(String arg1, MyClass arg2) {
        // ...
    }

    @Override
    public void someOtherEvent(AnotherClass arg1, int arg2) {
        // ...
    }
}

目前,我正在使用for循環調用偵聽器:

for (EventListener listener : listeners) {
    listener.someEvent("Hello world", (MyClass) myObject);
}

我想使用一種方法來調用它,如下所示:

fireEvent("someEvent", "Hello world", (MyClass) myObject);

或者可能是事件參數的數組或其他內容。

一種實現方法是創建某種事件對象,但是我並不特別想這樣做,因為它看起來很雜亂(有人告訴我我在這里錯了;我對Java沒有經驗)。 有沒有辦法創建類似於上面的fireEvent? EventListener是一個接口,如果有幫助的話。

從理論上講,您可以使用Java反射來做到這一點:

public void fireEvent(String name, Object... args) {
    Method method = null;
    // 1. find method
    for (Method m : EventListener.class.getMethods()) {
        if (m.getName().equals(name)) {
            method = m;
            break;
        }
    }

    if (method == null) {
        throw new IllegalArgumentException("Unknown event method: " + name);
    }

    // 2. call method on all listeners
    for (EventListener l : listeners) {
        try {
            method.invoke(l, args);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new IllegalArgumentException(e);
        }
    }
}

(請注意,這是一個瑣碎的版本,不涵蓋所有事件,例如重載的事件方法等。)

但是我強烈建議不要這樣做! 它不僅丑陋且難以閱讀,還使您的程序不再具有類型安全性! 當您使用錯誤的名稱String或錯誤的參數數量或類型時,編譯器不會注意到,但是程序會在運行時中斷!

因此,我建議為偵聽器的每個事件處理程序方法簡單地使用一個受保護的fireXXXEvent方法(使用簡單的for循環)。 在您的情況下,這將是:

protected void fireSomeEvent(String arg1, MyClass arg2);
protected void fireSomeOtherEvent(AnotherClass arg1, int arg2);

當然,您也可以引入事件對象(可能通過子類化java.util.EventObject )。 但這不一定會減少偵聽器中方法的數量(但可以-取決於您所擁有的事件的類型)。

有一些更高級的策略,例如在JavaFX中將通用事件處理程序與事件類型對象和通用事件對象一起使用,但是我認為如果您對Java不太熟悉,則不建議這樣做。

旁注:使用一個CopyOnWriteArrayList用於存儲你的聽眾或迭代的副本listeners射擊的事件時,否則你可能會得到一個ConcurrentModificationException ,如果聽眾試圖自己從監聽器列表中刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM