如何从实现类中获取泛型接口的类型参数?

7

我有这个接口:

public interface EventHandler<T extends Event> {
    void handle(T event);
}

并且这个类实现它:

public class MyEventHandler implements EventHandler<MyEvent> {
    @Override
    public void handle(MyEvent event) {
        //do something
    }
}

在此类中,T参数是MyEvent,它是Event的具体实现。如何使用反射获取它?

可能是使用反射在Java中获取泛型参数类型的重复问题。 - Nikolay Ivanov
2个回答

11

通过泛型接口解析T的类型。例如:

public interface SomeInterface<T> {
}

public class SomeImplementation implements SomeInterface<String> {

    public Class getGenericInterfaceType(){
        Class clazz = getClass();
        ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericInterfaces()[0];
        Type[] typeArguments = parameterizedType.getActualTypeArguments();
        Class<?> typeArgument = (Class<?>) typeArguments[0];
        return typeArgument;
    }
}

public static void main(String[] args) {
    SomeImplementation someImplementation = new SomeImplementation();
    System.out.println(someImplementation.getGenericInterfaceType());
}

注意,actualTypeArguments 的类型是 Type,而不是 Class。在您的情况下,它是一个 Class,因为您的类型定义是 EventHandler<MyEvent>


0

当尝试使用泛型和反射进行任何非平凡操作时,请考虑使用Guava的TypeToken

private interface Event {}

private interface EventHandler<T extends Event> {
    void handle(T event);
}

TypeToken<?> findEventType(final Class<? extends EventHandler> handlerClass) throws Exception {
    final TypeToken<? extends EventHandler> handlerTypeToken = TypeToken.of(handlerClass);
    final Invokable<? extends EventHandler,Object> method = handlerTypeToken.method(EventHandler.class.getDeclaredMethod("handle", Event.class));
    return method.getParameters().get(0).getType();
}

public void testExploreGuavaTypeTokens() throws Exception {
    class MyEvent implements Event {}

    class MyEventHandler implements EventHandler<MyEvent> {
        @Override public void handle(final MyEvent event) {}
    }

    assertEqual(MyEvent.class, findEventType(MyEventHandler.class).getRawType());
}

(请注意,findEventType() 返回的 TypeToken 可能包含比 Class 更丰富的类型信息;这就是为什么由调用者决定是否通过 getRawType() 简化它的原因。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接