72 votes

Pourquoi est-T lié par un Objet dans les Collections.max() signature?

Juste allé à travers la Java 7 java.util.Collections classe de mise en œuvre, et a vu quelque chose que je ne comprends pas en fonction max signature, pourquoi T est délimité par l'Objet ?

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
    Iterator<? extends T> i = coll.iterator();
    T candidate = i.next();

    while (i.hasNext()) {
        T next = i.next();
        if (next.compareTo(candidate) > 0)
            candidate = next;
    }
    return candidate;
} 

Pourquoi ne pas omettre l'objet de limites?

public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll) {
    Iterator<? extends T> i = coll.iterator();
    T candidate = i.next();

    while (i.hasNext()) {
        T next = i.next();
        if (next.compareTo(candidate) > 0)
            candidate = next;
    }
    return candidate;
}

Veuillez donner quelques exemples qui correspond à la méthode originale et non à la seconde.

86voto

Benjamin Gruenbaum Points 51406

Les deux ont les mêmes limites, mais il n'y est une différence subtile.

 <T extends Object & Comparable<? super T>> 

Cela entraînera T pour devenir un Object en vertu de l'effacement.

 <T extends Comparable<? super T>>

Cela entraînera T devenir Comparable en vertu de l'effacement.


Dans ce cas, il est fait parce que, .max antérieure de Java 5. Nous pouvons voir dans ce lien Joachim gentiment à condition que la signature de l' .max en Java 1.4.2 est:

public static Object max(Collection coll)

Si nous avions utilisé <T extends Comparable<? super T>> liées, notre signature

public static Comparable max(Collection coll)

Qui briserait l'Api. J'ai réussi à trouver cette page qui traite de la conversion de la vieille Api pour les génériques et il donne de l' .max comme un exemple précis.

Ici, ils expliquent pourquoi max est définie de cette manière:

Vous devez également vous assurer que la nouvelle version de l'API conserve la compatibilité binaire avec les anciens clients. Cela implique que l'effacement de l'API doit être le même que l'original, ungenerified API. Dans la plupart des cas, cela tombe naturellement, mais il existe des cas subtils. Nous allons les examiner l'un de la plus subtile des cas que nous avons rencontrés, la méthode Collections.max(). Comme nous l'avons vu dans la section Plus de Plaisir avec des caractères génériques, un plausible signature pour max() est:

public static <T extends Comparable<? super T>> T max(Collection<T> coll) Ce qui est bien, sauf que l'effacement de cette signature est: public static Comparable max(Collection coll) qui est différent de l'original de la signature de max(): public static Object max(Collection coll)

On pourrait certainement avoir précisé cette signature pour max(), mais il n'a pas été fait, et de tous les anciens binaires, fichiers de classe qui appellent des Collections.max() dépendent d'une signature qui renvoie l'Objet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X