Java反射:从实现类

时间:2015-12-11 11:04:31

标签: java reflection

我有这个界面:

public interface EventHandler<T extends Event> {

    void handle(T event);

}

这个类实现它:

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

鉴于:

Class myEventHandlerClass = getClazz();

在此段中,T参数为MyEvent,这是Event的具体实现。如何使用反射获得这个?

我想要这样的事情:

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

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

myEventhandlerClass.getDeclaredMethod("handle");抛出NoSuchMethodException,因为我没有指定参数类型,因为我只知道这是Event的具体实现,但我不知道哪个。< / p>

2 个答案:

答案 0 :(得分:5)

通过通用接口解析T的类型。 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:请记住,acutalTypeArguments的类型为Type。它们不能是Class。在您的情况下,它是一个类,因为您的类型定义是EventHandler<MyEvent>

答案 1 :(得分: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());
}

(请注意TypeToken返回的findEventType()可能包含比Class所能表示的更丰富的类型信息;这就是调用者决定是否通过{{1}简化它的原因}。)