7
votes

Comment obtenir les arguments de type réels à une interface générique implémentée indirectement mise en œuvre?

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 ( aussi sur ideone.com ): xxx

On dirait qu'il y a assez de générique Tapez les informations à l'exécution pour déduire que:

  • enfant étend la base >
  • base implémente génial >

    et nous pouvons donc mettre tous les morceaux ensemble pour conclure que:

    • infantile implémente superbes >>

      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à?


1 commentaires

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 / ...


3 Réponses :


-1
votes

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;
    }
}


2 commentaires

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.



4
votes

Edit: Vous voudrez peut-être simplement rechercher: http://code.google.com/ p / gentyref /

Si vous pouvez garantir que toutes les implémentations de génial > code> n'auront pas de type arguments, le code suivant devrait vous aider à démarrer [1]: p > xxx pré>

si, toutefois, les instanciations de génial > code> ou base code> seront effectués, ce type d'information sera perdu à cause de l'effacement. Cela peut être travaillé, comme une convention, avec quelque chose comme ceci: p> xxx pré>

remarque le {} code>, cela crée une nouvelle classe anonyme qui implémente (ou ici s'étend ici) base code>. Cette classe aura ses paramètres de type disponibles pour la réflexion. P>

Si vous avez peur de faire respecter cette convention, vous pouvez masquer les constructeurs et n'exposer que les méthodes d'usine: P>

investigate(new ArrayList<Integer>());
investigate(new ArrayList<String>() {}); // new anonymous ArrayList class
investigate("");
investigate(new Awesome<Comparable<?>> () {}); // new anonymous implementation of Awesome


0 commentaires

1
votes

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]);
}


0 commentaires