2010-10-16 4 views
0

HI: Quel est le type générique dans java? Juste pour réduire l'exception de distribution de classe? De même, le K signifie "clés", V signifie "valuse", qu'en est-il de l'E et du T?problème générique

Pour une classe générique, par exemple: liste, je comprends comme que la liste ne peut mettre objet de type String, mais je ne suis pas tout à fait clair sur la méthode générique:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 
    for (T o : a) { 
     c.add(o); // Correct 
    } 
} 

Qu'est-ce le T signifie dans le ci-dessus>? Quelqu'un peut-il me donner une expaination simple? J'ai lu le tutoriel par sun, mais je ne comprends pas encore. Donc, je souhaite que quelqu'un puisse l'expliquer sans trop de mots professionnels.

+0

L'appeler T est (juste) une convention. Vous pouvez l'appeler Item (ou FuzzyBear) si vous le souhaitez. Quoi qu'il en soit, c'est un espace réservé pour un "type générique" dans ce contexte (apparaît dans les <>). –

+0

Je sais, c'est seulement un exemple mais il y a 'Arrays.asList (T ...)' et 'Collections.addAll (Collection, T ...)' pour cela. – whiskeysierra

Répondre

2

Les lettres E et T représentent respectivement Element et Type, mais notez qu'elles ne sont pas appliquées par le compilateur ou quoi que ce soit de ce genre. Il est recommandé d'utiliser des lettres majuscules, il est donc préférable de les distinguer (les mots minuscules ressemblent à des noms de variables, les mots commençant par des majuscules ressemblent à des classes et les majuscules ressemblent à des constantes)

En ce qui concerne l'utilisation, pensez-y de cette façon. Lorsque vous créez un tableau, vous pouvez créer Object[], String[], Integer[], SomeClass[], qui vous indique exactement ce qui s'y trouve. Jusqu'à l'introduction des génériques, les collections/classes de cartes (List, Set, Map) avaient le problème que vous pouviez y mettre quelque chose (certains pourraient argumenter que ce n'est pas un problème). Alors maintenant, vous pouvez créer List<String>, List<Object> similaire à des tableaux. Il y a quelques différences cependant. Par exemple String[] étend Object[], mais List<String> ne pas étendre List<Object> de sorte que vous ne pouvez pas mettre une instance de liste de chaînes dans une variable de liste d'objets. L'avantage des génériques est que vous pouvez les avoir sur n'importe quelle classe, et une classe peut avoir plusieurs paramètres génériques (comme Map<K, V>). Vous pouvez le voir comme Class paramètres donnés aux instances d'autres classes, qui leur indiquent quels types leurs méthodes devraient recevoir ou retourner.

Et oui le point est que le compilateur peut vérifier si vous leur donnez le bon type de paramètres, de sorte que vous pouvez éviter ClassCastExceptions qui apparaîtrait à l'exécution. Par exemple avant génériques que vous pourriez faire:

String s = ""; 
List l = new ArrayList(); 
l.add(s); 
Integer i = (Integer)l.get(0); // ClassCastException 

mais avec les génériques:

String s = ""; 
List<String> l = new ArrayList<String>(); 
l.add(s); 
Integer i = (Integer)l.get(0); // compiler warning: cannot cast from String to Integer 

De plus, vous pouvez avoir un paramètre de type générique sur une seule méthode comme dans votre exemple (la classe elle-même ne besoin d'avoir un paramètre de type pour cela).Cela indique au compilateur que cette méthode doit correspondre à toutes les instances du paramètre type sur les paramètres de méthode et/ou le type de retour. Dans votre exemple appeler comme:

String[] a = new String[1]; 
List<Integer> l = new ArrayList<Integer>(); 
fromArrayToCollection(a, l); 

se traduira par une erreur de compilation, car la méthode doit recevoir un T[] et un Collection<T>, T ici étant la même. Mais vous lui avez donné un String[] (donc T est ici String) et un List<Integer> (donc T est ici Integer, pas String). Si j'étais List<String>, cela fonctionnerait. Notez également que List<T> s'étend Collection<T> puisque List étend Collection, mais List<T> ne s'étend pas List<S> même si T étend S (quels que soient T et S).

Oh, et vous pouvez avoir des caractères génériques sur les médicaments génériques spécifiant des limites pour les classes qui peuvent remplacer le type paramter:

public <T extends SomeClass> void fromArrayToCollection(T[] a, COllection<T> c); 

De cette façon, la méthode ne fonctionnera que si vous lui donnez someClass [] ou SomeChildClass [] (où SomeChildClass qui étend SomeClass), mais pas Object [] ou String [].

1

T signifie Type. Lorsque vous instanciez une classe générique, vous devez spécifier le type contenu dans l'instance. Ainsi, au lieu d'avoir une collection d'objets, vous pouvez avoir une collection de String ou MyType ou WhateverType. Les génériques donnent une sécurité de type classe au moment de la compilation. Si vous essayez de coller le type de données incorrect dans une collection générique, vous obtiendrez un avertissement du compilateur. Personnellement, je préfère cela par un mile pour attraper une exception de casting. De même, il n'est pas nécessaire de lancer à partir de type Object lors de la récupération à partir d'une collection Generic, contrairement aux collections non génériques.

+0

Merci.
"static void" que fait ce "T"? ce type de retour de méthode est vide, donc je me demande l'usage du T ici. – hguser

0

Le dans

static <T> void fromArrayToCollection(T[] a, Collection<T> c) 

déclare "T" étant un type générique au lieu du nom d'une certaine classe. Sinon, le compilateur cherchera une classe avec le nom "T".

Questions connexes