Java 使用反射方法检索类的泛型参数是否保证有效(在我的例子中)?
好的,我正在尝试为自己设计一个事件系统,这是我目前为止为事件处理程序所做的(event是一些空类): 我知道在处理类似的事情时,类型擦除是一个因素,但我不明白的是,它何时适用于我使用的Java 使用反射方法检索类的泛型参数是否保证有效(在我的例子中)?,java,events,generics,reflection,Java,Events,Generics,Reflection,好的,我正在尝试为自己设计一个事件系统,这是我目前为止为事件处理程序所做的(event是一些空类): 我知道在处理类似的事情时,类型擦除是一个因素,但我不明白的是,它何时适用于我使用的EventHandler,或者说实话。例如,我使用EventHandler的唯一方法是: public class TestEvent extends Event {} public class TestEventHandler implements EventHandler<TestEvent> {
EventHandler
,或者说实话。例如,我使用EventHandler
的唯一方法是:
public class TestEvent extends Event {}
public class TestEventHandler implements EventHandler<TestEvent>
{
@Override
public void handle(TestEvent event)
{
System.out.println("Event Handled");
}
}
公共类TestEvent扩展事件{}
公共类TestEventHandler实现EventHandler
{
@凌驾
公共无效句柄(TestEvent事件)
{
System.out.println(“已处理事件”);
}
}
(我的事件将在它们自己的包中,处理程序将在另一个包中)
即将出现的事件总线将按类注册此处理程序,并获取其通用事件类型,以用作事件类和事件处理程序映射中的键
无论如何,如有任何澄清,将不胜感激。如果我只能得到泛型类型,比如一半的时间或者别的什么,那就行不通了,我可能不得不做一个没有泛型类型的版本。如果您愿意,可以在回答中随意批评EventHandler的格式。此反射技巧也用于类型标记(查找它们) 下面是一个例子
public class Generic<TypeParameter> {
public void method(TypeParameter parameter) {
// no way to know the type bound to TypeParameter due to Type Erasure
}
}
还告诉我们参数的类型为TestEvent
。此信息在运行时不会丢失。它是类
信息的一部分(在字节码中)
如果您继续使用使您的EventHandler
类型与您的TestEventHandler
类似,您将能够使用反射技巧获得事件类型。注意,还可以使用匿名子类
new EventHandler<TestEvent>() {/*body*/};
neweventhandler(){/*body*/};
实现同样的目的。您显示的代码依赖于MyClass
作为EventHandler
的直接实现类,并且MyClass
使用具体类作为类型参数来实现EventHandler
的类型参数。所以它一定是这样的:
public interface EventHandler <T extends Event>
{
public void handle(T event);
}
class MyClass implements EventHandler<String>
如果MyClass
没有直接实现EventHandler
,而是通过介于两者之间的一个或多个非泛型类:
class MyClass implements YourClass
class YourClass implements EventHandler<String>
class MyClass实现您的类
类YourClass实现EventHandler
(在后一种情况下,智能代码可以遍历类型层次结构以找到实现EventHandler
的参数,但处理所有情况需要非常复杂,例如YourClass
本身可能是泛型的,并使用其参数之一实现EventHandler
)>)感谢您的快速解释,但还有一个问题:您说公共类TestEventHandler Extendes EventHandler
是“显式”的。假设我举了一个不显式的例子,这是否类似于公共类TestEventHandler Extendes EventHandler
?(别问我为什么我会这样做)@Octopod我只是用explicit这个词来强调你知道你使用的是什么类型。在你的注释中的TestEventHandler
中,你使用的是一个类型变量。没有办法知道它在类本身中的值(类型绑定)。
@Override
public void handle(TestEvent event)
{
System.out.println("Event Handled");
}
new EventHandler<TestEvent>() {/*body*/};
class MyClass implements EventHandler<String>
class MyClass<T> implements EventHandler<T>
class MyClass implements YourClass
class YourClass implements EventHandler<String>