繁体   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