On m'a demandé dans une interview pourquoi String est immuable
J'ai répondu comme ceci:
Lorsque nous créons une chaîne en java comme
String s1="hello";
alors un objet sera créé dans la piscine de chaîne (bonjour) et s1 pointera à bonjour .Maintenant si encore une fois nous neString s2="hello";
puis un autre objet ne sera pas créé , mais s2 pointera vershello
parce que JVM va d' abord vérifier si le même objet est présent dans le pool de chaînes ou non. S'il n'est pas présent, seul un nouvel objet est créé sinon pas.
Maintenant , si java permet chaîne mutable suppose alors si nous changeons s1 à hello world
alors s2 valeur sera également hello world
si java chaîne est immuable.
Quelqu'un peut-il me dire si ma réponse est bonne ou mauvaise ?
std::string
est modifiable, mais ils ont également un pool de chaînes (enfin, plus correctement, un pool de tableaux de caractères).Réponses:
String
est immuable pour plusieurs raisons, voici un résumé:String
dans les connexions réseau, les URL de connexion à la base de données, les noms d'utilisateur / mots de passe, etc. S'il était modifiable, ces paramètres pourraient être facilement modifiés.String
est utilisé comme arguments pour le chargement de classe. Si mutable, cela peut entraîner le chargement d'une classe incorrecte (car les objets mutables changent d'état).Cela étant dit, l'immuabilité de
String
signifie uniquement que vous ne pouvez pas la modifier à l'aide de 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, considérez l'exemple suivant:la source
String
est mutable, alors le chargeur de classe prendrait la chaîne passée, ferait une copie et ne changerait pas sa copie. Lorsque vous pensez à un problème avec les mutablesjava.lang.String
, pensez à la façon dont C ++ résout ce problème (car il a des mutablesstd::string
.Les développeurs Java décident que les chaînes sont immuables en raison des aspects suivants: conception, efficacité et sécurité .
Les chaînes de conception sont créées dans une zone de mémoire spéciale du tas Java appelée «pool de chaînes internes». Pendant que vous créez un nouveau String (pas dans le cas de l'utilisation du constructeur String () ou de toute autre fonction String qui utilise en interne le constructeur String () pour créer un nouvel objet String; le constructeur String () crée toujours une nouvelle constante de chaîne dans le pool, sauf si nous appelez la variable méthode intern () ), il recherche le pool pour vérifier s'il existe déjà. S'il existe, renvoie la référence de l'objet String existant. Si la chaîne n'est pas immuable, la modification de la chaîne avec une référence entraînera une valeur incorrecte pour les autres références.
Selon cet article sur DZone:
la source
Nous ne pouvons pas être sûrs de ce que pensaient réellement les concepteurs Java lors de la conception,
String
mais nous ne pouvons conclure ces raisons que sur la base des avantages que nous retirons de l'immuabilité des chaînes, dont certains sont1. Existence d'un pool de constantes de chaîne
Comme indiqué dans l'article Pourquoi la chaîne est stockée dans le pool de constantes de chaîne , chaque application crée trop d'objets chaîne et afin d'éviter que la JVM ne crée d'abord beaucoup d'objets chaîne, puis les récupère. La JVM stocke tous les objets chaîne dans une zone de mémoire distincte appelée pool de constantes String et réutilise les objets de ce pool mis en cache.
Chaque fois que nous créons un littéral de chaîne, la JVM voit d'abord si ce littéral est déjà présent dans le pool constant ou non et s'il y est, une nouvelle référence commencera à pointer vers le même objet dans SCP.
Dans exemple ci - dessus objet chaîne avec la valeur
Naresh
sera créée en se SCP qu'une seule fois et toute référencea
,b
,c
pointera vers le même objet , mais si nous essayons de faire des changements dansa
par exemplea.replace("a", "")
.Idéalement
a
devrait avoir une valeurNresh
maisb
,c
devrait rester inchangé car en tant qu'utilisateur final , nous faisons le changementa
seulement. Et nous savonsa
,b
,c
tous pointent le même objet , donc si nous faisons un changementa
, d' autres devraient également refléter le changement.Mais l'immuabilité des chaînes nous sauve de ce scénario et en raison de l'immuabilité de l'objet string, l'objet string
Naresh
ne changera jamais. Ainsi, lorsque nous apportons une modification aua
lieu d'une modification dans l'objet chaîne, laNaresh
JVM crée un nouvel objet, assignez-lea
, puis modifiez cet objet.Ainsi, le pool de chaînes n'est possible qu'en raison de l'immuabilité de String et si String n'aurait pas été immuable, la mise en cache des objets de chaîne et leur réutilisation n'aurait aucune possibilité car toute variable aurait changé la valeur et corrompu les autres.
Et c'est pourquoi il est géré par JVM très spécialement et dispose d'une zone mémoire spéciale.
2. Sécurité du fil
Un objet est appelé thread-safe lorsque plusieurs threads y opèrent, mais qu'aucun d'entre eux n'est capable de corrompre son état et que l'objet conserve le même état pour chaque thread à tout moment.
Comme nous, un objet immuable ne peut être modifié par personne après sa création, ce qui rend chaque objet immuable est thread-safe par défaut. Nous n'avons pas besoin de lui appliquer des mesures de sécurité des threads telles que la création de méthodes synchronisées.
Ainsi, en raison de sa nature immuable, l'objet string peut être partagé par plusieurs threads et même s'il est manipulé par de nombreux threads, il ne changera pas sa valeur.
3. Sécurité
Dans chaque application, nous devons transmettre plusieurs secrets, par exemple le nom d'utilisateur \ les mots de passe de l'utilisateur, les URL de connexion et, en général, toutes ces informations sont passées en tant qu'objet de chaîne.
Supposons maintenant que si String n'aurait pas été de nature immuable, cela entraînerait une menace sérieuse pour la sécurité de l'application car ces valeurs sont autorisées à être modifiées et si cela est autorisé, elles pourraient être modifiées en raison d'un code mal écrit ou de toute autre personne qui avoir accès à nos références variables.
4. Chargement de classe
Comme indiqué dans Création d'objets via la réflexion en Java avec exemple , nous pouvons utiliser la
Class.forName("class_name")
méthode pour charger une classe en mémoire qui appelle à nouveau d'autres méthodes pour le faire. Et même JVM utilise ces méthodes pour charger des classes.Mais si vous voyez clairement, toutes ces méthodes acceptent le nom de la classe en tant qu'objet chaîne, les chaînes sont donc utilisées dans le chargement de la classe java et l'immuabilité fournit la sécurité par laquelle la classe correcte est chargée
ClassLoader
.Supposons que String n'aurait pas été immuable et que nous essayions de charger
java.lang.Object
ce qui est changéorg.theft.OurObject
entre et maintenant tous nos objets ont un comportement que quelqu'un peut utiliser pour des choses indésirables.5. Mise en cache du HashCode
Si nous allons effectuer des opérations liées au hachage sur un objet, nous devons remplacer la
hashCode()
méthode et essayer de générer un hashcode précis en utilisant l'état de l'objet. Si l'état d'un objet change, cela signifie que son hashcode doit également changer.Parce que String est immuable, la valeur d'un objet string ne sera jamais modifiée, ce qui signifie que son hashcode ne changera pas non plus, ce qui donne à la classe String l'occasion de mettre en cache son hashcode lors de la création de l'objet.
Oui, l'objet String met en cache son hashcode au moment de la création de l'objet, ce qui en fait le candidat idéal pour les opérations liées au hachage car 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é.En savoir plus sur les raisons pour lesquelles la chaîne est immuable et définitive en Java .
la source
Raison la plus importante selon cet article sur DZone:
J'espère que cela vous aidera.
la source
J'ai lu cet article Pourquoi la chaîne est immuable ou définitive en Java et suppose que ce qui suit peut être la raison la plus importante:
la source
Vous avez raison.
String
en java utilise le concept deString Pool
littéral. Lorsqu'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 renvoyer sa référence.Si une chaîne n'est pas immuable, changer la chaîne avec une référence sera conduit à une valeur erronée pour les autres références.J'ajouterais encore une chose, car il
String
est immuable, il est sans danger pour le multi-threading et une seule instance de String peut être partagée entre différents threads. Cela évite l'utilisation de la synchronisation pour la sécurité des threads, les chaînes sont implicitementthread safe
.la source
La classe String
FINAL
signifie que vous ne pouvez pas créer de classe pour en hériter, changer la structure de base et rendre le Sting mutable.Une autre variable d'instance et des méthodes de la classe String qui sont fournies sont telles que vous ne pouvez pas changer d'
String
objet une fois créé.La raison pour laquelle vous avez ajouté ne rend pas du tout la chaîne immuable, tout cela indique comment la chaîne est stockée dans le tas.
la source
La chaîne est donnée comme immuable par les micro-systèmes Sun, car la chaîne peut être utilisée comme clé dans la collection de cartes. StringBuffer est mutable. C'est la raison, il ne peut pas être utilisé comme clé dans l'objet de la carte
la source
La raison la plus importante pour laquelle une chaîne devient immuable en Java est la considération de sécurité . Le suivant serait la mise en cache .
Je crois que d'autres raisons données ici, telles que l'efficacité, la concurrence, la conception et le pool de chaînes découlent du fait que String est rendu immuable. Pour par exemple. String Pool a pu être créé car String était immuable et non l'inverse.
Consultez la transcription de l'entretien avec Gosling ici
la source
En plus des bonnes réponses, je voulais ajouter quelques points. Comme les chaînes, Array contient une référence au début du tableau, donc si vous créez deux tableaux
arr1
et que vous avezarr2
fait quelque chose commearr2 = arr1
ça, la référence seraarr2
identique, car laarr1
modification de la valeur de l'un d'entre eux entraînera la modification de l'autre par exempleNon seulement cela causerait des bogues dans le code, mais il peut également (et sera) exploité par un utilisateur malveillant. Supposons que vous ayez un système qui modifie le mot de passe administrateur. L'utilisateur doit d'abord entrer le
newPassword
, puis leoldPassword
si le programmeoldPassword
est identique auadminPass
changement de mot de passeadminPass = 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 unetemp
variable pour contenir le mot de passe administrateur avant que les utilisateurs n'entrent des données si leoldPassword
est égal àtemp
cela change le mot de passe sinonadminPass = 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 un accès administrateur. Une autre chose que je n'ai pas comprise en apprenant à propos des chaînes, pourquoi la JVM ne crée-t-elle pas une nouvelle chaîne pour chaque objet et n'a-t-elle pas un emplacement unique en mémoire pour cela et vous pouvez simplement le faire en utilisantnew String("str");
La raison pour laquelle vous ne voudriez pas toujours utilisernew
est parce que la mémoire n'est pas efficace et qu'il est plus lent dans la plupart des cas, en savoir plus .la source
Si
HELLO
est votre chaîne, vous ne pouvez pas passerHELLO
àHILLO
. Cette propriété est appelée propriété d'immutabilité.Vous pouvez avoir plusieurs variables String pointeur pour pointer HELLO String.
Mais si HELLO est char Array, vous pouvez changer HELLO en HILLO. Par exemple,
Répondre:
Les langages de programmation ont des variables de données immuables qui peuvent être utilisées comme clés dans une paire clé / valeur. Les variables de chaîne sont utilisées comme clés / index, elles sont donc immuables .
la source
Du
Security
point de vue, nous pouvons utiliser cet exemple pratique:la source