12
votes

Comment obtenir la valeur Type de carte en Java?

Duplicaté possible:

Obtenez un type générique de java.Util.list

J'ai une carte et je veux obtenir le type de T d'une instance de cette carte. Comment puis-je faire ça?

E.g. Je veux faire quelque chose comme: xxx

, il n'y a pas de ce type "getvaluetype ()" fonction dans l'API.


6 commentaires

Voir ceci: Stackoverflow.com/ Questions / 1942644 / ...


Vous pouvez utiliser Réflexion


Quelle est l'exigence fonctionnelle? Il peut y avoir de meilleures solutions que de violer la réflexion.


Non, la réflexion ne le fera pas, en raison de l'effacement de type.


@Staxman - En fait, reflet fonctionnera, car vous pouvez récupérer des informations sur le type déclaré de l'instance. Votre commentaire sur la réponse de Andy est correct, cependant: si tout ce que vous avez est l'instance, vous ne pouvez pas obtenir les informations de type de celui-ci. Mais il est probable que l'instance a été déclarée quelque part (membre de la classe, signature de méthode, etc.), et cette déclaration pourrait être utilisée de manière réfléchie pour déterminer le type. Techniquement, les valeurs ne sont pas garanties, cependant.


La question a demandé comment obtenir le type "d'une instance".


3 Réponses :


7
votes

Vous ne pouvez pas l'obtenir de l'instance, car dans les génériques Java, le paramètre Type est disponible uniquement au moment de la compilation, pas au moment de l'exécution.

Ceci est connu sous le nom de Erasure de type. une définition plus formelle est fournie dans le JLS.


2 commentaires

Ce n'est pas précis; Il y a des réponses donnant au code exact nécessaire pour le faire, quelques manières différentes


En réalité, cela est 100% correct pour ce cas particulier: si tout ce que vous avez est dit d'instance, il n'y a aucune information de type à trouver, rien du tout. La carte en question est de type HASHMAP, car les paramètres de type ici sont supprimés après la compilation (ils induisent les couts de type nécessaires au code d'octet).



16
votes

Si votre carte est un champ déclaré , vous pouvez procéder comme suit: xxx

le Code ci-dessus imprimera: xxx

Cependant, si vous avez simplement une instance de la carte , par exemple Si elle était transmise à une méthode, vous ne pouvez pas obtenir les informations à ce moment-là: xxx

vous pourrait saisir la signature de la méthode (à nouveau, à l'aide de la réflexion Comme mon exemple ci-dessus) Déterminez le type de effacé , mais cela ne vous obtient pas vraiment (voir Edition ci-dessous).

Edit:

Les commentaires de Baluscade ci-dessous doivent être notés. Vous n'avez vraiment pas besoin de faire cela; vous avez déjà déclaré le type de la carte, vous ne recevez donc plus aucune information que vous n'avez déjà. Voir son Répondez ici . < / p>


3 commentaires

La réflexion peut être utilisée à l'exécution des valeurs référencées sur une carte.


Noté devrait être que cela ne renvoie que les types génériques déclarés (comme dans mappe mapper partie), pas les types instanciés types de génériques (Comme dans New HashMap () Partie). Comme indiqué dans ma réponse dans la duplication liée; Il ne sert à rien de les comprendre de cette façon si vous les avez déjà déclarés vous-même dans le code ...


@Balusc - convenu; Votre commentaire sur la question à propos de la conception des alternatives est probablement la meilleure direction à prendre cette question. Le code de ma réponse donne la puissance de ne plus que S / Il sait déjà à la compilation.



2
votes

Bien que des réponses correctes aient été données, une autre alternative n'a pas encore été signalée. Fondamentalement, les champs et les méthodes ne sont pas les seuls endroits où les informations de type générique peuvent vivre: la déclaration de super-classe a également ces informations.

Cela signifie que si votre carte est en fait un sous-type de type: P>

  new TypeToken<Map<String, Double>>() { }


0 commentaires