Pourquoi T est-il limité par Object dans la signature Collections.max ()?

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 pour max() est:

public static > T max(Collection coll) public static > T max(Collection coll) Cela va, sauf que l’effacement de cette signature est: 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.