Ich habe eine parametrisierte Schnittstelle, die auf viele verschiedene Arten implementiert ist. Zur Laufzeit muss ich bei einem beliebigen Objekt, das diese Schnittstelle implementiert, herausfinden, was die eigentlichen Typparameter für die Schnittstelle sind.Wie erhalten Sie die Argumente des tatsächlichen Typs zu einer indirekt implementierten generischen Schnittstelle?
Hier ist ein Ausschnitt, das Problem zu veranschaulichen, und ein halbwegs Versuch, es zu lösen (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?
}
}
Es sieht aus wie genug gibt es generische Typinformationen zur Laufzeit, dass ableiten:
Child extends Base<List<Integer>>
Base<E> implements Awesome<Set<E>>
Und deshalb können wir alle Bits und Stücke zusammen, dass zu dem Schluss:
Child implements Awesome<Set<List<Integer>>>
So sieht es aus wie das Problem lösbar ist, aber es ist nicht so einfach, denn wir haben würden mit einer beliebigen Klassen-/Schnittstellenhierarchie zu arbeiten. Ist das der einzige Weg, dies zu tun? Gibt es einen einfacheren Weg? Hat jemand schon eine Bibliothek dafür geschrieben?
Mir ist keine Bibliothek bekannt, die dies implementiert. Ich habe es selbst gemacht - und es war nicht sehr angenehm. Ich könnte zumindest eine Super-Typ-Token-Implementierung finden: http://code.google.com/p/google-gson/source/browse/trunk/src/main/java/com/google/gson/reflect/TypeToken.java ? r = 60 & spec = svn89 –