Maison Java javaDidacticiel Analyse approfondie de la méthode intern() en Java

Analyse approfondie de la méthode intern() en Java

May 19, 2017 am 09:47 AM
java

1. Problèmes de chaînes

Les chaînes sont en fait très utiles dans notre travail de codage quotidien, et elles sont relativement simples à utiliser, donc peu de gens font quelque chose de spécial à leur sujet. recherche. En revanche, les entretiens ou les tests écrits impliquent souvent des questions plus approfondies et plus difficiles. Lors du recrutement, je pose occasionnellement des questions pertinentes aux candidats. Cela ne signifie pas que les réponses doivent être particulièrement correctes et approfondies. Habituellement, le but de poser ces questions est double. Le premier est de tester la compréhension des connaissances de base. de JAVA. La seconde consiste à tester les connaissances de base de JAVA. La seconde consiste à examiner l'attitude du candidat à l'égard de la technologie.

Voyons ce que le programme suivant va produire ? Si vous pouvez répondre correctement à chaque question et savoir pourquoi, cet article ne vous dira pas grand-chose. Si la réponse est incorrecte ou si le principe n’est pas très clair, examinez de plus près l’analyse suivante. Cet article devrait vous aider à comprendre clairement les résultats de chaque programme et les raisons profondes de la publication des résultats.

Segment de code un :

package com.paddx.test.string;
public class StringTest {
    public static void main(String[] args) {
        String str1 = "string";
        String str2 = new String("string");
        String str3 = str2.intern();
 
        System.out.println(str1==str2);//#1
        System.out.println(str1==str3);//#2
    }
}
Copier après la connexion

Segment de code deux :

package com.paddx.test.string;
public class StringTest01 {
    public static void main(String[] args) {
        String baseStr = "baseStr";
        final String baseFinalStr = "baseStr";
 
        String str1 = "baseStr01";
        String str2 = "baseStr"+"01";
        String str3 = baseStr + "01";
        String str4 = baseFinalStr+"01";
        String str5 = new String("baseStr01").intern();
 
        System.out.println(str1 == str2);//#3
        System.out.println(str1 == str3);//#4
        System.out.println(str1 == str4);//#5
        System.out.println(str1 == str5);//#6
    }
}
Copier après la connexion

Segment de code trois (1) :

package com.paddx.test.string;  
public class InternTest {
    public static void main(String[] args) {
 
        String str2 = new String("str")+new String("01");
        str2.intern();
        String str1 = "str01";
        System.out.println(str2==str1);//#7
    }
}
Copier après la connexion

Segment de code Trois (2) :

package com.paddx.test.string;
 
public class InternTest01 {
    public static void main(String[] args) {
        String str1 = "str01";
        String str2 = new String("str")+new String("01");
        str2.intern();
        System.out.println(str2 == str1);//#8
    }
}
Copier après la connexion

Pour faciliter la description, j'ai encodé les résultats de sortie du code ci-dessus de #1~#8, et la partie de police bleue ci-dessous est le résultat.

2. Analyse approfondie des chaînes

1. Analyse du segment de code 1

Les chaînes n'appartiennent pas aux types de base, mais elles peuvent être comme des types de base. Attribuez directement une valeur via un littéral, bien sûr, vous pouvez également générer une chaîne objet via new. Cependant, il existe une différence essentielle entre générer des chaînes par affectation littérale et new :

Analyse approfondie de la méthode intern() en Java

Lors de la création d'une chaîne par affectation littérale, la priorité sera donnée aux constantes Vérifiez si la même chaîne existe déjà dans le pool . Si elle existe déjà, la référence dans la pile pointe directement vers la chaîne si elle n'existe pas, une chaîne est générée dans le pool constant puis La référence sur la pile pointe vers cette chaîne. Lors de la création d'une chaîne via new, un objet chaîne est directement généré dans le tas (notez qu'après JDK 7, HotSpot a transféré le pool de constantes de la génération permanente vers le tas. Pour des informations détaillées, veuillez vous référer à "Mémoire JDK8 Model-The Disagging PermGen"), la référence dans la pile pointe vers l'objet. Pour les objets chaîne dans le tas, vous pouvez ajouter la chaîne au pool de constantes via la méthode intern() et renvoyer une référence à la constante.

Maintenant, nous devrions être capables de comprendre clairement le résultat du segment de code 1 :

Résultat n°1 : Parce que str1 pointe vers une constante dans la chaîne, str2 est un objet généré dans le tas, donc str1==str2 renvoie false.

Résultat n°2 : str2 appelle la méthode interne, qui copiera la valeur de str2 ("string") dans le pool de constantes, mais la chaîne existe déjà dans le pool de constantes (c'est-à-dire que la chaîne pointe vers par str1), donc renvoie directement une référence à la chaîne, donc str1==str2 renvoie vrai.

Les résultats suivants de l'exécution du segment de code un :

Analyse approfondie de la méthode intern() en Java

2. Analyse du segment de code deux

Pour Le résultat du deuxième segment de code est plus facile à comprendre en décompilant le fichier StringTest01.class :

Contenu du pool constant (partie) :

Analyse approfondie de la méthode intern() en Java

Instruction d'exécution ( part), la deuxième colonne #+ordinal correspond à l'élément dans le pool constant) :

Analyse approfondie de la méthode intern() en Java

Avant d'expliquer le processus d'exécution ci-dessus, comprenez d'abord les deux instructions :

ldc : Poussez l'élément du pool de constantes d'exécution, chargez la référence de l'élément spécifié du pool de constantes vers la pile.

astore_ : stocke la référence dans une variable locale, attribue la référence à la nième variable locale .

Nous commençons maintenant à expliquer le processus d'exécution du segment de code 2 :

0 : ldc               #2 : Chargez le deuxième élément ("baseStr") du pool de constantes dans la pile.

2 : astore_1 : Attribue la référence en 1 à la première variable locale, c'est-à-dire String baseStr = "baseStr"

3 : ldc #2 : Charge la seconde dans la constante ; pool item("baseStr") sur la pile.

5 : astore_2 : Attribuez la référence en 3 à la deuxième variable locale, c'est-à-dire la chaîne finale baseFinalStr="baseStr" ;

6 : ldc #3 : Chargez la première chaîne dans le pool constant Trois éléments ("baseStr01") sont ajoutés à la pile.

8 : astore_3 : Attribue la référence en 6 à la troisième variable locale, à savoir String str1="baseStr01";

9 : ldc #3 : Chargez le troisième élément ("baseStr01") du pool de constantes dans la pile.

11 : astore 4 : Attribuez la référence en 9 à la quatrième variable locale : String str2="baseStr01" ;

Résultat n°3 : str1==str2 retournera certainement true , car les deux str1 et str2 pointent vers la même adresse de référence dans le pool constant. Donc en fait, après JAVA 1.6, l'opération "+" d'une chaîne constante sera directement synthétisée en chaîne lors de la phase de compilation.

13 : nouveau           #4 : Générer une instance de StringBuilder.

16 : dup : Copiez la référence de l'objet généré par 13 et poussez-le sur la pile.

17 : invokespecial #5 : Appelez le cinquième élément du pool de constantes, la méthode StringBuilder.

Les trois instructions ci-dessus sont utilisées pour générer un objet StringBuilder.

20 : aload_1  : Charge la valeur du premier paramètre, qui est "baseStr"

21 : Invoquervirtual #6 : Appeler la méthode append de l'objet StringBuilder.

24 : ldc #7 : Chargez le septième élément ("01") du pool de constantes dans la pile.

26 : invoquervirtual #6 : Appelez la méthode StringBuilder.append.

29 : invokevirtual #8 : Appelez la méthode StringBuilder.toString.

32 : astore 5 : modifiez l'affectation de la référence du résultat dans 29 à la cinquième variable locale, c'est-à-dire l'affectation à la variable str3.

Résultat n°4 : Comme str3 est en fait le résultat généré par stringBuilder.append(), il n'est pas égal à str1 et le résultat renvoie false.

34 : ldc #3 : Chargez le troisième élément ("baseStr01") du pool de constantes dans la pile.

36 : astore 6 : Attribuez la référence en 34 à la sixième variable locale, c'est-à-dire str4="baseStr01";

Résultat n°5 : Parce que str1 et str4 pointent vers des constantes La troisième élément dans le pool, donc str1==str4 renvoie true. Ici, nous pouvons également trouver un phénomène : pour les champs finaux, le remplacement constant est effectué directement au moment de la compilation, tandis que pour les champs non finaux, le traitement de l'affectation est effectué au moment de l'exécution.

38 : nouveau #9 : Créer un objet String

41 : dup : Copiez la référence et placez-la sur la pile.

42 : ldc #3 : Chargez le troisième élément ("baseStr01") du pool de constantes dans la pile.

44 : invokespecial #10 : Appelez la méthode String."" et transmettez la référence à l'étape 42 en tant que paramètre à la méthode.

47 : invokevirtual #11 : Appelez la méthode String.intern.

Le code source correspondant de 38 à 41 est new String(“baseStr01″).intern().

50 : astore 7 : attribuez le résultat renvoyé à l'étape 47 à la variable 7, c'est-à-dire que str5 pointe vers la position de baseStr01 dans le pool de constantes.

Résultat n°6 : Comme str5 et str1 pointent vers la même chaîne dans le pool de constantes, str1==str5 renvoie true.

Exécutez le segment de code deux, le résultat de sortie est le suivant :

Analyse approfondie de la méthode intern() en Java

Analyse du segment de code trois :

Pour le segment de code trois, les résultats d'exécution sont différents dans JDK 1.6 et JDK 1.7. Jetons d'abord un coup d'œil aux résultats en cours d'exécution, puis expliquons les raisons :

Résultats en cours d'exécution sous JDK 1.6 :

Analyse approfondie de la méthode intern() en Java

Résultats en cours d'exécution sous JDK 1.7 :

Analyse approfondie de la méthode intern() en Java

Selon l'analyse du segment de code 1, il devrait être facile d'obtenir le résultat du JDK 1.6, car str2 et str1 pointent à l'origine vers des emplacements différents et devraient renvoyer false.

Le problème étrange est qu'après JDK 1.7, true est renvoyé pour le premier cas, mais après avoir changé la position, le résultat renvoyé devient faux. La raison principale en est qu'après JDK 1.7, HotSpot a déplacé le pool de constantes de la génération permanente vers le métaespace. Pour cette raison, la méthode interne après JDK 1.7 a subi des changements d'implémentation relativement importants. toujours être utilisé en premier. Accédez à pour demander si existe déjà dans le pool constant. S'il existe, renvoyez la référence dans le pool constant. Ce n'est pas différent d'avant. introuvable dans le pool constant, alors la chaîne ne sera plus copiée dans le pool constant, mais une référence à la chaîne d'origine sera générée dans le pool constant. Donc :

Résultat n°7 : Dans le premier cas, comme il n'y a pas de chaîne "str01" dans le pool constant, une référence à "str01" dans le tas sera générée dans le pool constant, et lors de l'exécution affectation littérale, le pool de constantes existe déjà, la référence peut donc être renvoyée directement. Par conséquent, str1 et str2 pointent tous deux vers la chaîne dans le tas et renvoient true.

Résultat n°8 : après avoir échangé les positions, comme le pool de constantes n'existe pas lors de l'exécution d'une affectation littérale (String str1 = "str01"), str1 pointe vers la position dans le pool de constantes et str2 pointe vers le tas When. la méthode interne est utilisée pour l'objet dans , elle n'a aucun effet sur str1 et str2, donc false est renvoyé.

[Recommandations associées]

1. Tutoriel vidéo gratuit Java

2. Résumé de l'expérience d'utilisation de la méthode intern() dans. JAVA

3.Quel est le concept de méthode interne en Java

4 Analyser le rôle de intern() en Java

5. Explication détaillée de intern() dans l'objet String

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Vous avez un jeu croisé?
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Programme Java pour trouver le volume de la capsule Programme Java pour trouver le volume de la capsule Feb 07, 2025 am 11:37 AM

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

Comment exécuter votre première application Spring Boot dans Spring Tool Suite? Comment exécuter votre première application Spring Boot dans Spring Tool Suite? Feb 07, 2025 pm 12:11 PM

Spring Boot simplifie la création d'applications Java robustes, évolutives et prêtes à la production, révolutionnant le développement de Java. Son approche "Convention sur la configuration", inhérente à l'écosystème de ressort, minimise la configuration manuelle, allo

See all articles