Pourquoi la classe String est immuable et finale en Java - 5 raisons

Share:
Java String Immutable final
Il n'y a pratiquement aucune entretien Java, où une question à propos des Strings n'est posée. Pourquoi String est immuable en Java, est la plus populaire.  Cette question est également posée sous la forme "Pourquoi la classe String est rendue finale en Java ?" ou simplement, "Pourquoi String est finale ?".
Afin de répondre à ces questions, le programmeur Java doit avoir une solide compréhension sur comment la classe String fonctionne, quelles sont les caractéristiques spéciales de cette classe et certains principes fondamentaux.

La classe String est une classe God en Java, elle a des caractéristiques spéciales qui ne sont pas disponibles pour d'autres classes. Par exemple : les littéraux de chaîne sont stockés dans des pools. et vous pouvez concaténer des chaînes à l'aide de l'opérateur +.
Compte tenu de son importance dans la programmation Java, les concepteurs Java l'ont rendu "final", ce qui signifie que vous ne pouvez pas étendre la classe java.lang.String, cela aide aussi à rendre l'objet String Immutable.

Maintenant, revenant à notre question, pourquoi String est immuable en Java? Bien sûr, cela devrait être lié aux avantages et aux gains. Maintenant, réfléchissons à ce que sont ces avantages ou caractéristiques, ce qui motive cette décision. Je ne sais pas s'il existe déjà un document officiel d'Oracle ou de Sun, qui peut éclairer cette décision.

Bien que je me rappelle avoir lu quelque part, une question demandée à James Gosling, créateur de Java, à propos du choix "final" de la classe String. Il a dit quelque chose à propos de la sécurité. Il a été soutenu que rendre la classe "final" limite sérieusement sa capacité à évoluer ou à s'étendre et James a mentionné que les classes qui sont essentielles à l'utilisation de Java sont définitives, afin que personne ne puisse changer de comportement avec Java.

5 raisons pourquoi String est final ou Immutable en Java

Bien que les vraies raisons que la classe String est finale soient connues des concepteurs Java, et à part cet indice sur la sécurité de James Gosling, je pense que les raisons suivantes suggèrent aussi pourquoi String est finale ou immuable en Java.

1) String Pool
Les concepteurs Java savent que String va être le type de données le plus utilisé dans tous les types d'applications Java et c'est pourquoi ils voulaient l'optimiser dès le départ. L'une des étapes clés dans cette direction était l'idée de stocker des littéraux de chaînes dans le pool String. L'objectif était de réduire les objets String temporairement en les partageant. Et afin de les partager, ils doivent être issus de la classe Immutable. Vous ne pouvez pas partager un objet mutable avec deux parties qui sont inconnues l'une de l'autre. Prenons un exemple hypothétique, où deux variables de référence pointent vers le même objet String:

String s1 = "Java";
String s2 = "Java";
Maintenant si s1 change l'objet de "Java" en "C ++", la variable de référence a aussi la valeur s2 = "C ++", qu'elle ne connaît même pas. En rendant String immutable, ce partage de chaîne littérale était possible. En bref, l'idée clé du String Pool ne peut pas être implémentée sans faire de String final ou Immutable dans Java.


2) Sécurité
Java a un objectif clair en termes de fourniture d'un environnement sécurisé à tous les niveaux de service et String est essentielle dans tous ces aspects de la sécurité. La chaîne a été largement utilisée comme paramètre pour de nombreuses classes Java, par ex. pour ouvrir la connexion réseau, vous pouvez passer l'hôte et le port en tant que chaîne, pour lire les fichiers en Java, passer le chemin des fichiers et le répertoire en tant que chaîne et pour ouvrir la connexion à la base de données. Si String n'était pas immuable, un utilisateur peut avoir accordé l'accès à un fichier particulier dans le système, mais après l'authentification, il peut changer le PATH en quelque chose d'autre, ce qui pourrait causer de graves problèmes de sécurité. De même, lors de la connexion à la base de données ou à toute autre machine du réseau, la valeur String en mutation peut poser des menaces de sécurité. Les chaînes mutables peuvent également provoquer des problèmes de sécurité dans la "Reflection", car les paramètres sont des chaînes.

3) Utilisation de String dans le mécanisme de chargement de classe
Une autre raison de faire du String final ou Immutable était due au fait qu'il était fortement utilisé dans le mécanisme de chargement de classe. Comme String n'est pas immuable, un attaquant peut tirer parti de ce fait et d'une requête pour charger des classes Java standard, par ex. java.io.Reader peut être remplacé par une classe malveillante com.unknown.DataStolenReader. En conservant String final et immuable, nous pouvons au moins être sûrs que la JVM charge les classes correctes.

4) Avantages du Multithreading
La concurrence et le multithread étant l'offre clé de Java, il était logique de penser à la sécurité des threads. Comme on s'attendait à ce que String soit largement utilisé, le rendre immuable signifie pas de synchronisation externe, ce qui signifie beaucoup plus de code propre impliquant le partage de String entre plusieurs threads. Cette caractéristique unique rend beaucoup plus facile le codage des accès concurrents, compliqué, prêtant à confusion et prêtant à l'erreur. Parce que String est immuable et que nous le partageons simplement entre les threads, il en résulte un code plus lisible.

5) Optimisation et performance
Maintenant, quand vous faites d'une classe immuable, vous savez d'avance que cette classe ne va pas changer une fois créée. Ceci garantit un chemin ouvert pour de nombreuses optimisations de performance, par ex. mise en cache du String elle-même, alors String cache son hashcode. Elle calcule même le hashcode paresseusement une fois créé, il suffit de le mettre en cache. Dans un monde idéal, lorsque vous appelez d'abord la méthode hashCode () de n'importe quel objet String, il calcule le code de hachage et tous les appels suivants à hashCode () retournent la valeur déjà calculée et mise en cache. Cela entraîne un gain de performance, étant donné que String est fortement utilisé dans les Maps basées sur le hachage, par ex. Hashtable et HashMap. La mise en cache de hashcode n'était pas possible sans la rendre immuable et définitive, car elle dépend du contenu de String elle-même.

Avantages et inconvénients de la classe String étant immutable ou finale en Java
Mis à part les avantages ci-dessus, il y a un autre avantage que vous pouvez compter en raison de la classe String étant finale en Java. C'est l'un des objets les plus populaires à utiliser comme clé dans les collections basées sur le hachage, par ex. HashMap et Hashtable. Bien que l'immutabilité ne soit pas une exigence absolue pour les clés HashMap, il est beaucoup plus sûr d'utiliser un objet Immutable comme clé qu'un autre objet mutable, car si l'état de l'objet mutable change pendant son utilisation dans HashMap, il est impossible de le récupérer. La méthode equals () et hashCode () dépendent de l'attribut changé. Si une classe est immuable, il n'y a aucun risque de changer son état, quand elle est stockée dans des collections basées sur le hachage. Un autre avantage significatif que j'ai déjà souligné est sa sécurité. Comme String est immuable, vous pouvez la partager en toute sécurité entre les threads sans vous soucier de la synchronisation externe. Cela rend le code concurrent plus lisible et moins sujette aux erreurs.

Malgré tous ces avantages, l'immuabilité présente également certains inconvénients, par ex. ça ne vient pas sans coût. Puisque String est immuable, elle génère beaucoup d'utilisation temporaire et généré un objet, ce qui crée une pression pour le Garbage Collector. Les concepteurs Java y ont déjà pensé et le stockage des littéraux String dans le pool est leur solution pour réduire la duplication des chaînes. Cela aide, mais vous devez faire attention à créer une chaîne sans utiliser de constructeur, par ex. new String () ne sélectionne pas d'objet dans le pool de chaînes. Aussi, en moyenne, l'application Java génère trop de "déchets". Le stockage des chaînes dans le pool comporte également un risque caché. Le pool de String est situé dans l'espace PermGen de Java Heap, qui est très limité par rapport à Java Heap. Avoir trop de chaînes littérales remplira rapidement cet espace, ce qui entraînera java.lang.OutOfMemoryError: PermGen Space. Heureusement, les programmeurs de langage Java ont identifié ce problème et à partir de Java 7, ils ont déplacé String pool vers l'espace de Heap normal, qui est beaucoup plus grand que l'espace PermGen. Il y a un autre inconvénient à faire une chaîne finale, c'est qu'on limite son extensibilité. Maintenant, vous ne pouvez pas étendre String pour fournir plus de fonctionnalités, bien que les cas plus généraux soient à peine nécessaires, toujours sa limitation pour ceux qui veulent étendre la classe java.lang.String.

Ces 5 raisons donnent certainement un indice sur le fait que la classe String a été rendue Final et Immutable dans Java. Bien sûr, c'est la décision des concepteurs Java. Pour des raisons similaires, les classes wrapper comme Integer, Long, Double et Float sont également immuables et finales

Post a Comment

Aucun commentaire