Die Arrays.asList-Methode gibt nicht java.util.ArrayList zurück

Arrays.asList und java.util.ArrayList sind nicht kompatibel

Eine statische Methode, die ein List-Objekt aus Argumenten variabler Länge, Arrays.asList (T ... t), generieren kann, aber kein Objekt von java.util.ArrayList zurückgibt, da es ähnliche Namen hat ..

Code wie der folgende führt zu einem Kompilierungsfehler.

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>

Da es als Listentyp zurückgegeben wird, sieht es gut aus, wenn Sie es in "java.util.ArrayList" umwandeln und der Kompilierungsfehler tatsächlich verschwindet.

* Eine schlechte Besetzung
java.util.ArrayList<Integer> arrayList = (java.util.ArrayList<Integer>) Arrays.asList(1,2,3);

Aber zur Laufzeit bekomme ich eine "ClassCastException". Mache das niemals.

Schauen Sie sich den Inhalt von Arrays.asList an

Werfen Sie einen Blick auf die Implementierung, um zu sehen, was die Methode "Arrays.asList" zurückgibt.

Array.java


@SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
...Abkürzung

return new ArrayList <> (a); gibt eine ArrayList zurück! Ich möchte sagen, aber folgen wir der ArrayList weiter.

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);
        }
...Abkürzung

Sie können sehen, dass es eine verschachtelte "private und statische ArrayList-Klasse" in der Array-Klasse hat und neu und instanziiert ist.

Und diese ArrayList-Klasse erbt "AbstractList", nicht die "java.util.ArayList" -Klasse. (Da java.util.ArayList auch AbstractList erbt, ist die Vererbungshierarchie dieselbe.)

__ Mit anderen Worten, Sie können sehen, dass Arrays.asList eine Instanz mit demselben Namen wie java.util.ArrayList (ohne Pakete) zurückgibt, jedoch mit einer anderen Klasse (keine Vererbungsbeziehung). __ __

__Die java.util.ArrayList-Klasse und die ArrayList-Klasse in der Arrays-Klasse sind nicht kompatibel. __ __

Daher die oben genannten

* Eine schlechte Besetzung
java.util.ArrayList<Integer> arrayList = (java.util.ArrayList<Integer>) Arrays.asList(1,2,3);

Fand heraus, warum es eine `` `ClassCastException``` auslöst.

Lesen Sie die offizielle Dokumentation

Wenn Sie [Offizielle Dokumentation der Arrays-Klasse] Link-Arrays lesen, lautet die Erklärung von asList

Gibt eine Liste mit fester Größe zurück, die mit dem angegebenen Array funktioniert.

ein.

Mit anderen Worten, die __ArrayList-Klasse in der Arrays-Klasse ist eine Liste mit fester Länge , die sich von der __ Liste mit variabler Länge java.util.ArrayList unterscheidet.

Nicht zu der von Arrays.asList erhaltenen Liste hinzufügen

Wie oben bestätigt, hat die ArrayList-Klasse in Arrays eine feste Länge, sodass die Anzahl der Elemente in der __list nicht geändert werden kann. __ __

Der folgende Code wird also kompiliert, aber die Ausnahme "UnsupportedOperationException" wird zur Laufzeit auftreten.

//Ich versuche, einer Liste mit fester Länge ein Element hinzuzufügen
List<Integer> list1 = Arrays.asList(1,2,3);
list1.add(4);  // UnsupportedOperationException

Dies ist in der Beschreibung der Add-Methode der geerbten [offiziellen Dokumentation der AbstractList-Klasse] link-AbstractList enthalten.

Diese Implementierung löst eine UnsupportedOperationException aus, sofern add (int, E) nicht überschrieben wird.

Dies liegt daran, dass die ArrayList-Klasse in Arrays die Methode add (int, E) nicht überschreibt.

Viele Leute würden add verwenden, wenn sie nicht wüssten, dass Arrays.asList eine Liste mit fester Länge zurückgeben würde.

Wie wäre es zu entfernen

Übrigens, wenn Sie auch die Methode remove verwenden, wird zur Laufzeit UnsupportedOperationException auftreten.

Es ist eine Liste mit fester Länge, daher habe ich den starken Willen, die Größe niemals zu ändern.

Zusammenfassung

Die von Arrays.asList zurückgegebene Liste ist nicht kompatibel mit java.util.ArrayList. Nicht besetzen.

Übrigens ist die von "Arrays.asList" zurückgegebene Liste eine Liste mit fester Länge. Wenn Sie die Größe später ändern, tritt eine Ausnahme auf.

Wenn Sie es wirklich mit dem Typ "java.util.ArrayList" verwenden möchten, übergeben Sie es an das Argument des Konstruktors und verwenden Sie es. Da es sich nicht mehr um eine feste Länge handelt, können Sie sie hinzufügen und entfernen.


//Kein Kompilierungsfehler oder ClassCastException zur Laufzeit
List<Integer> list1 = Arrays.asList(1,2,3);
ArrayList<Integer> list2 = new ArrayList<>(list1);

Da jedoch durch die Rückgabe von __Arrays.asList der Vorteil einer Liste mit fester Länge __ vollständig beseitigt wird, ist es meines Erachtens nicht erforderlich, solchen Code zu schreiben, und es ist besser, die Liste mit dem List-Schnittstellentyp zu behandeln. Ich denke es ist das Beste.

Recommended Posts

Die Arrays.asList-Methode gibt nicht java.util.ArrayList zurück
[Ruby] Methode, die die Wahrheit zurückgibt