public static void main(String[] args) { Map<String, Map<Long, List<String>>> map = getHashMap(); } static <K,V> Map<K,V> getHashMap() { return new HashMap<K, V>(); } I saw a similar code in google guava (as factory methods) for making instances of Hashmap without mentioning the generic types.I don't understand how the generic is getting inferred by the above program.I mean how can the function getHashMap understand the type of map since i'm not passing any type information to the function.
3 Réponses :
La fonction Je pense que le plan actuel est (toujours) pour JDK7 pour soutenir l'opérateur de diamants , donc ce type de chose fonctionnera avec gethashmap code> n'a pas à déduire les types. C'est sur le site d'appel que Javac est requis par la spécification de langue Java pour déduire que les types d'accord ( 15.12.2.7 Arguments de type infesser sur des arguments réels ).
nouveau code> aussi, bien que avec un peu de syntaxe apparemment inutile. p>
Pouvez-vous expliquer un peu.
@Tom: Que voulez-vous dire que Javac déduira le type.can que vous expliquez comment cette chose fonctionne en étapes.
@Emil La spécification réelle est compliquée. Voir le lien. Généralement, cela fait ce que vous voulez la plupart du temps.
Petite question: Depuis qu'enregistrer, il n'y a pas de différence entre hashmap
@Pablo Eh bien, il peut attraper des erreurs. Par exemple, si la mise en œuvre de la mappe particulière code> impliquée a nécessité un sous-type de code> clés code>. Je pense que l'implémentation Javac est d'attribuer un marqueur aux types de la méthode et de voir où ils sont attribués, plutôt que de commencer par la déclaration de variable et de travailler à l'envers à l'invocation de la méthode.
au niveau de la bytecode, la méthode aura un descripteur qui vient de dire qu'il y a une méthode avec le nom gethashmap, qui ne prend aucun argument et renvoie une carte (pas de génériques).
alors lorsque le compilateur analyse la ligne Carte Si vous auriez déclaré votre méthode comme: P> Carte >> code>, mais pour obtenir l'instance, je dois appeler une méthode. À ce stade, il s'agit du travail du compilateur de vérifier si le type de retour de la méthode correspond au type déclaré de la variable de votre affectation de ce résultat. Donc il vérifie si
chaîne code> correspond à
k code> et si
mappe
static <K extends Number,V> Map<K,V> getHashMap()
{
return new HashMap<K, V>();
}
class XX static <T> T foo(){ return new T(); } String s = XX.foo(); Integer i = XX.foo();