J’ai une classe de médicaments génériques . Dans une méthode de
, je veux obtenir l’instance de la classe de type T. Mais je ne peux pas appeler``
S’il vous plaît dites-moi votre meilleur moyen de se déplacer avec le `` ?
J’ai une classe de médicaments génériques . Dans une méthode de
, je veux obtenir l’instance de la classe de type T. Mais je ne peux pas appeler``
S’il vous plaît dites-moi votre meilleur moyen de se déplacer avec le `` ?
La réponse courte, c’est qu’il n’y a aucun moyen de savoir le type runtime de paramètres de type générique en Java. Je vous suggère de lire le chapitre sur l’effacement de type dans le Tutoriel Java pour plus de détails.
Une solution populaire consiste à passer la `` du paramètre de type dans le constructeur du type générique, par exemple
Je cherchais un moyen de faire moi-même sans l'ajout d'un supplément de dépendance au chemin de classe. Après quelques recherches, j'ai trouvé qu'il est possible, aussi longtemps que vous avez un générique supertype. C'est ok pour moi que je travaillais avec un DAO couche avec une couche générique supertype. Si cela correspond à votre scénario alors que c'est le plus fantastique de l'approche à mon humble avis.
La plupart des médicaments génériques cas d'utilisation j'en suis venu à travers une sorte de générique supertype par exemple, Liste de liste de tableaux ou GenericDAO pour DAO etc.
Pure Java solution
Cet article explique comment vous pouvez le faire en utilisant java pur.
http://blog.xebia.com/2009/02/07/acessing-generic-types-at-runtime-in-java/
Solution de printemps
Mon projet était à l'aide de printemps qui est encore mieux que le printemps est un utilitaire pratique la méthode pour trouver le type. C'est pour moi la meilleure approche, car il ressemble plus soignés. Je suppose que si vous n'étiez pas à l'aide de printemps, vous pouvez écrire votre propre méthode utilitaire.
import org.springframework.core.GenericTypeResolver;
public abstract class AbstractHibernateDao<T extends DomainObject> implements DataAccessObject<T>
{
@Autowired
private SessionFactory sessionFactory;
private final Class<T> genericType;
private final String RECORD_COUNT_HQL;
private final String FIND_ALL_HQL;
@SuppressWarnings("unchecked")
public AbstractHibernateDao()
{
this.genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), AbstractHibernateDao.class);
this.RECORD_COUNT_HQL = "select count(*) from " + this.genericType.getName();
this.FIND_ALL_HQL = "from " + this.genericType.getName() + " t ";
}
Il y a une petite lacune cependant: si vous définissez votre Foo
classe de base abstraite.
Cela voudrait dire que vous devez instancier vous classe comme:
Foo<MyType> myFoo = new Foo<MyType>(){};
(Notez le double croisillons à la fin.)
Maintenant, vous pouvez récupérer le type d' T
lors de l'exécution:
Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
Notez toutefois que l' mySuperclass
doit être la super-classe de la classe de définition de réellement définir le type final pour T
.
Il n'est également pas très élégant, mais vous devez décider si vous préférez new Foo<MyType>(){}
ou new Foo<MyType>(MyType.class);
dans votre code. Personnellement, je préfère la première forme parce que je suis allergique à toute forme de duplication...
Imaginez que vous avez une super-classe abstraite qui est générique:
public abstract class Foo<? extends T> {}
Et puis vous avez une deuxième classe qui étend la classe Foo avec un générique Barre qui s'étend T:
public class Second extends Foo<Bar> {}
Vous pouvez obtenir la classe Bar.class
dans la classe Foo en sélectionnant l' Type
(de m. bert bruynooghe réponse) et inférer l'aide d' Class
exemple:
Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
//Parse it as String
String className = tType.toString().split(" ")[1];
Class clazz = Class.forName(className);
Il est a noter que cette opération n'est pas idéal, donc c'est une bonne idée de mettre en cache la valeur calculée pour éviter de multiples calculs sur cette. L'une des utilisations courantes est au générique de la DAO mise en œuvre.
La mise en œuvre finale:
public abstract class Foo<? exteds T> {
private Class<T> inferedClass;
public Class<T> getGenericClass(){
if(inferedClass == null){
Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
String className = tType.toString().split(" ")[1];
inferedClass = Class.forName(className);
}
return inferedClass;
}
}
La valeur retournée est Bar.class lorsqu'il est appelé à partir de la classe Foo dans une autre fonction ou à partir de la Barre de classe.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.