J'ai une interface paramétrée mise en œuvre de différentes manières. Au moment de l'exécution, j'ai besoin de comprendre, étant donné un objet arbitraire qui implémente cette interface, quels paramètres de type réelle à l'interface sont.
Voici un extrait pour illustrer le problème et une tentative à mi-parcours de la résolution ( On dirait qu'il y a assez de générique Tapez les informations à l'exécution pour déduire que: P> et nous pouvons donc mettre tous les morceaux ensemble pour conclure que: p> Il semble que le problème est résoluble, mais ce n'est pas si simple, car nous devrions travailler avec une hiérarchie de classe / interface arbitraire. Est-ce le seul moyen de faire cela? Y a-t-il un moyen plus simple? A quelqu'un écrit une bibliothèque pour le faire déjà? P> p>
enfant étend la base
base
infantile implémente superbes
3 Réponses :
La réponse courte est non. Je suis d'accord que c'est une pitié ... :( La raison est que Java dépose des paramètres de type au stade de la compilation. Ils n'existent pas dans le code d'octet. Ils sont utilisés par le compilateur uniquement.
Pour résoudre votre problème, vous devez ajouter un autre paramètre "régulier" de la classe de type et le transmettre au constructeur lorsque vous créez une instance de base: p>
class Base<E> implements Awesome<Set<E>> { private E type; public Base(E type) { this.type = type; } }
Les informations de type sont dans le code octet. Donc, vous n'êtes pas correct. Vous pouvez obtenir les informations de type dans cette position. Google pour des jetons super types pour obtenir un exemple.
@THOMAS - Les informations de type statique sont stockées, des informations dynamiques ne sont pas.
Edit: Vous voudrez peut-être simplement rechercher: http://code.google.com/ p / gentyref /
Si vous pouvez garantir que toutes les implémentations de si, toutefois, les instanciations de remarque le Si vous avez peur de faire respecter cette convention, vous pouvez masquer les constructeurs et n'exposer que les méthodes d'usine: P> génial > code> n'auront pas de type arguments, le code suivant devrait vous aider à démarrer [1]: p >
génial > code> ou
base
{} code>, cela crée une nouvelle classe anonyme qui implémente (ou ici s'étend ici)
base
investigate(new ArrayList<Integer>());
investigate(new ArrayList<String>() {}); // new anonymous ArrayList class
investigate("");
investigate(new Awesome<Comparable<?>> () {}); // new anonymous implementation of Awesome
Après la proposition de @ oconnor0, voici comment le faire avec GentyRef :
static Type investigate(Awesome<?> somethingAwesome) { return GenericTypeReflector.getTypeParameter(somethingAwesome.getClass(), Awesome.class.getTypeParameters()[0]); }
Je ne suis pas au courant d'une bibliothèque qui implémente ceci. Je l'ai fait moi-même - et ce n'était pas très agréable. Je pouvais au moins trouver une implémentation de jeton super type: CODE.GOOGE.COM/P/GOOGE-GSON/SOURCE/BROWSE/TRUNK/SRC/MAIN/J AVA / ...