Java:传递实际<T extends Event>class。 (泛型问题)

Java: Pass actual <T extends Event> class. (Generics Problems)

我创建了自己的 EventExecutor class,类型为 <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 想要 class,所以这意味着我必须做一些转换,这不是我想做的。

让我无法使用 T 的泛型类型的问题是我的 EventManager class 的方法 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 成为我在同一个包中创建的 class。

我做错了什么?

编辑
所以基本上,最后我希望能够不必转换为我想要的 Event class:

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 必须是通用的唯一原因是因为您想传入匿名 function/class 来执行,并且您希望 function/class 取决于事件的实际类型。为避免混淆,我将其称为 EventCallback,因为 EventExecutor 听起来与 java.util.concurrent.Executor 相似,所以我想知道为什么您想要多个。

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