Pourquoi la chaîne est-elle immuable en Java?

on m'a demandé dans une interview pourquoi la chaîne est immuable

j'ai répondu comme ceci:

quand on crée une chaîne en java comme String s1="hello"; puis une objet sera créé dans chaîne de piscine(bonjour) et s1 sera pointant vers bonjour .Maintenant, si nous faisons à nouveau String s2="hello"; alors un autre objet ne sera pas créé mais S2 point hello parce que JVM vérifiera d'abord si le même objet est présent dans chaîne de piscine ou pas.Si pas présent alors qu'un nouveau est créé d'autre pas.

maintenant si supposons que java autorise la chaîne de caractères modifiable alors si nous changeons s1 en hello world alors s2 la valeur sera aussi hello world donc la chaîne de caractères java est immuable.

Can n'importe qui s'il Vous Plaît me dire si ma réponse est bon ou mauvais ?

135
demandé sur rocking 2014-03-14 10:38:17

13 réponses

String est immuable pour plusieurs raisons, voici un résumé:

  • Security : les paramètres sont typiquement représentés par String dans les connexions réseau, les URL de connexion de base de données, les noms d'utilisateurs/mots de passe, etc. S'il était mutable, ces paramètres pourraient facilement être changés.
  • synchronisation et simultanéité: rendre la chaîne immuable les rend automatiquement thread sûr de résoudre ainsi les problèmes de synchronisation.
  • Caching : lorsque le compilateur optimise vos objets String, il voit que si deux objets ont la même valeur (a="test", et b= "test"), vous n'avez besoin que d'un seul objet string (pour a et b, ces deux objets pointent vers le même objet).
  • chargement par Classe : String est utilisé comme argument pour le chargement par classe. Si mutable, il pourrait en résulter une mauvaise classe être chargé (parce que les objets mutables changent d'état).

cela dit, l'immuabilité de String signifie seulement que vous ne pouvez pas la changer en utilisant son API publique. Vous pouvez en fait contourner l'API normale en utilisant la réflexion. Voir la réponse ici .

dans votre exemple, si String était mutable, alors considérez l'exemple suivant:

  String a="stack";
  System.out.println(a);//prints stack
  a.setValue("overflow");
  System.out.println(a);//if mutable it would print overflow
129
répondu Community 2017-05-23 11:54:50

Développeurs Java décider Chaînes sont immuables en raison de l'aspect suivant de la conception, de l'efficacité et de la sécurité .

Design Les chaînes sont créées dans une zone de mémoire spéciale en Java heap connu sous le nom de "String Intern pool". Pendant que vous créez une nouvelle chaîne (pas dans le cas d'utiliser le constructeur String() ou toute autre fonction String qui utilise en interne le constructeur String() pour créer un nouvel objet String; String() le constructeur crée toujours une nouvelle constante de chaîne dans le pool à moins que nous appelions la méthode intern() ) variable il cherche dans le pool pour vérifier si elle existe déjà. Si c'est exister, ensuite de retour à la référence de la Chaîne existante de l'objet. Si la chaîne n'est pas immuable, changer la chaîne avec une référence conduira à la mauvaise valeur pour les autres références.

selon cet article sur DZone:

Sécurité La chaîne de caractères est largement utilisée comme paramètre pour de nombreuses classes java, par exemple la connexion réseau, l'ouverture de fichiers, etc. Si String n'était pas immuable, une connexion ou un fichier serait modifié et conduirait à une menace sérieuse de sécurité. Les chaînes mutables pourraient aussi causer des problèmes de sécurité dans la réflexion, car les paramètres sont des chaînes.

efficacité Le hashcode de string est fréquemment utilisé en Java. Pour exemple, dans une table de hachage. Être immuable garantit que le hashcode sera toujours le même, pour qu'il puisse être mis en cache sans inquiéter les changements.Cela signifie, il n'est pas nécessaire de calculer hashcode à chaque fois qu'il est utilisé.

37
répondu Alex Mathew 2017-11-05 16:27:14

nous ne pouvons pas être sûrs de ce que les concepteurs Java pensaient réellement tout en concevant String mais nous ne pouvons que conclure ces raisons basées sur les avantages que nous obtenons de chaîne immutabilité, dont certains sont

1. Existence D'un Pool de cordes Constant

comme discuté dans" 151932092020 "pourquoi la chaîne est stockée dans la piscine constante de la chaîne article, chaque application crée trop d'objets de chaîne et afin de sauver JVM de d'abord en créant des tas d'objets de ficelle, puis en les ramassant. JVM stocke tous les objets string dans une zone de mémoire séparée appelée string constant pool et réutilise les objets de cette zone.

chaque fois que nous créons une chaîne de caractères littéral JVM voit pour la première fois si ce littéral est déjà présent dans constant pool ou pas et s'il est là, une nouvelle référence commencera à pointer vers le même objet dans SCP.

String a = "Naresh";
String b = "Naresh";
String c = "Naresh";

dans l'exemple ci-dessus la valeur Naresh sera créée dans SCP une seule fois et toute référence a , b , c va pointer vers le même objet mais que faire si nous essayons de faire un changement dans a par exemple a.replace("a", "") .

idéalement, a devrait avoir la valeur Nresh mais b , c devrait rester inchangé parce qu'en tant qu'utilisateur final, nous faisons le changement dans a seulement. Et nous savons a , b , c tous sont pointer le même objet donc si nous faisons un changement dans a , d'autres devraient également refléter le changement.

mais l'immutabilité de la chaîne nous sauve de ce scénario et en raison de l'immuabilité de la chaîne objet chaîne objet Naresh ne changera jamais. Ainsi, lorsque nous effectuons un changement dans a au lieu d'un changement dans l'objet string Naresh , JVM crée un nouvel objet qui l'affecte à a et le modifie ensuite dans cet objet.

Afin De Chaîne le pool n'est possible qu'en raison de L'immuabilité de String et si String n'aurait pas été immuable, alors cacher des objets string et les réutiliser n'aurait pas de possibilité car n'importe quelle variable aurait changé la valeur et corrompu les autres.

et c'est pourquoi il est manipulé par JVM très spécialement et a été donné une zone de mémoire spéciale.

2. Sécurité Des Fils

un objet est appelé thread-safe lorsque plusieurs threads fonctionnent sur elle, mais aucun d'eux n'est en mesure de corrompre son état et l'objet tiennent le même état pour chaque fil à tout moment dans le temps.

comme nous un objet immuable ne peut pas être modifié par quiconque après sa création qui rend chaque objet immuable est fil sécurisé par défaut. Nous n'avons pas besoin d'y appliquer des mesures de sécurité telles que la création de méthodes synchronisées.

ainsi en raison de sa nature immuable chaîne objet peut être partagé par plusieurs fils et même si elle est la manipulation par de nombreux fils, il ne changera pas sa valeur.

3. Sécurité

dans chaque application, nous avons besoin de passer plusieurs secrets par exemple Nom d'utilisateur\mots de passe, URLs de connexion et en général, toutes ces informations sont passées comme l'objet de chaîne de caractères.

supposons maintenant que la chaîne de caractères n'aurait pas été immuable de nature immuable, elle constituerait une menace sérieuse pour la sécurité de la demande. parce que ces valeurs sont autorisées à être changées et si elles sont autorisées alors elles peuvent être changées en raison du code mal écrit ou de toute autre personne qui ont accès à nos références variables.

4. Classe De Chargement

comme expliqué dans créer des objets par réflexion en Java avec L'exemple , nous pouvons utiliser la méthode Class.forName("class_name") pour charger une classe en mémoire qui appelle encore d'autres méthodes pour le faire. Et même JVM utilise ces méthodes de chargement des classes.

mais si vous voyez clairement toutes ces méthodes accepte le nom de classe comme un objet de chaîne de sorte que les chaînes sont utilisées dans le chargement de classe java et immutabilité fournit la sécurité que la classe correcte se charge par ClassLoader .

supposons que la chaîne de caractères n'aurait pas été immuable et nous essayons de charger java.lang.Object qui sera changé en org.theft.OurObject entre-temps et maintenant tous nos objets ont un comportement que quelqu'un peut utiliser pour des choses indésirables.

5. HashCode De La Mise En Cache

si nous voulons effectuer des opérations de hachage sur n'importe quel objet, nous devons outrepasser la méthode hashCode() et essayer de générer un hashcode précis en utilisant l'état de l'objet. Si l'état de l'objet est modifié ce qui signifie que son hashcode devrait aussi changer.

parce que la chaîne de caractères est immuable de sorte que la valeur qu'un objet string contient ne sera jamais changée ce qui signifie que son hashcode ne changera pas non plus, ce qui donne à la classe String la possibilité de mettre en cache son hashcode lors de la création de l'objet.

Oui, L'objet String cache son hashcode au moment de la création de l'objet ce qui en fait le grand candidat pour les opérations liées au hashCode parce que le hashcode n'a pas besoin d'être calculé à nouveau ce qui nous fait gagner du temps. C'est pourquoi String est principalement utilisé comme HashMap clés.

plus d'informations sur pourquoi La chaîne est immuable et finale en Java .

7
répondu Naresh Joshi 2018-02-19 17:24:07

j'ai lu ce post pourquoi chaîne est immuable ou finale en Java et supposons que la raison suivante peut être la plus importante:

String est immuable en Java parce que les objets String sont mis en cache Chaîne de piscine . Étant donné que les chaînes de caractères en cache sont partagées entre plusieurs clients il y a toujours un risque, où l'action d'un client affecterait tous les autres clients.

4
répondu ThoQ 2016-01-14 03:14:12

vous avez raison. String en java utilise le concept de String Pool littéral. Quand une chaîne est créée et si la chaîne existe déjà dans le pool, La référence de la chaîne existante sera retournée, au lieu de créer un nouvel objet et de retourner sa référence.Si une chaîne n'est pas immuable, changer la chaîne avec une référence conduira à la mauvaise valeur pour les autres références.

j'ajouterais encore une chose, puisque String est immuable, il est sûr pour multi threading et une seule instance de chaîne peut être partagée entre différents threads. Cela évite l'utilisation de la synchronisation pour la sécurité du thread, les chaînes sont implicitement thread safe .

1
répondu Akshay Gupta 2017-01-28 15:12:36

chaîne est immuable parce que: -

1. : - Chaîne de piscine, est possible seulement parce que la Chaîne est immuable en java, cette façon de Java Runtime permet d'économiser beaucoup de java heap space parce que les différentes variables de Chaîne de caractères peut se référer à la même variable de Chaîne dans la piscine. Si String n'aurait pas été immuable, alors l'interning de String n'aurait pas été possible parce que si une variable avait changé la valeur, elle aurait été réfléchie à une autre les variables également.

2. Sécurité:- Si la Chaîne n'est pas immuable, alors il serait causer une grave menace pour la sécurité de l'application. Par exemple, le nom d'utilisateur de la base de données, le mot de passe sont passés comme chaîne de caractères pour obtenir la connexion de la base de données et dans la programmation de socket les détails de l'hôte et du port passés comme chaîne de caractères. Puisque String est immuable, sa valeur ne peut pas être changée, sinon n'importe quel hacker pourrait changer la valeur référencée pour causer des problèmes de sécurité dans l'application.

3. Thread-Safe:- Depuis le String est immuable, il est sans danger pour le multithreading et une seule instance de Chaîne peuvent être partagés entre les différents threads. Cela évite l'utilisation de la synchronisation pour la sécurité du thread, les chaînes sont implicitement thread safe

4. classloader: - les chaînes sont utilisées dans java classloader et l'immutabilité fournit la sécurité que la classe correcte est chargée par Classloader. Par exemple, pensez à un cas où vous essayez de charger java.SQL.Classe de connexion mais la valeur référencée est changée en myhacked.Classe de connexion qui peut faire des choses indésirables à votre base de données.

5. "151930920 la mise en Cache": - Depuis le String est immuable, son hashcode est mis en cache au moment de la création, et il n'a pas besoin d'être calculé à nouveau. Cela en fait un excellent candidat pour la clé dans une carte et son traitement est rapide que les autres objets de clé HashMap. C'est pourquoi la Chaîne est principalement objet utilisé comme clé HashMap. Ci-dessus sont quelques-unes des raisons que je pourrais penser qui montre les avantages de la chaîne immutabilité. C'est une grande caractéristique de la classe Java String et la rend spéciale.

1
répondu Neeraj Gahlawat 2017-11-22 12:43:15

classe String est FINAL cela signifie que vous ne pouvez pas créer une classe pour hériter et de changer la structure de base et de rendre le dard mutable.

autre chose la variable d'instance et les méthodes de la classe String qui sont fournies sont telles que vous ne pouvez pas changer l'objet String une fois créé.

la raison pour laquelle ce que vous avez ajouté ne rend pas la chaîne immuable du tout.Tout cela dit comment la corde est stockée dans le tas.Aussi string pool faire le énorme différence dans la performance

0
répondu Kick 2014-03-14 06:51:51

chaîne est donnée comme immuable par Sun micro systems, parce que chaîne peut utilisé pour stocker comme clé dans la collection de carte. StringBuffer est mutable .C'est la raison pour laquelle il ne peut pas être utilisé comme clé dans l'objet map

0
répondu chaithanya krishna gogineni 2017-06-23 02:46:12

la raison la plus importante pour qu'une chaîne soit rendue immuable en Java est Security consideration. Le suivant serait Caching .

je crois que d'autres raisons données ici, telles que l'efficacité, la concurrence, la conception et string pool découle du fait que la chaîne de fait immuable. Pour eg. String Pool pouvait être créé parce que String était immuable et pas l'inverse.

Vérifier Gosling interview transcription ici

d'un point de vue stratégique, ils ont tendance à ne pas avoir de problèmes. Et il y a habituellement des choses que vous pouvez faire avec des immuables que vous ne pouvez pas faire avec des choses mutables, Comme cacher le résultat. Si vous passez une chaîne de caractères dans un fichier ouvert, ou si vous passez une chaîne à un constructeur pour une étiquette dans une interface utilisateur, dans certaines Api (comme dans beaucoup de l'Api Windows) vous passez un tableau de caractères. Le destinataire de cet objet doit vraiment le copier, parce qu'ils ne savent rien de sa durée de conservation. Et ils ne savent pas ce qui arrive à l'objet, s'il est changé sous leurs pieds.

vous finissez par être presque forcé de répliquer l'objet parce que vous ne savez pas si vous obtenez ou non de posséder. Et ce qui est bien avec les objets immuables, c'est que la réponse est: "oui, bien sûr."Parce que le la question de la propriété, qui a le droit de changer, n'existe pas.

la sécurité était l'une des choses qui obligeait les cordes à être immuables. Vous avez une méthode d'ouverture de fichier. Vous passez une Chaîne de caractères. Et puis il fait toutes sortes de vérifications d'authentification avant de faire l'appel OS. Si vous parvenez à faire quelque chose qui a effectivement muté la chaîne, après le contrôle de sécurité et avant L'appel OS, puis boom, vous êtes dedans. Mais les Chaînes sont immuables, alors ce genre de l'attaque ne fonctionne pas. Cet exemple précis est ce qui a vraiment exigé que Strings be immuable

0
répondu Sameer Sinha 2017-11-05 12:48:54

outre les excellentes réponses, je voulais ajouter quelques points. Comme les chaînes, le tableau tient une référence au démarrage du tableau donc si vous créez deux tableaux arr1 et arr2 et avez fait quelque chose comme arr2 = arr1 cela fera la référence de arr2 même que arr1 donc changer la valeur dans l'un d'eux résultera en changement de l'autre par exemple

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4};
        int[] b = a;
        a[0] = 8;
        b[1] = 7;
        System.out.println("A: " + a[0] + ", B: " + b[0]);
        System.out.println("A: " + a[1] + ", B: " + b[1]);
        //outputs
        //A: 8, B: 8
        //A: 7, B: 7
    }
}

non seulement qu'il causerait des bugs dans le code, il aussi peut (et sera) exploitée par un utilisateur malveillant. Supposons que vous ayez un système qui change le mot de passe administrateur. L'utilisateur doit d'abord entrer le newPassword et ensuite le oldPassword si le oldPassword est le même que le adminPass le programme change le mot de passe par adminPass = newPassword . disons que le nouveau mot de passe a la même référence que le mot de passe administrateur donc un mauvais programmeur peut créer une variable temp pour tenir le mot de passe administrateur avant que l'utilisateur n'entre les données si le oldPassword est égal à temp il change le mot de passe sinon adminPass = temp . Quelqu'un sachant que pourrait facilement entrer le nouveau mot de passe et ne jamais entrer l'ancien mot de passe et abracadabra il a accès administrateur. Une autre chose que je n'ai pas compris en apprenant sur les chaînes de caractères pourquoi JVM ne crée pas une nouvelle chaîne pour chaque objet et avoir un endroit unique en mémoire pour elle et vous pouvez juste faire cela en utilisant new String("str"); la raison pour laquelle vous ne voudriez pas toujours utiliser new est parce que ce n'est pas efficace de mémoire et il est plus lent dans la plupart des cas lire la suite .

0
répondu Ãly Hâñý 2018-06-05 01:38:17

si HELLO est votre chaîne, alors vous ne pouvez pas changer HELLO en HILLO . Cette propriété est appelée propriété immutabilité.

vous pouvez avoir plusieurs variables de chaîne de pointage pour pointer la chaîne HELLO.

mais si HELLO est Char Array alors vous pouvez changer HELLO en HILLO. Par exemple,

char[] charArr = 'HELLO';
char[1] = 'I'; //you can do this

réponse:

les langages de programmation ont des variables de données immuables de sorte qu'il peut être utilisé comme clé dans la clé, valeur paire. les variables String sont utilisées comme clés/indices, de sorte qu'elles sont immuables .

0
répondu Uddhav Gautam 2018-07-20 20:55:42

du point de vue Security nous pouvons utiliser cet exemple pratique:

DBCursor makeConnection(String IP,String PORT,String USER,String PASS,String TABLE) {

    // if strings were mutable IP,PORT,USER,PASS can be changed by validate function
    Boolean validated = validate(IP,PORT,USER,PASS);

    // here we are not sure if IP, PORT, USER, PASS changed or not ??
    if (validated) {
         DBConnection conn = doConnection(IP,PORT,USER,PASS);
    }

    // rest of the code goes here ....
}
-1
répondu darxtrix 2017-10-12 06:20:09