web-dev-qa-db-fra.com

"New String ()" est-il également immuable?

J'ai étudié Java String pendant un certain temps. Les questions suivantes sont basées sur les articles ci-dessous

Java String est spécial
Immuabilité de la chaîne en Java

  1. Immuabilité: Maintenant, en tenant compte de l'immuabilité, la classe String a été conçue pour que les valeurs du pool commun puissent être réutilisées dans d'autres endroits/variables. Cela est valable si le String a été créé en tant que

    String a = "Hello World!"; Cependant, si je crée une chaîne comme

    String b = new String("Hello World!"); pourquoi est-ce aussi immuable? (ou est-ce?). Comme cela a une mémoire de tas dédiée, je devrais être en mesure de le modifier sans affecter aucune autre variable. Donc, par conception, y avait-il une autre raison pour laquelle String dans son ensemble est considéré comme immuable? Ou mon hypothèse ci-dessus est-elle fausse?

  2. La deuxième chose que je voulais demander concernait le pool de chaînes commun . Si je crée un objet chaîne comme

    String c = ""; Une entrée vide est-elle créée dans le pool?

Y a-t-il déjà des articles à ce sujet? Si oui, quelqu'un pourrait-il partager le lien?

72
Some guy

new String() est une expression qui produit un String ... et un String est immuable, quelle que soit la façon dont elle est produite.

(Demander si new String() est modifiable ou non est absurde. C'est du code de programme, pas une valeur. Mais je suppose que ce n'est pas ce que vous vouliez vraiment dire.)


Si je crée un objet chaîne comme String c = ""; une entrée vide est-elle créée dans le pool?

Oui; c'est-à-dire qu'une entrée est créée pour la chaîne vide. Il n'y a rien de spécial dans un String vide.

(Pour être pédant, l'entrée de la piscine pour "" est créé bien avant l'exécution de votre code. En fait, il est créé lorsque votre code est chargé ... ou peut-être même plus tôt que cela.)


Donc, je voulais savoir si le nouvel objet tas était immuable aussi, ...

Oui, ça l'est. Mais l'immuabilité est une propriété fondamentale des objets String. Tous les objets String.

Vous voyez, l'API String ne fournit tout simplement pas de méthodes any pour changer un String. Donc (à part certains dangereux et stupides1 astuces utilisant la réflexion), vous ne pouvez pas muter un String.

et si oui, quel était le but?.

La raison pour laquelle Java String est conçue comme une classe immuable est la simplicité. Elle facilite l'écriture de programmes corrects et la lecture/raison du code d'autres personnes si la classe de chaîne principale fournit une interface immuable (ou du moins, c'est la justification de cette décision de conception, si je comprends bien).

En partant de la réponse, je suppose que d'autres références à la même variable sont l'une des raisons. Veuillez me faire savoir si j'ai raison de comprendre cela.

Non, c'est plus fondamental que cela. Simplement, tous les objets String sont immuables. Aucun raisonnement spécial compliqué n'est requis pour comprendre cela. C'est juste >> est <<.

Pour mémoire, si vous voulez un objet "string-like" mutable en Java, vous pouvez utiliser StringBuilder ou StringBuffer. Mais ce sont des types différents de String.


1 - La raison pour laquelle ces astuces sont (IMO) dangereuses et stupides est qu'elles affectent les valeurs des chaînes potentiellement partagées par d'autres parties de votre application via le pool de chaînes. Cela peut provoquer le chaos ... d'une manière que le prochain gars à maintenir votre code a peu de chances de retrouver.

105
Stephen C

La chaîne est immuable quelle que soit la façon dont elle est instanciée

1) La réponse courte est oui , new String() est également immuable.

Parce que toutes les opérations mutables possibles (comme replace, toLowerCase etcetra) que vous effectuez sur String n'affecte pas l'instance d'origine String et vous renvoie une nouvelle instance .

Vous pouvez vérifier cela dans Javadoc pour String. Chaque méthode public de String exposée renvoie une nouvelle instance String et ne modifie pas l'instance actuelle sur laquelle vous avez appelé la méthode.

Ceci est très utile dans un environnement multi-thread car vous n'avez pas à penser à la mutabilité ( quelqu'un changera la valeur ) chaque fois que vous passez ou partagez le String autour. String peut facilement être le type de données le plus utilisé, donc les concepteurs nous ont tous bénis de ne pas penser à la mutabilité à chaque fois et nous ont évité beaucoup de douleur.

Immuabilité autorisée Pool de chaînes ou mise en cache

C'est à cause de la propriété d'immutabilité que le pool interne de chaînes était possible, comme lorsque la même valeur de chaîne est requise à un autre endroit, cette référence immuable est retournée. Si String aurait été modifiable, il n'aurait pas été possible de partager des String comme ceci pour économiser de la mémoire.

L'immutabilité des chaînes n'était pas due à la mise en commun, mais l'immutabilité comporte plus d'avantages.

L'internement ou le regroupement de chaînes est un exemple de modèle Flyweight Design

2) Oui, il sera interné comme tout autre String car un String vierge est aussi autant un String que les autres instances String.

Les références:

42
Narendra Pathai

Les bibliothèques Java Java sont fortement optimisées en fonction de la contrainte selon laquelle tout objet String est immuable, quelle que soit la façon dont cet objet est construit. Même si vous créez votre b à l'aide de new, un autre code que vous transmettez à cette instance traitera la valeur comme immuable. Ceci est un exemple du modèle Value Object, et tous les avantages (sécurité des threads, pas besoin de faire des copies privées) s'appliquent .

La chaîne vide "" est un objet String légitime comme tout le reste, il se trouve qu'il n'a aucun contenu interne, et comme toutes les chaînes de constantes au moment de la compilation sont internées, je vais pratiquement garantir qu'une bibliothèque d'exécution l'a déjà provoqué à ajouter à la piscine.

18
chrylis

1) La partie immuable n'est pas car du pool; cela rend simplement la piscine possible en premier lieu. Les chaînes sont souvent passées comme arguments à d'autres fonctions ou même partagées avec d'autres threads; Rendre les cordes immuables était une décision de conception pour faciliter le raisonnement dans de telles situations. Donc oui - Strings dans Java sont toujours immuables, peu importe comment vous les créez (notez qu'il est possible d'avoir des chaînes mutables dans Java - mais pas avec la classe String).

2) Oui. Probablement. Je ne suis pas sûr à 100%, mais cela devrait être le cas.

14
Cubic

À partir de documentation Java Oracle :

Les chaînes sont constantes; leurs valeurs ne peuvent pas être modifiées après leur création .

Et encore:

Les tampons de chaîne prennent en charge les chaînes mutables. Les objets String étant immuables, ils peuvent être partagés.

De manière générale: les objets "tous primitifs" (ou apparentés) sont immuables (veuillez accepter mon manque de formalisme).

Article connexe sur Stack Overflow:

A propos du pool d'objets : le pool d'objets est une optimisation Java qui n'est PAS liée à l'immuable également).

7
venergiac

Ce n'est pas strictement une réponse à votre question, mais si derrière votre question se trouve un souhait d'avoir des chaînes modifiables que vous pouvez manipuler, vous devriez vérifier la classe StringBuilder, qui implémente bon nombre des mêmes méthodes que String a mais ajoute également des méthodes pour changer le contenu actuel.

Une fois que vous avez construit votre chaîne de manière à vous en contenter, il vous suffit d'appeler toString() dessus pour la convertir en un String ordinaire que vous pouvez passer à routines de bibliothèque et autres fonctions qui ne prennent que Strings.

De plus, StringBuilder et String implémentent l'interface CharSequence, donc si vous voulez écrire des fonctions dans votre propre code qui peuvent utiliser des chaînes mutables et immuables, vous pouvez les déclarer pour prendre n'importe quel objet CharSequence.

7
Dolda2000

La chaîne est immuable signifie que vous ne pouvez pas changer l'objet lui-même, peu importe comment vous l'avez créé. Et comme pour la deuxième question: oui, il créera une entrée.

6
Kick

En fait, c'est l'inverse.

[...] la classe String a été conçue pour que les valeurs du pool commun puissent être réutilisées dans d'autres endroits/variables.

Non, la classe String est immuable afin que vous puissiez en référencer une instance en toute sécurité, sans vous soucier qu'elle soit modifiée à partir d'une autre partie de votre programme. C'est pourquoi la mise en commun est possible en premier lieu.

Alors, considérez ceci:

// this string literal is interned and referenced by 'a'
String a = "Hello World!";

// creates a new instance by copying characters from 'a'
String b = new String(a);

Maintenant, que se passe-t-il si vous créez simplement une référence à votre variable b nouvellement créée?

// 'c' now points to the same instance as 'b'
String c = b;

Imaginez que vous passez c (ou, plus précisément, l'objet auquel il fait référence) à une méthode sur un thread différent et continuez à travailler avec la même instance sur votre thread principal. Et imaginez maintenant ce qui se passerait si les chaînes étaient mutables.

Pourquoi est-ce le cas de toute façon?

Si rien d'autre, c'est parce que les objets immuables rendent le multithreading beaucoup plus simple, et généralement encore plus rapide. Si vous partagez un objet modifiable (qui serait n'importe quel objet avec état, avec des champs ou propriétés privés/publics modifiables) entre différents threads, vous devez faire particulièrement attention à assurer un accès synchronisé (mutex, sémaphores). Même avec cela, vous avez besoin d'un soin particulier pour garantir l'atomicité dans toutes vos opérations. Le multithreading est difficile.

En ce qui concerne les implications en termes de performances, notez que la plupart du temps, la copie de la chaîne entière dans une nouvelle instance, afin de changer même un seul caractère, est en fait plus rapide que d'induire un changement de contexte coûteux en raison des constructions de synchronisation nécessaires pour assurer un accès thread-safe. Et comme vous l'avez mentionné, l'immuabilité offre également des possibilités d'internement, ce qui signifie qu'elle peut réellement aider à réduire l'utilisation de la mémoire.

C'est généralement une assez bonne idée de rendre autant de choses immuables que possible .

5
Groo

1) Immuabilité: la chaîne sera immuable si vous la créez de manière nouvelle ou autre pour des raisons de sécurité

2) Oui, il y aura une entrée vide dans le pool de chaînes.

Vous pouvez mieux comprendre le concept en utilisant le code

    String s1 = new String("Test");
    String s2 = new String("Test");
    String s3 = "Test";
    String s4 = "Test";

    System.out.println(s1==s2);//false
    System.out.println(s1==s3);//false
    System.out.println(s2==s3);//false
    System.out.println(s4==s3);//true

J'espère que cela aidera votre requête. Vous pouvez toujours vérifier le code source de la classe String en cas de meilleure compréhension Lien: http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/6-b14/Java /lang/String.Java

4
nikhilgupta86

Les chaînes créées seront toujours immuables quelle que soit la façon dont elles sont créées.

Réponses à vos questions:

  1. La seule différence est:
    Lorsque la chaîne est créée comme - {String a = "Hello World!";} Alors seulement n objet est créé.
    Et quand il est créé comme - {String b = new String("Hello World!");} alors deux objets se crée. Le premier, car vous avez utilisé le mot clé 'new' et le second en raison de la propriété String.

  2. Oui bien sûr. Une entrée vide sera créée dans le pool.

2
Arbind

1 - La chaîne est immuable . Voir ceci:

ne chaîne Java est-elle vraiment immuable?

Vous pouvez donc le créer de plusieurs façons.

2-Réponse courte: Oui sera vide.

2
user1968030

L'immuabilité n'est pas une caractéristique de new, c'est une caractéristique de la classe String. Il n'a pas de méthodes de mutation, il est donc immuable.

1
fastcodejava

La chaîne est immuable car elle ne vous donne aucun moyen de la modifier. Il est conçu pour éviter toute falsification (il est définitif, le tableau sous-jacent n'est pas censé être touché ...).

Identiquement, Integer est immuable, car il n'y a aucun moyen de le modifier.

Peu importe comment vous le créez.

1
njzk2
 String A = "Test"
 String B = "Test"

Maintenant String B called "Test" .toUpperCase () which change the same object into"TESTER", soUNEwill also be "TEST" `ce qui n'est pas souhaitable.

1
Surya Rawat

Notez que dans votre exemple, la référence est modifiée et non l'objet auquel elle se réfère, c'est-à-dire b car une référence peut être modifiée et faire référence à un nouvel objet. Mais ce nouvel objet est immuable, ce qui signifie que son contenu ne sera pas modifié "après" avoir appelé le constructeur.

Vous pouvez changer une chaîne en utilisant b=b+"x"; Ou b=new String(b);, et le contenu de la variable a semble changer, mais ne confondez pas l'immuabilité d'une référence (ici la variable b) et l'objet auquel il se réfère (pensez aux pointeurs en C). L'objet vers lequel la référence pointe restera inchangé après sa création.

Si vous devez modifier une chaîne en modifiant le contenu de l'objet (au lieu de modifier la référence), vous pouvez utiliser StringBuffer, qui est une version modifiable de String.

0
Sohail Si