Il appartient à l'implémentation de modifier le contenu de la collection Java. Vous ne saurez pas si vous pouvez modifier cette collection tant que vous n'avez pas vérifié le code source ou essayé.
Par exemple, dans le javadoc de l'interface List, il est décrit comme suit.
UnsupportedOperationException - si l'opération d'ajout n'est pas prise en charge dans cette liste
UnsupportedOperationException - if the add operation is not supported by this list
C'est une telle spécification, donc nous ne pouvons rien y faire, mais c'est assez gênant pour l'appelant. Dans cet article, je vais vous montrer comment dire à l'appelant que «cette collection est immuable».
https://www.gwtcenter.com/covariance-and-contravariance Le contenu lui-même est presque écrit ici. Je l'ai trouvé utile pour communiquer l'immuabilité de la collection au compilateur, donc je vais approfondir cette partie cette fois.
J'utilise java11, mais cela fonctionne également avec 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)
La méthode java.util.Arrays # asList renvoie un List, qui ne peut pas utiliser add.
List<String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.add("d"); // UnsupportedOperationException
Définissez les génériques de fonction sur «? Etend la chaîne». Si vous le faites, toutes les méthodes qui prennent des génériques comme arguments entraîneront une erreur de compilation.
add
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.add("d"); // java:Type incompatible: java.lang.Chaîne? extends java.lang.Capture de chaîne#Ne peut pas être converti en 1
addAll
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
List<? extends String> anotherList = Arrays.asList("B");
unmodifiableList.addAll(anotherList); // java:Type incompatible: java.util.List<? extends java.lang.Capture de chaîne#1>Vers java.util.Collection<? extends ? extends java.lang.Capture de chaîne#2>Ne peut pas être converti en
replaceAll
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.replaceAll(s -> s.replaceAll("C", "D"));
En passant, si vous renvoyez la valeur telle quelle, l'erreur de compilation ne se produira pas.
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
unmodifiableList.replaceAll(s -> s);
unmodifiableList.forEach(System.out::println);
Il est possible de le récupérer en tant que type String.
get
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
String s = unmodifiableList.get(0);
System.out.println(s); // A
indexOf Les méthodes qui acceptent des arguments de type Object, tels que ʻindexOf`, peuvent être utilisées telles quelles.
List<String> unmodifiableList = Arrays.asList("A", "B", "C");
int index = unmodifiableList.indexOf("B");
System.out.println(index); // 1
Fondamentalement, vous ne pouvez pas supprimer ʻextends car vous ne pouvez pas le réaffecter à une variable qui n'utilise pas ʻextends
pour les génériques.
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
List<String> list = unmodifiableList; // java:Type incompatible: java.util.List<? extends java.lang.Capture de chaîne#1>Vers java.util.List<java.lang.String>Ne peut pas être converti en
L'affectation inverse est possible, donc la variable dans la méthode peut être List <String
et la valeur de retour peut être List <? Extends String>
.
List<String> unmodifiableList = Arrays.asList("A", "B", "C");
List<? extends String> list = unmodifiableList;
Cependant, il peut être affecté à des variables qui n'utilisent pas de génériques.
List<? extends String> unmodifiableList = Arrays.asList("A", "B", "C");
List rowList = unmodifiableList;
rowList.add("D"); // UnsupportedOperationException
~~ Le type brut lui-même est une opération non prise en charge ~~ Si vous voulez rendre une collection mutable telle que ʻArrayList` immuable, vous pouvez utiliser Collections # unmodifiableList. Enveloppez-le dans /Collections.html#unmodifiableList (java.util.List)) avant de le faire.
Des caractères supplémentaires seront ajoutés à la partie génériques, et il est utilisé différemment de l'objectif initial, donc je pense que c'est une bonne idée de l'utiliser beaucoup. Ce n'est pas sans échappatoires, donc ce n'est pas polyvalent. Mais est-ce plus gentil que de dire au moment de l'exécution que l'ajout, etc. ne peut pas être utilisé? Je pense que, donc je l'ai présenté cette fois.
Recommended Posts