[Java] L'ajout d'un élément à la collection provoque une erreur de compilation

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

Les références

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.

environnement

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)

Sujet principal

Faites une liste immuable

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

Faire échouer la compilation de la méthode add

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

Extraire la valeur

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

Réaffectation

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;

Une échappatoire appelée type brut

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.

Résumé

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

[Java] L'ajout d'un élément à la collection provoque une erreur de compilation
J'obtiens une erreur lors de l'ajout d'une dépendance
[Java] Créer une collection avec un seul élément
Essayez d'ajouter du texte à une image avec Scala en utilisant la bibliothèque standard de Java
[Java] Comment convertir un élément d'un tableau de type String en type Int
Java: utilisez Stream pour trier le contenu d'une collection
Je veux renvoyer un type différent de l'élément d'entrée avec Java8 StreamAPI Reduce ()
[Rails] Traitement après l'ajout d'une colonne à la table de devise
Une erreur se produit lors de l'installation du bundle après avoir défini la base de données sur mysql
Créer une méthode pour renvoyer le taux de taxe en Java
Afficher un écran d'erreur pendant le processus de téléchargement pour répondre
Un mémorandum pour atteindre le lieu qui démange pour Java Gold
Obtenir une collection non vide à partir d'un flux facultatif avec java
Qu'est-ce qu'une collection Java?
Entrée dans la console Java
À propos de la méthode de conversion d'une chaîne de caractères en entier / fraction (données de conversion) en Java
[Java] Comment rechercher des valeurs dans un tableau (ou une liste) avec la méthode contains
Tri d'une liste avec un tableau de type int comme élément (Java) (Comparator)
Connexion à une base de données avec Java (partie 1) Peut-être la méthode de base
J'ai essayé de traduire le message d'erreur lors de l'exécution d'Eclipse (Java)
Remplacer par une valeur selon la correspondance avec une expression régulière Java
Convertir un tableau de chaînes en une liste d'entiers en Java
[Java] J'ai essayé de faire un labyrinthe par la méthode de creusage ♪
Comment résoudre l'erreur inconnue apparue lors de l'utilisation de slf4j en Java
Comment vérifier le contenu de la chaîne de caractères java de longueur fixe
Comment obtenir la longueur d'un fichier audio avec Java
Résolution d'une erreur survenue lors de la tentative d'utilisation de Spark dans un environnement où Java 8 et Java 11 coexistent
Comment définir une taille de récupération par défaut si jOOQ obtient une erreur OOM lors de la récupération d'un énorme jeu de résultats
Traitement pour émettre un message d'erreur
[java8] Pour comprendre l'API Stream
Comment créer un conteneur Java
Bienvenue dans le marais des bibliothèques Java! !!
La route de JavaScript à Java
Comment créer un tableau Java
[Rails] J'ai découvert les fichiers de migration! (Ajout d'une colonne au tableau)
Une collection de phrases qui impressionne le "sentiment différent" de Java et de JavaScript
L'histoire de l'oubli de fermer un fichier en Java et de l'échec
[Java] Comment transformer un tableau à deux dimensions avec une instruction for étendue
Tutoriel Rails Résolution de l'erreur de déploiement sur Heroku, alors notez la solution
Obtenez le type d'un élément d'un tableau pour déterminer s'il s'agit d'un tableau
Comment savoir quelle version Java d'un fichier de classe a été compilée
[Petite histoire Java] Surveiller lorsqu'une valeur est ajoutée à la liste
[Java] Comment accéder au début d'une chaîne spécifique à l'aide de la classe String
Je souhaite afficher un message d'erreur lors de l'inscription dans la base de données
Comment obtenir le chemin absolu d'un répertoire s'exécutant en Java
Je veux ForEach un tableau avec une expression Lambda en Java
Déployer une application Node.js sur une instance ECS à l'aide du Cloud Toolkit
Comment créer une application avec un mécanisme de plug-in [C # et Java]
Configurez une interface graphique Java dans un thread séparé pour conserver le
Que faire si le message "Un serveur est déjà en cours d'exécution" s'affiche. Erreur lors de la tentative de démarrage du serveur rails
[Note] [Débutant] Comment écrire lors de la modification de la valeur d'un élément de tableau dans une phrase répétée de Ruby
Une erreur s'est produite lors de l'exécution d'une fonction avec CURSOR défini dans le paramètre OUT de MyBatis dans PostgreSQL.