2010-10-14 17 views
0

J'ai le problème suivant:Comment reconstruire des informations de type générique pour des classes ayant reçu un TypeLiteral?

Etant donné un type Guice littéral TypeLiteral<T> template et une classe Class c mise en œuvre ou l'extension T, construire un type Type t qui équivaut à c avec toutes les variables de type instanciés de manière à être compatible avec template .

Si c n'a aucune variable de type, c'est facile; c est le type en question. Toutefois, si c est de type des variables, alors je dois faire ce qui suit:

  1. Trouver le type dans l'héritage de c et de la hiérarchie de mise en œuvre correspondant au type brut de T
  2. Promenade à travers la structure des paramètres de type, trouver les types d'utilisation de variables et leurs types correspondants dans template
  3. Utilisez les fonctions auxiliaires Guice Types pour créer un type c instancié avec les types trouvés dans (2).

Bien sûr, il existe des cas d'erreur et il se peut qu'il ne soit pas complet. S'il ne trouve pas les utilisations correspondantes de toutes les variables de type, il échouera. Il pourrait y avoir d'autres cas aussi. Cependant, si j'ai ceci:

class CS<I> implements S<Map<I,Float>> { 
    // some stuff 
} 

et un type littéral TypeLiteral<S<Map<I,Float>>>, je veux obtenir un type qui représente CS entièrement instancié pour correspondre au type littéral.

Il semble que la réflexion fournisse suffisamment d'informations pour y parvenir, mais la logique semble complexe et sujette aux erreurs. Existe-t-il une bibliothèque existante qui expose cette logique?

Répondre

0

Ce problème est une instance du problème d'unification, et en tant que telle la norme unification algorithm est applicable et pas aussi compliqué que je pensais au départ. De plus, cette instance du problème permet certaines hypothèses simplificatrices significatives, car l'un des arbres ne contiendra pas de variables. 200 lignes de Java plus tard, j'ai une solution de travail.

0

TypeLiteral.getSupertype() devrait faire l'affaire:

TypeLiteral<?> t = TypeLiteral.get(x).getSupertype(y); 
+0

J'ai essayé 'template.getSupertype (c)', mais il se plaint que 'c' ne soit pas un supertype de' T' (ce qui est vrai, car c'est un sous-type de 'T'). –