How can I obtain the type parameter of a generic interface from an implementing class?

隐身守侯 提交于 2020-03-14 10:52:04

问题


I have this interface:

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

And this class implementing it:

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

In this clase, T parameter is MyEvent, that is a concrete implementation of Event. How can obtain this using reflection?


回答1:


Resolve the type of T by the generic interface. E.g.

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());
}

PS: Keep in mind that the acutalTypeArguments are of type Type. They must not be a Class. In your case it is a Class because your type definition is EventHandler<MyEvent>.




回答2:


When trying to do anything non-trivial with generics and reflection, consider Guava's 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());
}

(Note that the TypeToken returned by findEventType() could contain much richer type information than a Class can represent; that's why it's the caller's decision whether to simplify it via getRawType().)



来源:https://stackoverflow.com/questions/34222025/how-can-i-obtain-the-type-parameter-of-a-generic-interface-from-an-implementing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!