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.
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.
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.
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.
Ü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.
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.