Je viens juste de passer en revue l’implémentation de la classe java.util.Collections
de Java 7 et j’ai vu quelque chose que je ne comprends pas. Dans la signature de la fonction max
, pourquoi T
est-il limité par Object
?
public static <T extends Object & Comparable> T max(Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); while (i.hasNext()) { T next = i.next(); if (next.compareTo(candidate) > 0) candidate = next; } return candidate; }
max
semble fonctionner correctement si la limite de l’object est omise.
public static <T extends Comparable> T max(Collection coll) { Iterator i = coll.iterator(); T candidate = i.next(); while (i.hasNext()) { T next = i.next(); if (next.compareTo(candidate) > 0) candidate = next; } return candidate; }
Y a-t-il réellement des situations où la borne fait une différence? Si oui, veuillez fournir un exemple concret.
Les deux ont les mêmes limites mais il y a une différence subtile.
>
Cela provoquera T
pour devenir un Object
cours d’effacement.
>
Cela entraînera T
à devenir Comparable
sous effacement.
Dans ce cas, c’est fait car .max
est antérieur à Java 5. Nous pouvons voir dans ce lien que Joachim a gentiment fourni que la signature de .max
dans Java 1.4.2 soit:
public static Object max(Collection coll)
Avions-nous utilisé
tant que borne, notre signature serait
public static Comparable max(Collection coll)
Ce qui briserait les API. J’ai réussi à trouver cette page qui traite de la conversion d’anciennes API en applications génériques et donne l’exemple .max
.
Ici, ils expliquent pourquoi max
est défini de cette manière:
Vous devez également vous assurer que l’API révisée conserve la compatibilité binary avec les anciens clients. Cela implique que l’effacement de l’API doit être identique à celui de l’API non générée d’origine. Dans la plupart des cas, cela tombe naturellement, mais il y a des cas subtils. Nous examinerons l’un des cas les plus subtils que nous avons rencontrés, la méthode
Collections.max()
. Comme nous l’avons vu dans la section More Fun with Wildcards, une signature plausible pourmax()
est:
public static
> T max(Collection coll) public static
Cela va, sauf que l’effacement de cette signature est:> T max(Collection coll) public static Comparable max(Collection coll)
différent de la signature originale de max ():public static Object max(Collection coll)
On aurait certainement pu spécifier cette signature pour max (), mais cela n’a pas été fait, et tous les anciens fichiers de classes binarys qui appellent Collections.max () dépendent d’une signature qui retourne Object.