[Java] Das Hinzufügen eines Elements zur Sammlung führt zu einem Kompilierungsfehler

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

Verweise

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.

Umgebung

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)

Hauptthema

Machen Sie eine unveränderliche Liste

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

Stellen Sie sicher, dass die add-Methode nicht kompiliert werden kann

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);

Wert extrahieren

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

Neuzuweisung

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;

Eine Lücke namens Rohtyp

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.

Zusammenfassung

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

[Java] Das Hinzufügen eines Elements zur Sammlung führt zu einem Kompilierungsfehler
Beim Hinzufügen einer Abhängigkeit wird eine Fehlermeldung angezeigt
[Java] Erstellen Sie eine Sammlung mit nur einem Element
Versuchen Sie, mit Scala mithilfe der Standardbibliothek von Java Text zu einem Bild hinzuzufügen
[Java] So konvertieren Sie ein Element eines Array vom Typ String in einen Int-Typ
Java: Verwenden Sie Stream, um den Inhalt einer Sammlung zu sortieren
Ich möchte mit Java8 StreamAPI redu () einen anderen Typ als das Eingabeelement zurückgeben.
[Rails] Verarbeitung nach Hinzufügen einer Spalte zur Entwicklertabelle
Bei der Bundle-Installation tritt ein Fehler auf, nachdem die Datenbank auf MySQL gesetzt wurde
Erstellen Sie eine Methode, um den Steuersatz in Java zurückzugeben
Zeigen Sie während des Downloadvorgangs einen Fehlerbildschirm an, um zu antworten
Ein Memorandum, um den juckenden Ort für Java Gold zu erreichen
Holen Sie sich mit Java eine nicht leere Sammlung aus einem optionalen Stream
Was ist eine Java-Sammlung?
Eingabe in die Java-Konsole
Informationen zur Methode zum Konvertieren einer Zeichenfolge in eine Ganzzahl / einen Bruch (Umwandlungsdaten) in Java
[Java] So suchen Sie mit der Methode includes nach Werten in einem Array (oder einer Liste)
Sortieren einer Liste mit einem Array vom Typ int als Element (Java) (Comparator)
Herstellen einer Verbindung zu einer Datenbank mit Java (Teil 1) Möglicherweise die grundlegende Methode
Ich habe versucht, die Fehlermeldung beim Ausführen von Eclipse (Java) zu übersetzen.
Ersetzen Sie durch einen Wert entsprechend der Übereinstimmung mit einem regulären Java-Ausdruck
Verwandeln Sie ein Array von Strings in eine Liste von Ganzzahlen in Java
[Java] Ich habe versucht, mit der Grabmethode ein Labyrinth zu erstellen ♪
So beheben Sie den unbekannten Fehler, der bei der Verwendung von slf4j in Java aufgetreten ist
So überprüfen Sie den Inhalt der Java-Zeichenfolge mit fester Länge
So ermitteln Sie die Länge einer Audiodatei mit Java
Es wurde ein Fehler behoben, der beim Versuch auftrat, Spark in einer Umgebung zu verwenden, in der Java 8 und Java 11 gleichzeitig vorhanden sind
So legen Sie eine Standardabrufgröße fest, wenn jOOQ beim Abrufen einer großen Ergebnismenge einen OOM-Fehler erhält
Verarbeitung zur Ausgabe einer Fehlermeldung
[java8] Um die Stream-API zu verstehen
So erstellen Sie einen Java-Container
Willkommen im Sumpf der Java-Bibliotheken! !!
Der Weg von JavaScript nach Java
So erstellen Sie ein Java-Array
[Rails] Ich habe etwas über Migrationsdateien gelernt! (Hinzufügen einer Spalte zur Tabelle)
Eine Sammlung von Phrasen, die das "unterschiedliche Gefühl" von Java und JavaScript beeindruckt
Die Geschichte, zu vergessen, eine Datei in Java zu schließen und zu scheitern
[Java] So drehen Sie ein zweidimensionales Array mit einer erweiterten for-Anweisung
Rails Tutorial Der Bereitstellungsfehler für Heroku wurde behoben. Beachten Sie daher die Lösung
Rufen Sie den Typ eines Elements eines Arrays ab, um festzustellen, ob es sich um ein Array handelt
So finden Sie heraus, welche Java-Version der Klassendatei kompiliert wurde
[Java small story] Überwachen Sie, wann der Liste ein Wert hinzugefügt wird
[Java] Wie man mit der String-Klasse an die Spitze eines bestimmten Strings kommt
Ich möchte bei der Registrierung in der Datenbank eine Fehlermeldung anzeigen
So ermitteln Sie den absoluten Pfad eines in Java ausgeführten Verzeichnisses
Ich möchte für jedes Array mit Lambda-Ausdruck in Java
Bereitstellen einer Node.js-Anwendung auf einer ECS-Instanz mithilfe des Cloud Toolkit
So erstellen Sie eine App mit einem Plug-In-Mechanismus [C # und Java]
Richten Sie eine Java-GUI in einem separaten Thread ein, um die Haupt-GUI beizubehalten
Was tun, wenn die Meldung "Ein Server läuft bereits" angezeigt wird. Fehler beim Versuch, den Rails-Server zu starten
[Hinweis] [Anfänger] Schreiben, wenn der Wert eines Array-Elements in einem sich wiederholenden Satz von Ruby geändert wird
Beim Ausführen einer Funktion in PostgreSQL mit dem Parameter OUT von MyBatis auf CURSOR ist ein Fehler aufgetreten.