Je veux coder une méthode unique Je ne pouvais pas comprendre le but ultime des génériques. Je suis tellement confus. P> génériques vs surcharge? P> ajouter () code> en Java, qui pourrait ajouter des entiers, des chaînes, etc. Les génériques m'aideront. public Integer add(Integer i, Integer j){return i+j;}
public String add(String i, String j){return i+j;}
public <T> T add(T i, T j){return i+j;} //this gives me error.
8 Réponses :
Je veux coder une méthode unique Ajouter () en Java, qui pourrait ajouter des entiers, des chaînes, etc. Les génériques m'aideront. P> blockQuote>
non fort> p> Les génériques sont utilisés pour
Sécurité EM> Strong> surtout à la compilation. P> Vous pouvez spécifier un seul type à ajouter à la collection p>
Listelst; code> p> acceptera la chaîne uniquement, aucune superclasse de la chaîne Aucune sous-classe [par exemple, si elle existe] p>
- Generics LI> ul>
acceptera la chaîne uniquement, pas de superclasse de la chaîne Aucune sous-classe code> - ce n'est pas vrai. Quelque chose comme void add42 (liste
Generics pourrait em> l'aide, le problème ici est que le fonctionnement Une solution pratique sans génériques serait la suivante: p> + code> est défini uniquement pour Java Primitives et String code> mais pas pour les types en général . Et en Java, nous ne pouvons pas surcharger aux opérateurs (comme nous pouvons faire en C ++ par exemple). public Integer add(Integer a, Integer b) { return a + b; } // sum of a and b
public String add(String a, String b) { return a + b; } // concatenate operation!
public MyType add(MyType a, MyType b) { return a.add(b); } // requires add operation
Votre deuxième paragraphe n'est pas vrai. Le type de retour ne fait pas partie de la signature de méthode en Java, uniquement les types de noms et de paramètres. Tant que les paramètres sont distincts, vous pouvez avoir des types de rendement différents. Ou avez-je mal compris ce que vous avez écrit?
La surcharge n'a pas déterminé avec le type de retour. Il n'est pas nécessaire que le type de retour soit identique à la surcharge.
@Jonathan - merci beaucoup - c'était un shortonconefeError typique :-) a changé la réponse à un parcours "Java pour débutants";)
@Jonathan: Le type de retour fait partie de la signature, mais vous ne pouvez pas avoir deux méthodes qui ne diffèrent que dans le type de retour (car il est trop ambigu que vous appelez)
Les génériques sont agréables car si cela vous a fait correctement, il vous permet de généraliser une partie du code que vous avez écrit. En termes d'écriture, vous souhaitez minimiser le code inutile et réutiliser autant de code que possible. P>
En utilisant l'approche de surcharge, vous devez écrire chacune des surcharges, avec des génériques que vous devez le faire une fois. Les génériques fonctionnent bien dans des situations où vous manipulez une collection depuis que vous effectuez certaines opérations communes sur un ensemble de collections. Dans certaines situations si vous désirez une approche plus personnalisée pour manipuler certaines situations, vous devrez peut-être surcharger les méthodes, mais je vous ferai un objectif d'écrire des génériques si vous pouvez l'utiliser dans plusieurs endroits. p>
Je suis donc confondu avec des génériques Java avec des modèles C ++. Si des liens pour la comparaison de génériques et de modèles me sont plus utiles.
Stackoverflow.com/questions/36347/... peut vous aider à comprendre les similitudes et les différences entre ces deux.
C'est exactement le point de générique. Vous ne souhaitez pas implémenter une méthode qui peut tout accepter. Franchement, vous pouvez toujours mettre en œuvre la méthode
et transmettez-lui des entiers, des cordes, des booléens ... Mais dans la plupart des cas, vous ne voulez pas pour ça. La méthode doit faire face à l'argument et il devrait donc connaître le type du paramètre. C'est la raison pour laquelle si vous souhaitez faire une méthode, ajouter que les chaînes et les entiers impliquent 2 méthodes: p> maintenant, vous ne pouvez pas envoyer à Boolean à ajouter () méthode: une telle méthode juste n'existe pas. p> Vous pouvez également implémenter la méthode générique p> et appelez Il: ajouter (objet obj) code> p> ceci. ceci.
public <T extends XXXXX> T add(T i, T j) { return i+j; }
Merci d'avoir mentionné le étend code>, était sur le point de le faire moi-même.
Que diriez-vous d'une approche avec une interface générique: et une classe de gestionnaire: p> maintenant Vous pouvez maintenant enregistrer et utiliser personnalisé Additionneurs pour différentes classes: P> String addedString = manager.getAdder(String.class).add("abc", "def");
@SuppressWarnings("unchecked") // this is necessary because of
// the generic <Integer> type
List<Integer> addedList = manager
.getAdder(List.class)
.add(
Arrays.asList(1,2,3),
Arrays.asList(4,5,6)
);
Génériques en Java n'ajoute que la coulée au bytecode.
Le code sera le même, à l'exception de la coulée. P>
donc les deux constructions: p>
List list1 = new ArrayList(); List<String list2 = new ArrayList<String>(); .... String string1 = (String) list1.get(0); String string2 = list2.get(0);
D'autres ont souligné pourquoi cela ne fonctionne pas. Permettez-moi d'ajouter simplement, je pense que vous êtes mal compris que les génériques Java sont pour. Peut-être êtes-vous familiarisé avec les modèles C ++, ou avec une expansion macro, qui ressemble tous deux des génériques, mais sont une chose très différente. P>
Les génériques sont vraiment sur la sécurité des types et évitant les moulages en désordre. Vous dites au compilateur qu'une certaine collection contient des chaînes, puis il sait que tout ce que vous mettez dans ou que vous sortez doit être une chaîne. Vous obtenez une vérification du temps compilé sur les choses que vous avez placées et vous économisez des moulages sur les choses que vous découlez. P>
Il ne provoque pas que le compilateur génère un code différent selon le type. Les génériques ne sont pas un moyen de courte main pour éviter de devoir écrire, dire, une version "int" et une version "flottante" de la même fonction, comme une macro ou un modèle C ++ feront pour vous. Vous pourrez peut-être obtenir un tel comportement distinct souhaité en disposant de deux classes qui implémentent la même fonction, mais une utilisation d'int et de l'autre en utilisant des flotteurs. Mais vous pouvez le faire avec des techniques orientées objet sans génériques. Si vous ne pouvez pas obtenir le comportement distinct souhaité à l'aide de techniques orientées objet "non génériques", vous ne pouvez pas le faire avec des génériques non plus. P>
Lorsque vous faites
INTEGER I + INTEGER J CODE>, vous n'ajoutez pas réellemententiers code>.Les entiers code> ne prennent pas en charge l'opérateur+ code>. Ils obtiennent une boîte à rebord dansintens code>, non directement ajoutés sous formeinteger code> objets. Vous ne pouvez pas ajouter d'objets génériques car les objets ne prennent pas en charge l'opérateur+ code>.Strings code> est un cas particulier et prend en charge+ code>.La seule raison pour laquelle vous appelleriez vos deux exemples
ajoutez code> est dû au fait qu'ils utilisent les opérateurs+ code>, qui est en fait une similitude sans signification car elle fait des choses complètement différentes pour les chaînes et les entiers. Les méthodes de nom basées sur ce qu'ils font réellement du point de vue de l'appelant - c'est-à-dire la somme code> etconcaténate code> dans ce cas serait de bons noms.