quel est le sens de ArrayList final?

Quels avantages / inconvénients pouvons-nous obtenir en rendant ArrayList (ou autre collection) final? Je peux encore append à de nouveaux éléments ArrayList, supprimer des éléments et le mettre à jour. Mais qu’est-ce que l’effet fait que c’est final?

Mais qu’est-ce que l’effet fait que c’est final?

Cela signifie que vous ne pouvez pas relier la variable pour qu’elle pointe vers une autre instance de collection :

final List list = new ArrayList(); list = new ArrayList(); // Since `list' is final, this won't comstack 

En termes de style, je déclare la plupart des références que je n’ai pas l’intention de modifier comme final .

Je peux encore append à de nouveaux éléments ArrayList, supprimer des éléments et le mettre à jour.

Si vous le souhaitez, vous pouvez empêcher l’insertion, le retrait, etc. en utilisant Collections.unmodifiableList() :

 final List list = Collections.unmodifiableList(new ArrayList(...)); 

Cela signifie simplement que vous ne pouvez pas réatsortingbuer sa référence. Tenter de faire quelque chose comme ci-dessous entraînera une erreur de compilation.

 final List list = new ArrayList(); list = new LinkedList(); ^ Comstackr error here 

Si vous voulez vraiment une liste immuable, vous devez utiliser la méthode Collections.unmodifiableList() .

Vous ne pourrez pas modifier sa référence à l’aide de la new ArrayList par exemple.

Rendre la variable final permet de ne pas pouvoir réaffecter cette référence après qu’elle ait été assignée. Comme vous le mentionnez, vous pouvez toujours utiliser cette liste de méthodes pour apporter des modifications.

Si vous combinez le mot-clé final avec l’utilisation de Collections.unmodifiableList , vous avez le comportement que vous tentez probablement d’obtenir, par exemple:

 final List fixedList = Collections.unmodifiableList(someList); 

Cela a pour conséquence que la liste pointée par fixedList ne peut pas être modifiée. Attention cependant, il peut toujours être modifié via la référence someList (assurez-vous donc qu’il est hors de scope après cet atsortingbut).

final a beaucoup de conséquences sous multi threading.

  1. JMM définit clairement la finalisation de l’initialisation d’un champ final est garantie.

Ce qui n’est pas clairement défini est:

  1. Les compilateurs sont libres de les réorganiser à travers des barrières de mémoire.
  2. Les compilateurs peuvent toujours lire une copie en cache.

Cela n’affecte pas ce que vous pouvez faire avec la ArrayList, comme vous le constatez à juste titre – la ArrayList elle-même est toujours modifiable. Vous venez de rendre la référence immuable.

Mais faire une variable finale a d’autres avantages:

  • Il empêche la modification de la variable si elle doit restr constante. Cela peut aider à prévenir de futurs bogues.
  • Faire des variables final peut aider le compilateur à optimiser certaines performances.

En général, plus vous faites de choses immuables, mieux c’est. Faire des références finales (même si ce sont des références à des objects mutables) est généralement une bonne idée.

Final est un mot-clé ou un mot réservé en Java et peut être appliqué aux variables membres, aux méthodes, aux classes et aux variables locales en Java. Une fois que vous avez créé une référence finale, vous n’êtes pas autorisé à modifier cette référence et le compilateur vérifiera cela et générera une erreur de compilation si vous essayez de réinitialiser les variables finales dans Java.

Vous ne pouvez pas le relier à une collection différente comme l’a dit aix.

Exemple: En conjonction avec une implémentation de liste immuable, vous obtenez des membres sûrs que vous pouvez rendre publics.

Exemple: Lorsque vous vous fiez à cette référence, cela ne change pas le besoin final. Cela est vrai dans les scénarios de synchronisation, par exemple.

Il peut y avoir beaucoup plus d’exemples. C’est un bon style de déclarer les membres finaux si vous n’avez pas l’intention de changer la référence du tout.

Pour obtenir une liste vraiment immuable, vous devrez faire des copies complètes du contenu de la liste. UnmodifiableList ne ferait que rendre la liste des références quelque peu immuable. Faire une copie en profondeur de la liste ou du tableau sera maintenant difficile avec la taille croissante de la mémoire. Vous pouvez utiliser la sérialisation / désérialisation et stocker la copie profonde du tableau / liste dans un fichier temporaire. Le setter ne serait pas disponible car le membre doit être immuable. Le getter sérialiserait la variable membre dans un fichier, puis le désialiserait pour obtenir une copie profonde. La séraialisation a pour nature innée de pénétrer dans les profondeurs d’un arbre d’objects. Cela assurerait une immuabilité complète à un coût de performance cependant.

  package com.home.immutable.serial; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; public final class ImmutableBySerial { private final int num; private final Ssortingng str; private final ArrayList immutableList; ImmutableBySerial(int num, Ssortingng str, ArrayList list){ this.num = num; this.str = str; this.immutableList = getDeepCloned(list); } public int getNum(){ return num; } public Ssortingng getStr(){ return str; } public ArrayList getImmutableList(){ return getDeepCloned(immutableList); } private ArrayList getDeepCloned(ArrayList list){ FileOutputStream fos = null; ObjectOutputStream oos = null; FileInputStream fis = null; ObjectInputStream ois = null; ArrayList clonedObj = null; try { fos = new FileOutputStream(new File("temp")); oos = new ObjectOutputStream(fos); oos.writeObject(list); fis = new FileInputStream(new File("temp")); ois = new ObjectInputStream(fis); clonedObj = (ArrayList)ois.readObject(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { oos.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } return clonedObj; } } 

Je marque personnellement le champ des collections de mes classes comme final pour empêcher les utilisateurs de ma classe de vérifier si elle est nulle ou non. Cela fonctionne car, une fois que la valeur est déjà affectée à une variable finale, elle ne peut jamais être réaffectée à une autre valeur, y compris null.

Essentiellement, ce que vous essayez d’atteindre, c’est de rendre la liste immuable. Cependant, lorsque vous marquez la référence de liste finale, cela signifie que la référence ne peut pas être pointée sur un autre object de liste autre que celui-ci.

Si vous voulez un ArrayList final (immuable), utilisez plutôt la méthode utilitaire Collections.unmodifaibleList (list) de la classe Collections.

Je suis venu à penser à cette même question et à coder et à donner un exemple sous un autre angle.

Le tableau final peut toujours être modifié, référez-vous à l’exemple ci-dessous et lancez-le pour vous-même.

Voici la classe immuable avec déclaration de liste immuable:

 public final class ImmutableClassWithArrayList { final List theFinalListVar = new ArrayList(); } 

Et voici le pilote:

 public class ImmutableClassWithArrayListTester { public static void main(Ssortingng[] args) { ImmutableClassWithArrayList immClass = new ImmutableClassWithArrayList(); immClass.theFinalListVar.add("name"); immClass.theFinalListVar.forEach(str -> System.out.println(str)); } } 

Comme vous pouvez le voir, la méthode principale consiste à append (modifier) ​​la liste. La seule chose à noter est que la “référence” à l’object du type de collection ne peut pas être ré-assignée à un autre object de ce type. Comme dans la réponse d’adarshr ci-dessus, vous ne pouvez pas faire immClass.theFinalListVar = new ArrayList (); dans la méthode principale ici.

La partie modification m’a vraiment aidé à comprendre cela et j’espère que cela aidera de la même manière.