après la non-chaîne utilisée opérande de l'opérateur « + » sera le feu de chaîne conduit à la piscine chaîne?

Jim G:

Je bonnettes et la préparation de l'OCP 1Z0-815 et je lis de cet excellent livre préparer:

Deshmukh, Hanumant. OCP Oracle Certified Professional Java SE 11 Programmeur I Principes de base de l'examen 1Z0-815: Guide d'étude pour faire passer l'OCP Java 11 Developer Certification Partie 1 examen 1Z0-815 (p 99.). Enthuware. Edição faire Kindle.

String str = "hello";
for( int i = 0; i < 5; i + +) {
    str = str + i;
} 

L'objet ci-dessus crée une chaîne contenant « bonjour » au début, puis deux autres à chaque itération de la boucle - une chaîne contenant la valeur de int i et la chaîne concaténée. Ainsi, dans l'ensemble, le code ci-dessus crée 1 + 2 * 5 = 11 cordes. Cependant, si on vous demande combien de cordes seront admissibles à déchets collectés, la réponse est pas facile. La spécification du langage Java mentionne dans la section 15.8.1 que la non-chaîne opérande de l'opérateur + est converti en une chaîne à l'exécution, mais il ne dit pas clairement si cette chaîne va à la piscine à cordes (dans ce cas, il ne sera pas ordures collectées) ou non.

Permettez-moi de vous montrer un autre morceau de code:

String s = "hello";
int k = 100;
s = s + " 123" + k;

Dans ce cas, l'article 15.8.1 JLS dit clairement qu'un compilateur peut éviter de créer des chaînes multiples tout à fait en faisant usage d'un StringBuilder. Ainsi, il est impossible de dire combien de chaînes seront créées et combien seront admissibles à déchets collectés ...

La déclaration ci-dessus » ... La spécification du langage Java mentionne dans la section 15.8.1 que la non-chaîne opérande de l'opérateur + est converti en une chaîne à l'exécution, mais il ne dit pas clairement si cette chaîne va à la piscine String .. . » m'a conduit à chercher autour mais je ne l'ai pas réussi à trouver une explication: pour autant que je ne vois pas « nouveau » Je comprends qu'en effet, il va à la piscine à cordes et il est donc pas un objet. Consequentlly il n'est pas elegiable pour la collecte des ordures du tout. Est-ce que je dis quelque chose de mal?

En d'autres termes, pour autant que comprendre, chaque boucle se traduira par une chaîne constante dans la chaîne Piscine Heap (Java 11 à l'esprit au lieu de Java 7). hello0, hello1, hello2 et ainsi de suite et il n'y aura pas de candidat pour la collecte de déchets du tout. Je comprends que les ordures Colletion objets « propre » créé par nouvel opérateur et ne pas agir sur chaîne Pool.

Sur la base du paragraphe de conclusion, » ... section 15.8.1 dit clairement qu'un compilateur peut éviter de créer des chaînes multiples tout à fait en faisant usage d'un StringBuilder. Par conséquent, il est impossible de dire combien de chaînes seront créées et combien seront admissibles soient nettoyés ... » Je suppose qu'il dit que je ne peux pas découvrir combien de chaînes sont créées dans la chaîne Piscine dans le deuxième exemple de code (wihtout boucle) car StringBuilder est utilisé derrière la scène et nous savons que StringBuilder manipuler concaténation en mémoire en évitant de créer de nombreux littéraux de chaîne. Eh bien, si tel est le cas, je ne peux toujours supposer dans le premier thatt de code fofr chaque boucle entraînera une littérales String (hello0, hello1 ...) qui va à chaîne Piscine et ne seront pas admissibles pour la collecte de déchets en termes très pratiques. Ai-je tort?

PS .: Vous pouvez remarquer que Garbage Collection agit sur la corde piscine mais je comprends qu'en termes pratical, chaîne littérale dans la chaîne Piscine réside pour si longtemps que l' on peut considérer qu'il est jamais éligible pour d'ordures avant la fin du programme ( "il y a une référence implicite à l'objet string dans le code de chaque méthode qui utilise le littéral. » et « tous les littéraux de chaîne dans la piscine de chaîne sont accessibles jusqu'à ce que le programme est terminé et donc pas admissible à la collecte des ordures »

Stephen C:

pour autant que je ne vois pas , newje comprends qu'en effet , il va à la piscine à cordes et il est donc pas un objet.

Tout d' abord, la spécification du langage Java ne mentionne pas la piscine de chaîne spécifique. Ce qu'il dit en fait est que si deux expressions constantes de type chaîne sont equal, alors ils seront le même objet. (Cette garantie couvre littéraux de chaîne, mais couvre aussi des cas comme String s = "a" + "b";)

La piscine de chaîne est un >> << mécanisme de le faire, mais le JLS ne prescrit pas un mécanisme spécifique.


Qu'en est- il new?

Le JLS dit aussi que l' newopérateur produit toujours une marque nouvel objet:

« La valeur d'une expression de création d'instance de classe est une référence à l'objet nouvellement créé de la classe spécifiée. Chaque fois que l'expression est évaluée, un nouvel objet est créé. » ( JLS 15.9.4 )

La conséquence de ceci est:

String a1 = new String("a");
System.out.println("a" == a1);   // prints "false"

Cela doit être fait, parce que le nouveau Stringn'est pas un nouveau. Depuis la piscine de chaîne est un mécanisme de dédoublonnage, nous pouvons conclure que new String("a")ne met pas le nouvel objet String dans la piscine de chaîne.


De même, l' +opérateur crée une nouvelle chaîne:

« Le résultat de concaténation de chaîne est une référence à un Stringobjet qui est la concaténation des deux opérandes chaînes. Les caractères de la main gauche opérande précéder les caractères du droit opérande dans la chaîne nouvellement créée . » ( JLS 15.18.1 )

Le JLS dit aussi que le compilateur peut optimiser les expressions impliquant +:

« Une mise en œuvre peut choisir d'effectuer la conversion et concaténation en une seule étape pour éviter de créer puis jeter un intermédiaire Stringobjet. Pour augmenter les performances de concaténation de chaîne répétée, un compilateur Java peut utiliser la StringBufferclasse ou une technique similaire à réduire le nombre d'intermédiaires Stringobjets qui sont créés par l' évaluation d'une expression.

Pour les types primitifs, une mise en œuvre peut également optimiser l' écart de la création d'un objet d'emballage en convertissant directement à partir d' un type primitif à une chaîne. » ( JLS 15.18.1 )

Mais notez que cette optimisation est uniquement autorisée dans une expression, et non à travers de multiples déclarations.


Le JLS ne dit rien sur d' autres opérations de chaîne. Pour leur spécification il faut se référer aux javadocs . Dans les versions actuelles, les seules Stringméthodes qui indique qu'une nouvelle chaîne est toujours créée sont les deux joinméthodes.

Mais aussi, la seule méthode de chaîne qui mentionne spécifiquement la piscine de chaîne est la internméthode.


Voilà ce que disent les spécifications. Qu'est-ce que les implémentations de chaîne en réalité?

Eh bien , si vous examinez le code source standard pour les implémentations Java SE remontant à Java 1.1, vous trouverez que , à part intern, aucune méthode de cordes mettre des objets dans la piscine de chaîne. Aucun.


Vous avez également dit ceci:

Je comprends qu'en pratique, chaîne littérale dans la chaîne Piscine réside pour si longtemps que nous pouvons considérer qu'il est admissible à jamais Collection d'ordures avant la fin du programme.

Ce qui est vrai est la plupart des cas. L'exception est le code qui est que vous pouvez créer un classloader et l'utiliser pour charger les classes dynamiquement. Si ce classloader devient inaccessible, et il n'y a pas d'autres références aux classes qu'il chargé, puis ses littéraux de chaîne peut être injoignable ... avant la fin du programme.

Cela est susceptible de se produire si vous utilisez un produit (par exemple, un conteneur Web) où les nouvelles versions de classes peuvent être chargées à chaud.


Enfin, si nous regardons l'exemple:

   String str = "hello";
   for (int i = 0; i < 5; i++) {
       str = str + i;
   } 

En pratique:

  1. La première fois que nous courons, un nouveau Stringobjet sera (probablement) créé pour le "hello"littéral.

  2. A chaque itération de la boucle, au moins un nouveau Stringsera créé. Il est possible qu'un intermédiaire Stringsera créé pour représenter la valeur de chaîne de i, mais le compilateur est autorisé à optimiser les lignes .

  3. Aucun des intermédiaires Stringobjets sera interné / ajoutée à la piscine de chaîne.

  4. Tout sauf le "hello"littéral et la valeur finale sera injoignable.

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=315607&siteId=1
conseillé
Classement