La méthode Arrays.asList ne renvoie pas java.util.ArrayList

Arrays.asList et java.util.ArrayList ne sont pas compatibles

Une méthode statique qui peut créer un objet List à partir d'arguments de longueur variable, ʻArrays.asList (T ... t) `, mais ne retourne pas un objet de java.util.ArrayList car il a des noms similaires. ..

Un code comme celui-ci entraînera une erreur de compilation.

java.util.ArrayList<Integer> arrayList = Arrays.asList(1,2,3); // no instance(s) of type variable(s) T exist so that List<T> conforms to ArrayList<Integer>

Puisqu'il est retourné en tant que type List, il semble bon si vous le castez en `` java.util.ArrayList '', et l'erreur de compilation disparaît en fait.

* Un mauvais casting
java.util.ArrayList<Integer> arrayList = (java.util.ArrayList<Integer>) Arrays.asList(1,2,3);

Mais j'obtiens une `` ClassCastException '' au moment de l'exécution. Ne fais jamais ça.

Jetez un œil au contenu de Arrays.asList

Jetez un œil à l'implémentation pour voir ce que la méthode `ʻArrays.asList`` renvoie.

Array.java


@SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
...Abréviation

return new ArrayList <> (a); renvoie une ArrayList! Je veux dire cela, mais suivons plus loin cette «liste de tableaux».

Array.java


/**
     * @serial include
     */
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
        }
...Abréviation

Vous pouvez voir qu'il a une `` classe ArrayList privée et statique '' imbriquée dans la classe Array, et qu'elle est nouvelle et instanciée.

Et cette classe ArrayList hérite de `ʻAbstractList, pas de la classe java.util.ArayList``. (Puisque java.util.ArayList hérite également de AbstractList, la hiérarchie d'héritage est la même)

__ En d'autres termes, Arrays.asList renvoie une instance du même nom que java.util.ArrayList (hors packages) mais une classe différente (pas de relation d'héritage). __

__La classe java.util.ArrayList et la classe ArrayList `` dans la classe `ʻArrays sont incompatibles. __

Par conséquent, ce qui précède

* Un mauvais casting
java.util.ArrayList<Integer> arrayList = (java.util.ArrayList<Integer>) Arrays.asList(1,2,3);

Découvrez pourquoi il lance une `` ClassCastException ''.

Lire la documentation officielle

Si vous lisez [documentation officielle de la classe Arrays] link-Arrays, l'explication de asList est

Renvoie une liste de taille fixe qui fonctionne avec le tableau spécifié.

une.

En d'autres termes, la classe __ArrayList de la classe Arrays est une liste de longueur fixe , qui est différente de la liste de longueur variable __ java.util.ArrayList.

Ne pas ajouter à la liste obtenue par Arrays.asList

Comme confirmé ci-dessus, la classe ArrayList dans Arrays a une longueur fixe, de sorte que le nombre d'éléments dans la __list ne peut pas être modifié. __

Ainsi, le code suivant se compilera, mais l'exception `ʻUnsupportedOperationException`` se produira lors de l'exécution.

//J'essaye d'ajouter un élément à une liste de longueur fixe
List<Integer> list1 = Arrays.asList(1,2,3);
list1.add(4);  // UnsupportedOperationException

C'est dans la description de la méthode add de la [documentation officielle de la classe AbstractList] link-AbstractList héritée.

Cette implémentation lève une exception UnsupportedOperationException sauf si add (int, E) est remplacé.

Cela est dû au fait que la classe ArrayList dans Arrays ne remplace pas la «méthode add (int, E)».

Beaucoup de gens utiliseraient add s'ils ne savaient pas que Arrays.asList renverrait une liste de longueur fixe.

Que diriez-vous de supprimer

Au fait, si vous utilisez également la méthode remove, "UnsupportedOperationException" se produira lors de l'exécution.

C'est une liste de longueur fixe, donc je ressens une forte volonté de ne jamais changer la taille.

Résumé

La liste retournée par ʻArrays.asList`` est incompatible avec `java.util.ArrayList``. Ne lancez pas.

Soit dit en passant, la liste retournée par `ʻArrays.asList`` est une liste de longueur fixe. Si vous modifiez la taille ultérieurement, une exception se produira.

Si vous voulez vraiment l'utiliser avec le type java.util.ArrayList, passez-le à l'argument du constructeur et utilisez-le. Puisqu'il ne s'agit plus d'une longueur fixe, vous pouvez l'ajouter et le supprimer.


//Aucune erreur de compilation ou ClassCastException au moment de l'exécution
List<Integer> list1 = Arrays.asList(1,2,3);
ArrayList<Integer> list2 = new ArrayList<>(list1);

Cependant, puisque __Arrays.asList retourne complètement élimine le mérite de la liste de longueur fixe __, je pense qu'il n'est pas nécessaire d'écrire un tel code, et il est préférable de gérer la liste avec le type d'interface List. Je pense que c'est le meilleur.

Recommended Posts

La méthode Arrays.asList ne renvoie pas java.util.ArrayList
[Ruby] Méthode qui renvoie la vérité