我已经创建了自己的EventExecutor类,其类型为<T extends Event>

public interface EventExecutor<T extends Event> {

    ...
    public abstract void execute(Event event);
}


我现在知道这里的位置是错误的,因为我想传递:

public abstract void execute(T event);


我一直在研究Event Management System,当所有其他事件都运行后未取消Event时,某些代码将从EventExecutor运行,如下所示:

// event parameter should be of type T.
EventManager.call(event -> {
    // code here.
}, Class<? extends Event>, Object... eventParameters);


这里的问题是因为EventExecutor方法execute具有参数Event,这意味着event ->的类型是Event,而不是所需的类extends Event,所以这意味着我必须做一些铸造,这不是我想要的。

使我无法使用通用类型的T的问题是我的EventManager类的方法call

public static void call(EventExecutor<? extends Event> eventExecutor, Class<? extends Event> eventClass, Object... eventArgs) {
    synchronized (LOCK) {
        if (!checkIsEventClassRegistered(eventClass)) return;
        try {
            Event event = null;

            Class<?>[] constructorParameters = EventUtilities.getArrayOfClasses(eventArgs);
            Constructor<?> constructor = eventClass.getDeclaredConstructor(constructorParameters);

            event = (Event) constructor.newInstance(eventArgs);

            // HERE:
            if (!callAllRegisteredMethods(event)) eventExecutor.execute(event);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


我承认,我是泛型新手,但我看不到一切都出了什么问题。我尝试将event(在eventExecutor.execute(...)方法中)强制转换为T,但是它告诉我在EventExecutor中创建称为eventExecutor.execute(T)的方法,但是EventExecutor会引发错误,因为它想要T是我在同一包中创建的类。

我究竟做错了什么?

编辑
所以基本上,最后,我希望不必强制转换为想要的Event类:

EventManager.call(event -> {
    // Have this automatically be recognized as an instance of MyEventClass?
    System.out.println(event.getText());
}, MyEventClass.class, new String("text"));

最佳答案

您可以将call设为通用方法吗?

public static <T extends Event> void call(
   EventExecutor<T> eventExecutor, Class<T> eventClass, Object... eventArgs) {
  synchronized (LOCK) {
    if (!checkIsEventClassRegistered(eventClass)) return;
    try {
      Class<?>[] constructorParameters = EventUtilities.getArrayOfClasses(
          eventArgs);
      Constructor<?> constructor = eventClass.getDeclaredConstructor(
          constructorParameters);

      T event = eventClass.cast(constructor.newInstance(eventArgs));

      if (!callAllRegisteredMethods(event)) eventExecutor.execute(event);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}


注意我将强制转换替换为对Class.cast()的调用。

编辑:EventExecutor必须是通用的唯一原因是因为您想要传递匿名函数/类来执行,并且希望该函数/类取决于事件的实际类型。为避免混淆,我将其称为EventCallback,因为EventExecutor听起来与java.util.concurrent.Executor相似,所以让我想知道为什么您想要多个。

顺便说一句,在同步块中调用太多不在您控制范围内的代码可能不是一个好主意。

09-05 15:10