java - 具有不同类型的变量参数?

标签 java methods arguments

我的代码中有一个事件监听器列表:

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 是一个接口(interface),如果有帮助的话。

最佳答案

理论上,您可以使用 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 或错误的参数数量或类型时,编译器不会注意到,但程序会在运行时中断!

因此,我建议为监听器的每个事件处理程序方法简单地设置一个 protected fireXXXEvent 方法(使用简单的 for 循环)。在你的情况下,这将是:

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

当然,您也可以引入事件对象(可能通过子类化java.util.EventObject)。但这不一定会减少监听器中的方法数量(但可以 - 取决于您获得的事件类型)。

有一些更奇特的策略,例如使用带有事件类型对象和通用事件对象的通用事件处理程序(如 JavaFX 中),但我认为如果您对 java 不是很熟悉,则不建议这样做。

旁注:使用 CopyOnWriteArrayList 来存储监听器,或者在触发事件时迭代 监听器 的副本,否则您可能会收到 ConcurrentModificationException 如果监听器尝试将自身从监听器列表中删除。

关于java - 具有不同类型的变量参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19966481/

相关文章:

java - 加载 slf4j LoggerFactory 时,websphere 类加载器给出 java.lang.LinkageError

java - 在服务中实现 onActivityResult()

javascript - JScript 参数集合 - .Net 等效项

java - 模型可以刷新 View 吗?

Java打印包含多个整数的字符串

Android:振动器法(如果手机没有振动器?)

java - 我的一个方法使用在另一个方法中返回的变量。我无法使用第二种方法来打印或计算

android - 从 BroadcastReceiver 调用 Activity 的 finish() 方法

c# - 括号中带有(属性)的方法参数

python - 给出的参数与 python 看到的不匹配