好吧,所以我正在尝试为自己设计一个事件系统,这就是我迄今为止为事件处理程序所做的(event是一些空类):
public interface EventHandler
{
public Class<? extends Event> type();
public void handle(Event event);
}
目标是EventHandler只能处理一种类型的事件(此时)。但是,我想知道我是否可以像这样重新格式化:
public interface EventHandler <T extends Event>
{
public void handle(T event);
}
这将在两个方面帮助我:
- 对
type()
的需求消失了 - 我在处理事件时不必选角
基于这个问题:Java中泛型参数类的反射?,我可以通过以下方法获得T
:
ParameterizedType t = (ParameterizedType) MyClass.class.getGenericSuperclass(); //OtherClass<String>
Class<?> clazz = (Class<?>) t.getActualTypeArguments()[0]; // Class<String>
我知道在处理这样的事情时,类型擦除是一个因素,但我不明白它什么时候适用于我对EventHandler<T>
的使用,或者说实话。例如,我使用EventHandler<T>
的唯一方法是:
public class TestEvent extends Event {}
public class TestEventHandler implements EventHandler<TestEvent>
{
@Override
public void handle(TestEvent event)
{
System.out.println("Event Handled");
}
}
(我的事件将在他们自己的包中,处理程序将在另一个中)
即将出现的事件总线将按类注册此处理程序,并获取它的泛型event类型以用作event类和EventHandlers映射中的键。
无论如何,任何澄清都将不胜感激。如果我只能在一半的时间内获得泛型类型,那就行不通了,我可能不得不做一个没有泛型类型的版本。如果你愿意的话,可以在你的回答中批评EventHandler的格式。
这种反射技巧也用于类型标记(查找)。
以下是类型擦除发生的示例
public class Generic<TypeParameter> {
public void method(TypeParameter parameter) {
// no way to know the type bound to TypeParameter due to Type Erasure
}
}
但这并不适用于你的情况。类似的声明
public class TestEventHandler extends EventHandler<TestEvent>
非常明确。它使用TestEvent
作为泛型EventHandler
类型的类型参数。此外,方法声明
@Override
public void handle(TestEvent event)
{
System.out.println("Event Handled");
}
还告诉我们该参数的类型是CCD_ 7。此信息在运行时不会丢失。它是Class
信息的一部分(在字节码中)。
如果你继续使用使你的EventHandler
类型像TestEventHandler
一样,你就可以使用反射技巧来获得Event
类型。注意,您也可以使用匿名子类
new EventHandler<TestEvent>() {/*body*/};
实现同样的目标。
您显示的代码依赖于MyClass
作为EventHandler
的直接实现类,并且MyClass
使用一个具体类作为类型参数来实现EventHandler
的类型参数。所以它一定是这样的:
class MyClass implements EventHandler<String>
在大多数情况下(例如,使用类型令牌),用户需要创建一个匿名类,该类直接实现EventHandler<String>
,如下所示:new EventHandler<String>() { /* body of anonymous class, can be empty */ }
,除了匿名部分外,它等效于上面的名称类型。
一些代码不起作用的场景:
如果
MyClass
是泛型的,并且使用类型变量而不是具体类作为类型参数来实现EventHandler
:class MyClass<T> implements EventHandler<T>
如果
MyClass
没有直接实现EventHandler
,而是通过介于两者之间的一个或多个非泛型类:class MyClass implements YourClass class YourClass implements EventHandler<String>
(在后一种情况下,智能代码可以遍历类型层次结构来找到实现EventHandler
的参数,但处理所有情况需要非常复杂,例如YourClass
本身可能是泛型的,并使用其参数之一来实现EventHandler
)