Tengo una interfaz parametrizada que se implementa de muchas maneras diferentes. En tiempo de ejecución necesito descubrir, dado un objeto arbitrario que implementa esa interfaz, cuáles son los parámetros de tipo reales para la interfaz.¿Cómo obtener los argumentos de tipo reales para una interfaz genérica implementada indirectamente?
He aquí un fragmento de ilustrar el problema, y un intento a mitad de camino para resolverlo (also on ideone.com):
import java.util.*;
import java.lang.reflect.*;
interface Awesome<X> { }
class Base<E> implements Awesome<Set<E>> { }
class Child extends Base<List<Integer>> { }
class AwesomeExample {
public static void main(String[] args) {
Awesome<Set<List<Integer>>> x = new Child();
System.out.println(
((ParameterizedType)
Child.class.getGenericSuperclass()
).getActualTypeArguments()[0]
);
// prints "java.util.List<java.lang.Integer>"
System.out.println(
((ParameterizedType)
Base.class.getGenericInterfaces()[0]
).getActualTypeArguments()[0]
);
// prints "java.util.Set<E>"
investigate(x);
// we want this to print "Set<List<Integer>>"
}
static void investigate(Awesome<?> somethingAwesome) {
// how to do this?
}
}
Parece que hay suficiente información de tipo genérico en tiempo de ejecución para deducir que:
Child extends Base<List<Integer>>
Base<E> implements Awesome<Set<E>>
Y por lo tanto, podemos poner todas las partes y piezas para concluir que:
Child implements Awesome<Set<List<Integer>>>
lo que parece que el problema tiene solución, pero no es tan sencillo, ya que tendríamos para trabajar con una jerarquía de clase/interfaz arbitraria. ¿Es esta la única manera de hacer esto? ¿Hay alguna forma más simple? ¿Alguien ha escrito una biblioteca para hacer esto ya?
No conozco una biblioteca que implemente esto. Lo hice yo mismo, y no fue muy agradable. Al menos, podría encontrar una implementación de token de tipo super: http://code.google.com/p/google-gson/source/browse/trunk/src/main/java/com/google/gson/reflect/TypeToken.java ? r = 60 y spec = svn89 –