[英]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.