Java Reflection: get a generic interface type parameter from an implementation class

I have this interface:

public interface EventHandler<T extends Event> {

    void handle(T event);

}

And this class implements this:

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

Considering:

Class myEventHandlerClass = getClazz();

In this class parameter T MyEvent, this is a specific implementation Event. How can this be obtained by reflection?

I need something like this:

Class myEventHandlerClass = getClazz();
Method handleMethod = myEventhandlerClass.getDeclaredMethod("handle");

Class<?>[] params = method.getParameterTypes();
Class<?> eventConcreteType = params[0];

But myEventhandlerClass.getDeclaredMethod("handle");throws NoSuchMethodException, since I did not specify the type of parameter, because I just know that this is a specific implementation Event, but I do not know which one.

+4
source share
2 answers

Allow type by Tcommon interface. For example.

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: , acutalTypeArguments Type. Class. , EventHandler<MyEvent>.

+4

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

( , TypeToken, findEventType(), , Class, getRawType().)

0

Source: https://habr.com/ru/post/1619481/


All Articles