2015-12-11 3 views
4

У меня есть этот интерфейс: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, но я не знаю, какой ,

+0

Возможный дубликат [Получить тип общего параметра в Java с отражением] (http://stackoverflow.com/questions/1901164/get-type-of-a -генерический-параметр-в-Java-с-reflectio n) –

ответ

4

Решите тип 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()); 
} 

PS: Имейте в виду, что acutalTypeArguments имеют тип Type. Они не должны быть Class. В вашем случае это класс, потому что ваше определение типа - EventHandler<MyEvent>.

+0

Отлично, он работает! благодаря –

0

При попытке сделать что-нибудь нетривиальное с обобщениями и отражением, рассмотрит гуава-х 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().)

Смежные вопросы