Le problème avec
List<String> list = new LinkedList();
est que sur le côté gauche, vous utilisez le type générique tandis List<String>
que sur le côté droit vous utilisez le type brutLinkedList
. Les types bruts en Java n'existent effectivement que pour la compatibilité avec le code pré-générique et ne doivent jamais être utilisés dans du nouveau code, sauf si vous en avez absolument besoin.
Maintenant, si Java avait des génériques depuis le début et n'avait pas de types, tels que LinkedList
, qui ont été créés à l'origine avant d'avoir des génériques, il aurait probablement pu faire en sorte que le constructeur d'un type générique infère automatiquement ses paramètres de type à partir de la gauche - côté main de la mission si possible. Mais il ne l'a pas fait, et il doit traiter différemment les types bruts et les types génériques pour une compatibilité ascendante. Cela les oblige à créer une manière légèrement différente , mais tout aussi pratique, de déclarer une nouvelle instance d'un objet générique sans avoir à répéter ses paramètres de type ... l'opérateur diamant.
En ce qui concerne votre exemple d'origine List<String> list = new LinkedList()
, le compilateur génère un avertissement pour cette affectation car il le doit. Considère ceci:
List<String> strings = ... // some list that contains some strings
// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);
Les génériques existent pour fournir une protection au moment de la compilation contre les erreurs. Dans l'exemple ci-dessus, l'utilisation du type brut signifie que vous n'obtenez pas cette protection et obtiendrez une erreur au moment de l'exécution. C'est pourquoi vous ne devez pas utiliser de types bruts.
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
L'opérateur diamant, cependant, permet de définir le côté droit de l'affectation comme une véritable instance générique avec les mêmes paramètres de type que le côté gauche ... sans avoir à taper à nouveau ces paramètres. Il vous permet de conserver la sécurité des génériques avec presque le même effort que d'utiliser le type brut.
Je pense que la chose clé à comprendre est que les types bruts (sans <>
) ne peuvent pas être traités de la même manière que les types génériques. Lorsque vous déclarez un type brut, vous n'obtenez aucun des avantages et la vérification de type des génériques. Vous devez également garder à l'esprit que les génériques sont une partie à usage général du langage Java ... ils ne s'appliquent pas seulement aux constructeurs sans argument de Collection
s!