Java:传递实际的<t extends =“”event =“”>类。 (泛型问题)</t>

时间:2015-03-04 03:17:17

标签: java generics

我已经创建了自己的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运行,如下所示:< / p>

// 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"));

1 个答案:

答案 0 :(得分:1)

你能使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类似,所以我想知道为什么你会想要不止一个。

顺便说一下,当您处于同步块时,调用那些不受您控制的代码可能不是一个好主意。