简体   繁体   English

Java:通过实际 <T extends Event> 类。 (通用问题)

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

I've made my own EventExecutor class, which has the type <T extends Event> . 我已经制作了自己的EventExecutor类,其类型为<T extends Event> EventExecutor <T extends Event>

public interface EventExecutor<T extends Event> {

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

and I know right now that this up here is wrong, because I'm wanting to pass in: 我现在知道这里的位置是错误的,因为我想传递:

public abstract void execute(T event);

I've been working on an Event Management System , and when an Event isn't cancelled after all other events have ran, certain code will run from the EventExecutor as shown: 我一直在使用Event Management System ,并且在运行所有其他事件后未取消某个Event时,某些代码将从EventExecutor运行,如下所示:

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

The problem here is since the EventExecutor method execute has the parameter of Event , that means event -> is of type Event , and not the wanted class that extends Event , so that means I have to do some casting, which isn't what I want to do. 这里的问题是因为EventExecutor方法execute具有参数Event ,这意味着EventExecutor event ->Event类型,而不是extends Event的通缉类,因此这意味着我必须进行一些强制转换,这不是我要做的想做。

The problem that keeps me from using the generic type of T is my EventManager class's method call : 使我无法使用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();
        }
    }
}

I'll admit, I'm new to generics, and I don't see what's so wrong with everything. 我承认,我是泛型新手,但我看不到一切都出了什么问题。 I've tried casting event (in the eventExecutor.execute(...) method) to T , but it tells me to create the method in EventExecutor called eventExecutor.execute(T) , but then EventExecutor throws an error, because it wants T to be a class that I create in the same package. 我尝试将event (在eventExecutor.execute(...)方法中)强制转换为T ,但是它告诉我在EventExecutor创建名为eventExecutor.execute(T) ,但随后EventExecutor抛出错误,因为它想要T是我在同一包中创建的类。

What am I doing wrong? 我究竟做错了什么?

Edit 编辑
So basically, in the end I want to be able to not have to cast to my wanted Event class: 所以基本上,最后,我希望不必强制转换为想要的Event类:

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

Can you make call a generic method? 您可以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();
    }
  }
}

Note I replaced the cast to a call to Class.cast() . 注意,我将Class.cast()替换为对Class.cast()的调用。

Edit: The only reason why EventExecutor has to be generic is because you want to pass in an anonymous function/class to do the execution, and you want that function/class to depend on the actual type of the event. 编辑: EventExecutor必须具有通用性的唯一原因是,您想要传递匿名函数/类来执行,并且希望该函数/类取决于事件的实际类型。 To avoid confusion, I would call it an EventCallback , since EventExecutor sounds similar to java.util.concurrent.Executor , so I was left wondering why you would want more than one. 为避免混淆,我将其称为EventCallback ,因为EventExecutor听起来类似于java.util.concurrent.Executor ,所以我不知道您为什么想要多个。

Incidentally, it's probably not a good idea to call so much code that isn't under your control while you are in a synchronized block. 顺便说一句,在同步块中调用太多不在您控制范围内的代码可能不是一个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM