I have an interface with a method with a common return type , and at runtime some instances of classes that indirectly implement this interface. Now I want to know the type of actual return for each implementation using reflection.
(My idea is to use this mechanism to determine the strategy using the interface and find the matching strategy (specific type of return type) from the set of strategy implementations at runtime without the need to introduce redundant helper methods that expose the type).
To be more specific, consider the following scenario:
private interface DAO <I extends Serializable, E> { public E getById (I id); } private abstract class AbstractDAO <T> implements DAO<Integer, T> { @Override public T getById (Integer id) {
At run time, I want to find out for a given class ( PersonDAOExtension.class ) whose type will be returned for the getById(..) method (expected to be: Person.class ).
Using reflection, I can find out which generic Type returned from this method. In this case, it is a TypeVariable (but it can also be Class if any class in the hierarchy indicates a covariant return type):
Method method = PersonDAOExtension.class.getMethod("getById", Integer.class); Type genericReturnType = method.getGenericReturnType(); if (genericReturnType instanceof TypeVariable<?>) { TypeVariable<?> typeVariable = (TypeVariable<?>) genericReturnType; typeVariable.getName();
I assume that resolving the actual type would mean recursing to superclasses and interfaces and translating the original ( parameterizedType.getRawType() ) and actual ( parameterizedType.getActualTypeArguments() ) type arguments for any parameterized type until the type name is found .
Has anyone done this before, and maybe some code snippets are ready to help me achieve this? Thank you very much in advance:)
Hint: I was able to extract the following information at runtime using reflection, so the raw and actual type information is saved:
private abstract interface DAO<I, E> private abstract class AbstractDAO<T> extends Object implements DAO<Integer, T> [raw type:DAO<I, E>] private class PersonDAO extends AbstractDAO<Person> [raw type:AbstractDAO<T>] private class PersonDAOExtension extends PersonDAO