是使用保证有效的反射方法检索类的泛型参数(在我的情况下)



好吧,所以我正在尝试为自己设计一个事件系统,这就是我迄今为止为事件处理程序所做的(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

相关内容

  • 没有找到相关文章

最新更新