Si les objets immuables¹ sont bons, simples et offrent des avantages en programmation simultanée, pourquoi les programmeurs continuent-ils à créer des objets mutables²?
J'ai quatre ans d'expérience dans la programmation Java et, à mon avis, après avoir créé une classe, les personnes créent des getters et des setters dans l'EDI (ce qui la rend mutable). Y a-t-il un manque de conscience ou pouvons-nous nous en tirer avec l'utilisation d'objets mutables dans la plupart des scénarios?
¹ Un objet immuable est un objet dont l’état ne peut plus être modifié après sa création.
² L' objet mutable est un objet qui peut être modifié après sa création.
object-oriented
immutability
ahsteele
la source
la source
Réponses:
Les objets mutables et immuables ont leurs propres utilisations, avantages et inconvénients.
Les objets immuables rendent effectivement la vie plus simple dans de nombreux cas. Ils sont particulièrement applicables aux types de valeur, où les objets n'ont pas d'identité et peuvent donc être facilement remplacés. Et ils peuvent rendre la programmation concurrente plus sûre et plus propre (la plupart des bogues de concomitance notoirement difficiles à trouver sont en fin de compte causés par l’état mutable partagé entre les threads). Cependant, pour les objets volumineux et / ou complexes, créer une nouvelle copie de l'objet à chaque modification peut s'avérer très coûteux et / ou fastidieux. Et pour les objets ayant une identité distincte, modifier un objet existant est beaucoup plus simple et intuitif que de créer une nouvelle copie modifiée de celui-ci.
Pensez à un personnage de jeu. Dans les jeux, la vitesse est la priorité absolue. Par conséquent, si vous représentez vos personnages avec des objets mutables, votre jeu fonctionnera beaucoup plus rapidement qu'une implémentation alternative dans laquelle une nouvelle copie du personnage du jeu est générée à chaque petit changement.
De plus, notre perception du monde réel est inévitablement basée sur des objets mutables. Lorsque vous remplissez votre voiture d’essence à la station-service, vous la percevez comme le même objet (c’est-à-dire que son identité est conservée tant que son état change) - ce n’est pas comme si l’ancienne voiture avec un réservoir vide était remplacée par une nouvelle instances de voiture ayant leur réservoir progressivement de plus en plus plein. Ainsi, chaque fois que nous modélisons un domaine réel dans un programme, il est généralement plus simple et plus simple d'implémenter le modèle de domaine en utilisant des objets mutables pour représenter des entités réelles.
En dehors de toutes ces raisons légitimes, hélas, la raison la plus probable pour laquelle les gens continuent à créer des objets mutables est l'inertie de l'esprit, autrement dit la résistance au changement. Notez que la plupart des développeurs d'aujourd'hui ont été formés bien avant que l'immutabilité (et le paradigme de contenu, la programmation fonctionnelle) ne soit devenue "tendance" dans leur sphère d'influence, et ne gardent pas leurs connaissances à jour sur les nouveaux outils et méthodes de notre métier - En fait, beaucoup d’êtres humains résistent positivement aux nouvelles idées et processus. «J'ai été la programmation comme ça depuis nn ans et je ne me soucie pas des dernières manies stupides! »
la source
Point
classe dans .NET par exemple est immuable, mais la création de nouveaux points à la suite de modifications est simple et donc abordable. L'animation d'un personnage immuable peut être rendue très économique en découplant les «pièces mobiles» (mais oui, certains aspects sont alors mutables). (2) Les «objets volumineux et / ou complexes» peuvent très bien être immuables. Les cordes sont souvent volumineuses et bénéficient généralement de l'immuabilité. Une fois, j'ai réécrit une classe de graphes complexe pour qu'elle soit immuable, ce qui rend le code plus simple et plus efficace. Dans de tels cas, la clé est d'avoir un constructeur mutable.Je pense que vous avez tous manqué la réponse la plus évidente. La plupart des développeurs créent des objets mutables car la mutabilité est la valeur par défaut dans les langages impératifs. La plupart d’entre nous ont mieux à faire avec notre temps que de modifier constamment le code pour l’éloigner des valeurs par défaut - plus correct ou non. Et l'immuabilité n'est pas une panacée, pas plus que toute autre approche. Cela facilite certaines choses mais rend beaucoup d’autres beaucoup plus difficile, comme certaines réponses l’ont déjà indiqué.
la source
final
,const
etc. demande un peu d'effort supplémentaire ... sauf si vous configurez un modèle de code :-)Il y a une place pour la mutabilité. Les principes de conception pilotés par domaine fournissent une solide compréhension de ce qui devrait être modifiable et de ce qui devrait être immuable. Si vous y réfléchissez, vous réaliserez qu'il n'est pas pratique de concevoir un système dans lequel tout changement d'état d'un objet nécessite sa destruction et sa recomposition, ainsi que tout objet qui l'a référencé. Avec des systèmes complexes, cela pourrait facilement conduire à un effacement complet et à une reconstruction du graphe d'objets du système entier.
La plupart des développeurs ne font pas quoi que les exigences de performances soient suffisamment importantes pour qu'ils aient besoin de se concentrer sur la concurrence (ou sur de nombreux autres problèmes considérés universellement comme une bonne pratique par ceux qui sont informés).
Il y a des choses que vous ne pouvez tout simplement pas faire avec des objets immuables, comme avoir des relations bidirectionnelles. Une fois que vous avez défini une valeur d'association sur un objet, son identité change. Donc, vous définissez la nouvelle valeur sur l'autre objet et cela change également. Le problème est que la référence du premier objet n'est plus valide, car une nouvelle instance a été créée pour représenter l'objet avec la référence. Si cela continuait, il en résulterait des régressions infinies. Après avoir lu votre question, j’ai fait une petite étude de cas. Voici à quoi cela ressemble. Avez-vous une approche alternative qui permet une telle fonctionnalité tout en maintenant l’immutabilité?
la source
Relationship(a, b)
; Au moment de créer la relation, les deux entitésa
&b
existent déjà, et la relation elle-même est également immuable. Je ne dis pas que cette approche est pratique en Java; juste que c'est possible.R
est leRelationship(a,b)
et les deuxa
etb
sont immuables,a
nib
ne détiendrait une référenceR
. Pour que cela fonctionne, la référence devrait être stockée ailleurs (comme une classe statique). Est-ce que je comprends bien votre intention?J'ai lu "des structures de données purement fonctionnelles", et cela m'a fait comprendre qu'il existe de nombreuses structures de données qui sont beaucoup plus faciles à implémenter à l'aide d'objets mutables.
Pour implémenter une arborescence de recherche binaire, vous devez retourner une nouvelle arborescence à chaque fois: votre nouvelle arborescence devra faire une copie de chaque nœud modifié (les branches non modifiées sont partagées). Ce n'est pas si grave pour votre fonction d'insertion, mais pour moi, les choses sont devenues assez inefficaces rapidement lorsque j'ai commencé à travailler sur la suppression et le rééquilibrage.
L'autre chose à réaliser est que vous pouvez passer des années à écrire du code orienté objet et ne réalisez jamais à quel point un état mutable partagé peut être terrible, si votre code n'est pas exécuté de manière à exposer les problèmes de simultanéité.
la source
De mon point de vue, c'est un manque de conscience. Si vous examinez d'autres langages JVM connus (Scala, Clojure), les objets mutables sont rarement vus dans le code. C'est pourquoi les gens commencent à les utiliser dans des scénarios où le threading unique ne suffit pas.
J'apprends actuellement Clojure et j'ai une petite expérience de Scala (plus de 4 ans en Java) et votre style de codage change en raison de la prise de conscience de l'état.
la source
Je pense que l' un des principaux facteurs contribuant a été ignoré: Java Beans comptent beaucoup sur un style spécifique d'objets muter, et (surtout compte tenu de la source) tout à fait un peu de gens semblent prendre cela comme un (ou même le ) exemple canonique de la façon dont tous Java devrait être écrit.
la source
Tous les systèmes Java d'entreprise sur lesquels j'ai travaillé au cours de ma carrière utilisent Hibernate ou l'API JPA (Java Persistence API). Hibernate et JPA indiquent essentiellement que votre système utilise des objets mutables, car leur principe de base est qu'ils détectent et enregistrent les modifications apportées à vos objets de données. Pour de nombreux projets, la facilité de développement apportée par Hibernate est plus convaincante que les avantages d’objets immuables.
Il est évident que les objets mutables existent depuis beaucoup plus longtemps qu'Hibernate. Hibernate n'est donc probablement pas la "cause" initiale de la popularité des objets mutables. Peut-être que la popularité des objets mutables a permis à Hibernate de s’épanouir.
Mais aujourd’hui, si de nombreux jeunes programmeurs se moquent des systèmes d’entreprise utilisant Hibernate ou un autre ORM, ils prendront vraisemblablement l’habitude d’utiliser des objets mutables. Des frameworks comme Hibernate peuvent enraciner la popularité des objets mutables.
la source
Un point important qui n’a pas encore été mentionné est que le fait que l’état d’un objet soit mutable permette de rendre immuable l’ identité de l’objet qui encapsule cet état.
De nombreux programmes sont conçus pour modéliser des choses du monde réel qui sont intrinsèquement mutables. Supposons qu’à 00h51, une variable
AllTrucks
contienne une référence à l’objet n ° 451, qui est la racine d’une structure de données qui indique quelle cargaison est contenue dans tous les camions d’une flotte à ce moment-là (12h51), et certaines variables.BobsTruck
peut être utilisé pour obtenir une référence à l'objet # 24601, à un objet indiquant quelle cargaison est contenue dans le camion de Bob à ce moment-là (12h51). À 12h52, certains camions (y compris ceux de Bob) sont chargés et déchargés, et les structures de données sont mises à jour de sorte àAllTrucks
contenir une référence à une structure de données indiquant que la cargaison est dans tous les camions à compter de 12h52.Que devrait-il arriver
BobsTruck
?Si la propriété 'cargo' de chaque objet camion est immuable, l'objet # 24601 représentera à tout jamais l'état du camion de Bob à 00h51. Si
BobsTruck
contient une référence directe à l'objet n ° 24601, à moins que le code mis à jour ne soitAllTrucks
également mis à jourBobsTruck
, il ne représentera plus l'état actuel du camion de Bob. Notez en outre que, sauf siBobsTruck
est stocké dans une forme d'objet mutable, le codeAllTrucks
pouvant être mis à jour pourrait être mis à jour uniquement si le code était explicitement programmé pour le faire.Si on veut pouvoir
BobsTruck
observer l'état du camion de Bob tout en maintenant tous les objets immuables, on pourrait avoirBobsTruck
une fonction immuable qui, étant donné la valeur quiAllTrucks
a eu ou a eu à un moment donné, donnera l'état du camion de Bob à ce temps. On pourrait même lui demander d’assumer deux fonctions immuables - l’une comme celle ci-dessus, et l’autre acceptant une référence à un état de flotte et un nouvel état de camion, et renvoyant une référence à un nouvel état de flotte correspondait à l'ancien, sauf que le camion de Bob aurait le nouvel état.Malheureusement, avoir à utiliser une telle fonction à chaque fois que l'on veut accéder à l'état du camion de Bob pourrait devenir assez ennuyeux et encombrant. Une autre approche serait de dire que l’objet n ° 24601 restera toujours et à jamais (tant que quelqu'un en fera référence) représente l’ état actuel du camion de Bob. Le code qui voudra accéder de manière répétée à l'état actuel du camion de Bob n'aura pas à exécuter une fonction fastidieuse à chaque fois - il pourrait simplement faire une fonction de recherche une fois pour découvrir que l'objet # 24601 est le camion de Bob, puis simplement accéder à cet objet à tout moment, il veut voir l'état actuel du camion de Bob.
Notez que l'approche fonctionnelle n'est pas sans avantages dans un environnement mono-thread, ou dans un environnement multi-thread où les threads ne feront qu'observer les données plutôt que de les modifier. Tout fil de l'observateur qui copie la référence de l'objet contenue dans
AllTrucks
et examine ensuite les états des camions représentés ainsi verront l’état de tous les camions à partir du moment où ils ont saisi la référence. Chaque fois qu'un thread observateur veut voir de nouvelles données, il peut simplement saisir à nouveau la référence. D'autre part, avoir l'ensemble de l'état de la flotte représenté par un seul objet immuable exclurait la possibilité que deux threads mettent à jour simultanément des camions différents, car chaque thread, laissé à lui-même, produirait un nouvel objet "state de la flotte", qui comprend: le nouvel état de son camion et les anciens états de tous les autres. L’exactitude peut être assurée si chaque thread utiliseCompareExchange
pour se mettre à jourAllTrucks
que s’il n’a pas changé et répond à un échec.CompareExchange
en régénérant son objet d'état et en renouvelant l'opération, mais si plusieurs threads tentent une opération d'écriture simultanée, les performances seront généralement moins bonnes que si toutes les écritures étaient effectuées sur un seul thread; plus les threads tentent de telles opérations simultanées, plus les performances seront mauvaises.Si des objets de camion individuels sont modifiables mais ont une identité immuable , le scénario multithread devient plus clair. Un seul fil peut être autorisé à fonctionner à la fois sur un camion donné, mais les fils fonctionnant sur des camions différents peuvent le faire sans interférence. Bien qu’il existe des moyens d’émuler un tel comportement, même lorsqu’on utilise des objets immuables (par exemple, on pourrait définir les objets "AllTrucks" de manière à ce que le réglage de l’état d’un camion appartenant à XXX à SSS nécessite simplement de générer un objet qui dit "À partir de [Heure], l'état du camion appartenant à [XXX] est maintenant [SSS]; l'état de tout le reste est [Ancienne valeur de AllTrucks] ". La génération d'un tel objet serait assez rapide pour que, même en cas de conflit, un
CompareExchange
la boucle ne prendrait pas longtemps. D'autre part, l'utilisation d'une telle structure de données augmenterait considérablement le temps requis pour trouver le camion d'une personne donnée. L'utilisation d'objets mutables d' identités immuables évite ce problème.la source
Il n'y a pas de bien ou de mal, cela dépend de ce que vous préférez. Il y a une raison pour laquelle certaines personnes préfèrent des langues qui privilégient un paradigme plutôt qu'un autre, et un modèle de données plutôt qu'un autre. Cela dépend de vos préférences et de ce que vous voulez réaliser (et être en mesure d'utiliser facilement les deux approches sans aliéner les fans inconditionnels d'un côté ou de l'autre est un saint graal que certaines langues recherchent).
Je pense que la meilleure et la plus rapide des réponses à votre question est de vous diriger vers les avantages et les inconvénients de l’immutabilité et de la mutabilité .
la source
Consultez cet article de blog: http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html . Il résume pourquoi les objets immuables sont meilleurs que mutables. Voici une courte liste d'arguments:
Les gens utilisent des objets mutables, autant que je sache, car ils mélangent toujours la POO avec une programmation procédurale impérative.
la source
En Java, les objets immuables nécessitent un constructeur qui prend toutes les propriétés de l'objet (ou le constructeur les crée à partir d'autres arguments ou valeurs par défaut). Ces propriétés doivent être marquées comme final .
Il y a quatre problèmes, principalement liés à la liaison de données :
Vous pouvez limiter les points 1 et 2 en utilisant des annotations telles
@ConstructorProperties
que la création d'un autre objet générateur modifiable (généralement couramment) pour créer l'objet immuable.la source
Je suis surpris que personne n'ait mentionné les avantages de l'optimisation des performances. Selon le langage utilisé, un compilateur peut procéder à de nombreuses optimisations lorsqu'il s'agit de données immuables, car il sait que les données ne changeront jamais. Toutes sortes de choses sont ignorées, ce qui vous donne d’énormes avantages en termes de performances.
De plus, les objets immuables éliminent presque toute la classe des bugs d'état.
Ce n'est pas aussi grand qu'il devrait l'être parce que c'est plus difficile, cela ne s'applique pas à toutes les langues et la plupart des gens ont appris le codage impératif.
De plus, j'ai constaté que la plupart des programmeurs sont heureux dans leur boîte et résistent souvent à de nouvelles idées qu'ils ne comprennent pas complètement. En général, les gens n'aiment pas le changement.
Rappelez-vous également que l'état de la plupart des programmeurs est mauvais. La plupart des programmes qui sont faits dans la nature sont terribles et sont causés par un manque de compréhension et de politique.
la source
Pourquoi les gens utilisent-ils une fonctionnalité puissante? Pourquoi les gens utilisent-ils la méta-programmation, la paresse ou le typage dynamique? La réponse est la commodité. L'état mutable est si facile. Il est si facile de mettre à jour sur place et le seuil de la taille du projet où l'état immuable est plus productif que l'état modable est assez élevé, de sorte que le choix ne vous fera pas souffrir pendant un certain temps.
la source
Les langages de programmation sont conçus pour être exécutés par des ordinateurs. Tous les blocs de construction importants des ordinateurs - CPU, RAM, cache, disques - sont mutables. Lorsqu'ils ne le sont pas (BIOS), ils sont vraiment immuables et vous ne pouvez pas non plus créer de nouveaux objets immuables.
Par conséquent, tout langage de programmation construit au-dessus d’objets immuables souffre d’un déficit de représentation dans son implémentation. Et pour les langues anciennes telles que le C, c'était une grosse pierre d'achoppement.
la source
Sans objets mutables, vous n'avez pas d'état. Certes, c'est une bonne chose si vous pouvez le gérer et s'il y a une chance qu'un objet puisse être référencé à partir de plusieurs threads. Mais le programme va être plutôt ennuyeux. De nombreux logiciels, en particulier les serveurs Web, évitent de prendre la responsabilité d'objets mutables en poussant la mutabilité sur des bases de données, des systèmes d'exploitation, des bibliothèques système, etc. En pratique, cela libère le programmeur des problèmes de mutabilité et rend Web (et autres) développement abordable. Mais la mutabilité est toujours là.
En général, vous avez trois types de classes: les classes normales, non fil-safe, qui doivent être soigneusement gardées et protégées; classes immuables, qui peuvent être utilisées librement; et des classes mutables, thread-safe qui peuvent être utilisées librement mais qui doivent être écrites avec un soin extrême. Le premier type est celui qui pose problème, les pires étant ceux que l’on pense être du troisième type. Bien sûr, les premiers types sont les plus faciles à écrire.
Je finis généralement avec beaucoup de classes normales et modifiables que je dois surveiller de très près. Dans une situation multi-thread, la synchronisation nécessaire ralentit tout, même lorsque je peux éviter une étreinte mortelle. Donc, je fais habituellement des copies immuables de la classe mutable et les remets à quiconque peut l’utiliser. Une nouvelle copie immuable est nécessaire chaque fois que l’origine change, alors j’imagine que j’ai parfois une centaine d’exemplaires de l’original. Je suis totalement dépendant de Garbage Collection.
En résumé, les objets modifiables, non thread-safe, conviennent si vous n'utilisez pas plusieurs threads. (Mais le multithreading est une injustice partout - soyez prudent!) Ils peuvent être utilisés en toute sécurité si vous les limitez à des variables locales ou si vous les synchronisez de manière rigoureuse. Si vous pouvez les éviter en utilisant le code éprouvé d'autres personnes (bases de données, appels système, etc.), faites-le. Si vous pouvez utiliser une classe immuable, faites-le. Et je pense qu'en général , les gens ne sont pas au courant des problèmes de multithreading ou sont (sensiblement) terrifiés par eux et utilisent toutes sortes de trucs pour éviter le multithreading (ou plutôt, en poussent la responsabilité ailleurs).
En tant que PS, je sens que les jetters et les setters Java deviennent incontrôlables. Regarde ça .
la source
Beaucoup de gens ont eu de bonnes réponses, je tiens donc à souligner un aspect très observateur et extrêmement vrai que vous avez évoqué et qui n'a pas été mentionné ailleurs.
La création automatique de setters et de getters est une idée horrible, mais c’est la première façon pour les gens soucieux de la procédure d’essayer de forcer OO dans leur état d’esprit. Les setters et les getters, ainsi que les propriétés ne devraient être créés que lorsque vous vous en rendrez compte et non pas par défaut
En fait, bien que vous ayez besoin de getters assez régulièrement, le seul moyen de créer des propriétés d’inscription ou d’écriture dans votre code consiste à utiliser un modèle de générateur qui les verrouille après l’instanciation complète de l’objet.
De nombreuses classes sont modifiables après la création, ce qui est correct. Les propriétés ne doivent pas être manipulées directement. Vous devez plutôt lui demander de manipuler ses propriétés via des appels de méthodes contenant une logique métier réelle (oui, un opérateur est à peu près le même chose comme manipulant directement la propriété)
Maintenant, cela ne s'applique pas vraiment non plus aux codes / langages de style "Scripting", mais au code que vous créez pour quelqu'un d'autre et attendez des autres qu'ils lisent de manière répétée au fil des ans. J'ai dû faire cette distinction récemment parce que j'aime beaucoup jouer avec Groovy et qu'il y a une énorme différence entre les objectifs.
la source
Les objets mutables sont utilisés lorsque vous devez définir des valeurs multiples après l'instanciation de l'objet.
Vous ne devriez pas avoir de constructeur avec, par exemple, six paramètres. Au lieu de cela, vous modifiez l'objet avec les méthodes setter.
Un exemple de ceci est un objet Report, avec des setters pour la police, l'orientation, etc.
En bref: les mutables sont utiles lorsque vous avez beaucoup d’états à définir sur un objet et qu’il ne serait pas pratique d’avoir une signature de constructeur très longue.
EDIT: un modèle de générateur peut être utilisé pour construire l’état complet de l’objet.
la source
new ReportBuilder().font("Arial").orientation("landscape").build()
withFont
retourne unReport
.Je pense que l'utilisation d'objets mutables découle de la pensée impérative: vous calculez un résultat en modifiant pas à pas le contenu des variables mutables (calcul par effet secondaire).
Si vous pensez fonctionnellement, vous voulez avoir un état immuable et représenter les états suivants d'un système en appliquant des fonctions et en créant de nouvelles valeurs à partir d'anciennes.
L'approche fonctionnelle peut être plus propre et plus robuste, mais elle peut s'avérer très inefficace en raison de la copie, de sorte que vous souhaitez revenir à une structure de données partagée que vous modifiez de manière incrémentielle.
Le compromis que je trouve le plus raisonnable est le suivant: commencez par les objets immuables puis passez aux objets mutables si votre mise en œuvre n'est pas assez rapide. De ce point de vue, utiliser systématiquement des objets mutables dès le début peut être considéré comme une optimisation prématurée : vous choisissez dès le départ la mise en œuvre la plus efficace (mais aussi plus difficile à comprendre et à mettre au point).
Alors, pourquoi beaucoup de programmeurs utilisent-ils des objets mutables? IMHO pour deux raisons:
la source
Je sais que vous parlez de Java, mais j’utilise tout le temps mutable vs immuable dans objective-c. Il existe un tableau immuable NSArray et un tableau mutable NSMutableArray. Ce sont deux classes différentes écrites spécifiquement de manière optimisée pour gérer l'utilisation exacte. Si j'ai besoin de créer un tableau et de ne jamais en modifier le contenu, j'utiliserais NSArray, un objet plus petit et beaucoup plus rapide, comparé à un tableau mutable.
Ainsi, si vous créez un objet Person immuable, vous avez uniquement besoin d'un constructeur et de getters. L'objet sera donc plus petit et utilise moins de mémoire, ce qui accélérera votre programme. Si vous devez modifier l'objet après la création, un objet Personne mutable sera préférable afin de pouvoir modifier les valeurs au lieu de créer un nouvel objet.
Donc, selon ce que vous envisagez de faire avec l'objet, choisir mutable ou immuable peut faire une énorme différence en termes de performances.
la source
Outre de nombreuses autres raisons données ici, un problème est que les langues grand public ne supportent pas bien l'immutabilité. Au moins, vous êtes pénalisé pour immuabilité dans la mesure où vous devez ajouter des mots-clés supplémentaires, tels que const ou final, et devez utiliser des constructeurs illisibles avec de très nombreux arguments ou des modèles de constructeur trop longs.
C'est beaucoup plus facile dans les langues créées avec immuabilité. Considérez cet extrait de code Scala pour définir une classe Person, éventuellement avec des arguments nommés, et créer une copie avec un attribut modifié:
Si vous voulez que les développeurs adoptent l’immuabilité, c’est l’une des raisons pour lesquelles vous pourriez envisager de passer à un langage de programmation plus moderne.
la source
Immuable signifie que vous ne pouvez pas changer la valeur et mutable signifie que vous pouvez changer la valeur si vous pensez en termes de primitives et d'objets. Les objets diffèrent des primitives en Java en ce qu'ils sont de types intégrés. Les primitives sont des types intégrés tels que int, boolean et void.
Beaucoup de gens pensent que les variables primitives et objets qui ont un modificateur final en face d'eux sont immuables, cependant, ce n'est pas tout à fait vrai. Donc, final ne signifie presque pas immuable pour les variables. Consultez ce lien pour un exemple de code:
la source
Je pense qu'une bonne raison serait de modéliser des "objets" mutables "réels", comme des fenêtres d'interface. Je me souviens vaguement d'avoir lu que la POO avait été inventée lorsque quelqu'un avait essayé d'écrire un logiciel pour contrôler certaines opérations portuaires.
la source
Java, dans de nombreux cas, requiert des objets mutables, par exemple lorsque vous voulez compter ou renvoyer quelque chose dans un visiteur ou un exécutable, vous avez besoin de variables finales, même sans multithreading.
la source
final
est en fait environ un quart d'un pas vers l' immutabilité. Ne pas voir pourquoi vous en parlez.final
. Le situer dans ce contexte évoque une confusion vraiment étrangefinal
entre «mutable», alors que le but mêmefinal
est de prévenir certains types de mutation. (BTW, pas mon downvote.)