Dynamique Générique en Tapant Java
Si j'ai une classe à l'aide de type générique comme
public class Record<T> {
private T value;
public Record(T value) {
this.value = value;
}
}
il est assez simple de type tout au long de la conception du temps, si je sais que tous les types qui sont utilisés, comme c'est le cas dans cet exemple:
//I type explicitly
String myStr = "A";
Integer myInt = 1;
ArrayList myList = new ArrayList();
Record rec1 = new Record<String>(myStr);
Record rec2 = new Record<Integer>(myInt);
Record rec3 = new Record<ArrayList>(myList);
Qu'advient-il si je reçois une liste d'objets à partir de "quelque part" où je ne sais pas le type? Comment puis-je attribuer le type:
//now let's assume that my values come from a list where I only know during runtime what type they have
ArrayList<Object> myObjectList = new ArrayList<Object>();
myObjectList.add(myStr);
myObjectList.add(myInt);
myObjectList.add(myList);
Object object = myObjectList.get(0);
//this fails - how do I do that?
new Record<object.getClass()>(object);
- Les génériques est pour le moment de la compilation, le typage fort. C'est assez inutile si vous n'avez pas d'idée sur le type que vous essayez d'en déduire. Vous devez concevoir de telle manière qu'il y a au moins connu une interface ou une classe de base que vous pouvez utiliser. Vous pourriez faire
new Record<Object>(object)
, je suppose.
Vous devez vous connecter pour publier un commentaire.
Java génériques ne sont pas des Modèles C++.
Java les génériques sont un moment de la compilation caractéristique, pas un moment de l'exécution de la fonction.
Voici un lien vers le Java génériques Tutoriel.
Cela peut ne jamais travailler avec Java:
Vous devez soit utiliser le polymorphisme (par exemple, chaque objet implémente une interface connue) ou RTTI (instanceof ou de la Classe.isAssignableFrom()).
Vous pourriez faire ceci:
ou vous pouvez utiliser la Le générateur de modèle.
La création des instances de Types Génériques au moment de l'Exécution
Je ne suis pas tout à fait clair sur ce que vous essayez d'accomplir, mais à première vue, il ressemble à la solution la plus simple est la meilleure solution.
Il pourrait être résolu avec l'aide d'un environnement de script ( Groovy, JavaScript, JRuby, Jython ) qui pourrait évaluer de façon dynamique et d'exécuter du code arbitraire à créer les objets, mais ça a été très compliqué et trop complexe, juste pour créer un objet.
Mais malheureusement, je pense qu'il a un très piétons solution.
Tant qu'il y est un ensemble prédéfini de types pris en charge, vous pouvez utiliser un
Factory
modèle. Ici je viens de tirer parti de laProvider<>T
interface à partir de lajavax.inject
/com.google.inject
paquet.Q26289147_ProviderPattern.java
Avertissement:
Ce d'abord regardé comme l'un des génériques de problème, il n'est pas le cas, c'est une création problème.
Cela dit, vous n'avez pas besoin de passer autour des instances de
Class<?>
vous pouvez obtenirGeneric Type
informations de classes Paramétrées lors de l'exécution avecTypeToken
de Goyave.Vous pouvez même créer des instances d'un type générique lors de l'exécution avec
TypeToken
de la Goyave de la bibliothèque.Le principal problème est que cette syntaxe n'est pas pris en charge:
Geography<myClass.newInstance()> geo;
, et je crois que de toute façon faux autre que leProvider
de mise en œuvre ci-dessus.Q26289147.java
Remarques:
generated
Classeto pass to
getInstance()` d'un Injecteur. n'ai pas essayé encore, je viens de penser à elle!Class<T>.cast()
faire casting qui n'a pas besoin@SuppressWarning("unchecked")
tous sur la place.`Si vous ne connaissez pas le type, vous ne pouvez pas appliquer la compilation des contrôles avec les génériques.
Juste pour le plaisir de l'utiliser vous pourriez dire