2 votes

Pourquoi le constructeur d'ArrayList<E> autorise-t-il un paramètre brut d'ArrayList ?

Pourquoi ce code compile-t-il :

ArrayList strings = new ArrayList();
strings.add("s1");
strings.add("s2");

ArrayList<Integer> numbers = new ArrayList<Integer>(strings);

Étant donné que le constructeur en question s'attend à un fichier Collection<? extends E>E dans ce cas est Integer ? Comment les objets sont-ils contenus dans le type brut ArrayList une sous-classe de E ? Ou existe-t-il une magie cachée du compilateur qui permet cela à des fins patrimoniales ?

2voto

Jerry06 Points 2443

Vérifiez le ArrayList constructeur :

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

El elementData est un tableau d'objets :

transient Object[] elementData;

Si nouveau ArrayList(Collection<? extends E> c) acceptera tous les Collection je m'en fiche E type

Il va jeter ClassCastExceptionwhen quand nous l'utilisons :

Integer i= numbers.get(1);

1voto

actc Points 625

Le compilateur devrait vous donner cet avertissement :

Sécurité du type : L'expression de type ArrayList a besoin d'une conversion non vérifiée. pour se conformer à Collection<? extends Integer>

disant qu'il y a un problème avec l'argument donné (chaînes de caractères).

Vous devriez également obtenir cette exception lorsque vous essayez d'exécuter le code :

java.lang.ClassCastException : java.lang.String cannot be cast to java.lang.Integer

La raison pour laquelle vous n'obtenez pas d'erreur de compilation est que le ArrayList strings n'est pas défini correctement, vous avez omis le type String. Donc la compilation peut seulement deviner qu'il y a quelque chose qui ne va pas. Changez votre code en

ArrayList<String> strings = new ArrayList<String>();

et vous obtiendrez l'erreur de compilation

Le constructeur ArrayList<Integer>(ArrayList<String>) est indéfini

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