J'ai une interface ( mon idée est d'utiliser ce mécanisme pour définir une stratégie à l'aide d'une interface et trouver une stratégie correspondante (type de retour spécifique) sur un ensemble d'implémentations de stratégie au moment de l'exécution, sans avoir à introduire des méthodes d'assistance redondantes qui Exposez le type em>). p> Pour être plus spécifique, examinons le scénario suivant: p> au moment de l'exécution, je veux savoir pour Une classe donnée ( Utilisation de la réflexion, je peux trouver quel type générique persondaoextension.class code>) quel type sera renvoyé pour la méthode
GetById (..) code> (attendu:
personne.class code> ). P>
type code> est renvoyé de cette méthode. Dans ce cas, c'est un
typévariable code> (mais pourrait aussi être une classe code> code>, si une classe de la hiérarchie spécifierait un type de retour covariant): p>
private abstract interface DAO<I, E>
private abstract class AbstractDAO<T> extends Object implements DAO<Integer, T> [raw type:DAO<I, E>]
private class PersonDAO extends AbstractDAO<Person> [raw type:AbstractDAO<T>]
private class PersonDAOExtension extends PersonDAO
3 Réponses :
J'ai déjà eu un problème similaire. Dans ma solution, la classe abstraite avait une méthode nommée
et dans la classe abstraite J'ai eu une carte Vous pouvez également enregistrer une classe de pojo aussi bien. Si vous avez besoin de plus d'informations: p> Je sais que Ce n'est pas la meilleure solution mais c'était simple et faire le travail. P> P> registre de vide statique (classe Étend dao> clazz,? Étend dao daoinstance) code>. P>
code> qui références stockées aux instances. J'ai utilisé des singletons mais vous pouvez utiliser un multimap si vous avez plusieurs instances. En utilisant cette technique, vous pouvez vous débarrasser de la réflexion et vous aurez un
définir code> de toutes les implémentations que vous avez enregistrées et leurs classes. P>
registre de vide statique (DaoData DaoData,? étend dao daoinstance) code> p>
Quel est le type de retour de cette méthode nommée registre?
Je pense que c'était void code>.
J'étais enfin capable de trouver une solution, de recouvrer en super classes et d'interfaces, remplaçant les variables de type avec les arguments de type passés jusqu'à atteindre la classe de base souhaitée: fonctionne comme un charme: P> List<DAO<?, ?>> knownDAOs = ...
for (DAO<?, ?> daoImpl : knownDAOs) {
Type[] types = resolveActualTypeArgs(daoImpl.getClass(), DAO.class);
boolean canReadPerson = types[1] instanceof Class<?> && Person.class.isAssignableFrom((Class<?>) types[1]);
}
Joli! FYI, j'ai trouvé une petite bibliothèque qui fournit des fonctionnalités similaires, mais de manière plus générale: GentyRef < / a>. Je lui ai donné un coup de feu juste pour résoudre mon problème (à résoudre plus précisément les types de champs lorsqu'une sous-classe réduit le type générique) et semble assez prometteur. Les génériques ont beaucoup de cas d'angle et je ne pense pas que GentyRef couvre tous, mais c'est un bon départ.
Il suffit de tester avec des arguments génériques échangés ( Crazymap
J'ai pu déterminer le type de retour générique d'une méthode d'une ligne en une ligne avec Google Guva's Typeoken classe: Alternativement, si vous souhaitez obtenir le type générique d'une classe (comme vous l'avez fait dans votre Réponse acceptée), plutôt que le type de retour d'une méthode, vous pouvez effectuer les éléments suivants: P> (new TypeToken<DAO<?, Person>>() {})
.isSupertypeOf(TypeToken.of(PersonDAOExtension.class))
Que voulez-vous faire avec le type, une fois que vous le savez? Si vous envisagez d'utiliser
instanceOf code> Opérateur, vous pouvez faire à la place
si (PERSON.CLASS.ISAssignAdFrom (Method.getReturnType ())) {...} code>
Le type de retour (non générique) est un objet, cela reviendrait toujours faux ...