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