Es liegt an der Implementierung, den Inhalt der Java Collection zu ändern. Sie werden nicht wissen, ob Sie diese Sammlung ändern können, bis Sie den Quellcode überprüfen oder ausprobieren.
Im Javadoc der List-Schnittstelle wird dies beispielsweise wie folgt beschrieben.
UnsupportedOperationException --wenn das Hinzufügen in dieser Liste nicht unterstützt wird
UnsupportedOperationException - if the add operation is not supported by this list
Dies ist eine solche Spezifikation, daher können wir nichts dagegen tun, aber es ist für den Anrufer ziemlich unpraktisch. In diesem Artikel zeige ich Ihnen, wie Sie dem Anrufer mitteilen können, dass "diese Sammlung unveränderlich ist".
https://www.gwtcenter.com/covariance-and-contravariance Der Inhalt selbst ist hier fast geschrieben. Ich fand es nützlich, dem Compiler die Unveränderlichkeit der Sammlung mitzuteilen, daher werde ich mich dieses Mal mit diesem Teil befassen.
Ich benutze Java11, aber es funktioniert auch mit Java8.
$ java --version
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.21.0, JRE 11 Mac OS X amd64-64-Bit Compressed References 20200715_677 (JIT enabled, AOT enabled)
OpenJ9 - 34cf4c075
OMR - 113e54219
JCL - 95bb504fbb based on jdk-11.0.8+10)
Die Methode java.util.Arrays # asList gibt eine Liste zurück, die add nicht verwenden kann.
List<String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.add("d"); // UnsupportedOperationException
Setzen Sie die Funktionsgenerika auf "? Extends String". Wenn Sie dies tun, führen alle Methoden, die Generika als Argumente verwenden, zu einem Kompilierungsfehler.
add
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.add("d"); // java:Inkompatibler Typ: java.lang.String? extends java.lang.String-Erfassung#Kann nicht in 1 konvertiert werden
addAll
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
List<? extends String> anotherList = Arrays.asList("B");
unmodifiableList.addAll(anotherList); // java:Inkompatibler Typ: java.util.List<? extends java.lang.String-Erfassung#1>Nach Java.util.Collection<? extends ? extends java.lang.String-Erfassung#2>Kann nicht konvertiert werden
replaceAll
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.replaceAll(s -> s.replaceAll("C", "D"));
Übrigens, wenn Sie den Wert so zurückgeben, wie er ist, tritt der Kompilierungsfehler nicht auf.
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.replaceAll(s -> s);
unmodifiableList.forEach(System.out::println);
Es ist möglich, es als String-Typ abzurufen.
get
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
String s = unmodifiableList.get(0);
System.out.println(s); // A
indexOf Methoden, die Argumente vom Typ Objekt verwenden, wie z. B. "indexOf", können unverändert verwendet werden.
List<String> unmodifiableList = Arrays.asList("A", "B", "C");
int index = unmodifiableList.indexOf("B");
System.out.println(index); // 1
Sie können einer Variablen, die für Generika keine "Erweiterungen" verwendet, keine Neuzuweisung zuweisen. Daher können Sie "Erweiterungen" grundsätzlich nicht entfernen.
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
List<String> list = unmodifiableList; // java:Inkompatibler Typ: java.util.List<? extends java.lang.String-Erfassung#1>Nach Java.util.List<java.lang.String>Kann nicht konvertiert werden
Da die umgekehrte Zuordnung möglich ist, ist es auch möglich, "List <String" als Variable in der Methode und "List <? Extends String>" als Rückgabewert zu verwenden.
List<String> unmodifiableList = Arrays.asList("A", "B", "C");
List<? extends String> list = unmodifiableList;
Es kann jedoch Variablen zugewiesen werden, die keine Generika verwenden.
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
List rowList = unmodifiableList;
rowList.add("D"); // UnsupportedOperationException
~~ Der Rohtyp selbst ist eine nicht unterstützte Operation ~~ Wenn Sie eine veränderbare Sammlung wie "ArrayList" unveränderlich machen möchten, können Sie [Sammlungen # unmodifizierbare Liste] verwenden (https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util). Wickeln Sie es vorher in /Collections.html#unmodizableList (java.util.List) ein.
Dem generischen Teil werden zusätzliche Zeichen hinzugefügt, und er wird anders als der ursprüngliche Zweck verwendet. Ich denke, es ist eine gute Idee, ihn häufig zu verwenden. Es ist nicht ohne Lücken, also nicht allzweckmäßig. Aber ist es freundlicher, als zur Laufzeit zu sagen, dass Hinzufügen usw. nicht verwendet werden kann? Ich denke das, also habe ich es dieses Mal vorgestellt.
Recommended Posts