好吧,所以我试图为自己设计一个事件系统,这就是我目前为事件处理程序所做的事情(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()
的需求消失了。 基于这个问题:Reflection for Class of generic parameter in 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");
}
}
(我的事件将在他们自己的包中,处理程序将在另一个中)
即将成为事件的总线将按类注册此处理程序,并获取它的通用事件类型,以用作事件类和EventHandler映射中的键。
无论如何,任何澄清都将不胜感激。如果我只能在一半时间内得到通用类型,那么它就不会有用,而且我可能不得不做一个没有泛型类型的版本。如果你愿意,可以随意批评如何在你的答案中开始格式化EventHandler。
答案 0 :(得分:1)
这种反射技巧也用于类型标记(看起来像)。
以下是type erasure发生的例子
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");
}
还告诉我们该参数的类型为TestEvent
。此信息不会在运行时丢失。它是Class
信息的一部分(字节代码中的信息)。
如果您继续使用类似EventHandler
的{{1}}类型,那么您将能够使用反射技巧获取TestEventHandler
类型。请注意,您还可以使用匿名子类
Event
实现同样的目标。
答案 1 :(得分:0)
您展示的代码依赖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
)