我已经创建了自己的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
相似,所以让我想知道为什么您想要多个。顺便说一句,在同步块中调用太多不在您控制范围内的代码可能不是一个好主意。