Heim Java javaLernprogramm Eingehende Analyse der intern()-Methode in Java

Eingehende Analyse der intern()-Methode in Java

May 19, 2017 am 09:47 AM
java

1. String-Probleme

Strings sind in unserer täglichen Codierungsarbeit tatsächlich sehr nützlich und relativ einfach zu verwenden, daher unternehmen nur wenige Leute etwas Besonderes Forschung. Andererseits beinhalten Vorstellungsgespräche oder schriftliche Tests oft tiefergehende und schwierigere Fragen. Ich stelle den Kandidaten bei der Einstellung gelegentlich relevante Fragen. Dies bedeutet nicht, dass die Antworten besonders korrekt und ausführlich sein müssen. Der erste Zweck besteht darin, das Verständnis der Grundkenntnisse zu testen JAVA. Die zweite besteht darin, die Grundkenntnisse von JAVA zu testen. Die zweite besteht darin, die Einstellung des Bewerbers zur Technologie zu untersuchen.

Mal sehen, was das folgende Programm ausgibt? Wenn Sie jede Frage richtig beantworten können und wissen, warum, dann wird Ihnen dieser Artikel nicht viel sagen. Wenn die Antwort falsch ist oder das Prinzip nicht ganz klar ist, schauen Sie sich die folgende Analyse genauer an. Dieser Artikel soll Ihnen helfen, die Ergebnisse jedes Programms und die tiefer liegenden Gründe für die Ausgabe der Ergebnisse klar zu verstehen.

Codesegment eins:

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
    }
}
Nach dem Login kopieren

Codesegment zwei:

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
    }
}
Nach dem Login kopieren

Codesegment drei (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
    }
}
Nach dem Login kopieren

Codesegment Drei (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
    }
}
Nach dem Login kopieren

Der Einfachheit halber habe ich die Ausgabeergebnisse des obigen Codes von #1 bis #8 codiert, und der blaue Schriftartteil unten ist das Ergebnis.

2. Eingehende Analyse von Strings

1. Analyse von Codesegment 1

Strings gehören nicht zu den Grundtypen, können es aber Weisen Sie den Wert direkt über ein Literal zu, Sie können jedoch auch ein Zeichenfolgen--Objekt über „new“ generieren. Es gibt jedoch einen wesentlichen Unterschied zwischen der Erzeugung von Zeichenfolgen durch Literalzuweisung und Neu:

Eingehende Analyse der intern()-Methode in Java

Beim Erstellen einer Zeichenfolge durch Literalzuweisung wird Konstanten Priorität eingeräumt. Überprüfen Sie, ob Die gleiche Zeichenfolge ist bereits im -Pool vorhanden. Wenn sie bereits vorhanden ist, zeigt die -Referenz im Stapel direkt auf die Zeichenfolge. Wenn sie nicht vorhanden ist, wird eine Zeichenfolge im Konstantenpool generiert Die Referenz auf dem Stapel zeigt auf diese Zeichenfolge. Beim Erstellen einer Zeichenfolge über new wird ein Zeichenfolgenobjekt direkt im Heap generiert (beachten Sie, dass HotSpot nach JDK 7 den Konstantenpool von der permanenten Generierung auf den Heap übertragen hat. Ausführliche Informationen finden Sie unter „JDK8-Speicher“. Model-The Disappearing PermGen“ Artikel), zeigt die Referenz im Stapel auf das Objekt. Für Zeichenfolgenobjekte im Heap können Sie die Zeichenfolge über die Methode intern() zum Konstantenpool hinzufügen und einen Verweis auf die Konstante zurückgeben.

Jetzt sollten wir das Ergebnis von Codesegment 1 klar verstehen können:

Ergebnis Nr. 1: Da str1 auf eine Konstante in der Zeichenfolge zeigt, ist str2 ein im Heap generiertes Objekt. also gibt str1==str2 false zurück.

Ergebnis Nr. 2: str2 ruft die interne Methode auf, die den Wert in str2 („string“) in den Konstantenpool kopiert, aber der String existiert bereits im Konstantenpool (d. h. der String, auf den gezeigt wird). durch str1), also Gibt einen Verweis auf die Zeichenfolge direkt zurück, sodass str1==str2 true zurückgibt.

Die folgenden Ergebnisse der Ausführung von Codesegment eins:

Eingehende Analyse der intern()-Methode in Java

2. Analyse von Codesegment zwei

Für Das Ergebnis des zweiten Codesegments ist durch Dekompilieren der Datei StringTest01.class leichter zu verstehen:

Konstanter Poolinhalt (Teil):

Eingehende Analyse der intern()-Methode in Java

Ausführungsanweisung ( Teil) , die zweite Spalte #+Ordinalzahl entspricht dem Element im Konstantenpool):

Eingehende Analyse der intern()-Methode in Java

Bevor Sie den obigen Ausführungsprozess erklären, verstehen Sie zunächst die beiden Anweisungen:

ldc: Element aus dem Laufzeitkonstantenpool verschieben, die Referenz des angegebenen Elements aus dem Konstantenpool in den Stapel laden.

astore_: Referenz in lokaler Variable speichern, Referenz der n-ten lokalen

-Variable zuweisen.

Jetzt beginnen wir mit der Erklärung des Ausführungsprozesses von Codesegment 2:

0: ldc               #2: Laden Sie das zweite Element („baseStr“) im Konstantenpool in den Stapel.

2: astore_1: Weisen Sie die Referenz in 1 der ersten lokalen Variablen zu, also String baseStr = "baseStr"

3: ldc #2: Laden Sie die zweite in die Konstante pool item("baseStr") auf den Stapel.

5: astore_2: Weisen Sie die Referenz in 3 der zweiten lokalen Variablen zu, d. h. final String baseFinalStr="baseStr"

6: ldc #3: Laden Sie den ersten String in Konstantenpool Drei Elemente („baseStr01“) werden dem Stapel hinzugefügt.

8: astore_3: Weisen Sie die Referenz in 6 der dritten lokalen Variablen zu, nämlich String str1="baseStr01";

9: ldc #3: Laden Sie das dritte Element („baseStr01“) im Konstantenpool in den Stapel.

11: astore 4: Weisen Sie die Referenz in 9 der vierten lokalen Variablen zu: String str2="baseStr01";

Ergebnis #3: str1==str2 wird definitiv true zurückgeben, weil beides str1 und str2 verweisen auf dieselbe Referenzadresse im Konstantenpool. Tatsächlich wird nach JAVA 1.6 die „+“-Operation einer konstanten Zeichenfolge während der Kompilierungsphase direkt in eine Zeichenfolge synthetisiert.

13: neu           #4: Generieren Sie eine Instanz von StringBuilder.

16: dup: Kopieren Sie die Referenz des von 13 generierten Objekts und schieben Sie es auf den Stapel.

17: invokespecial #5: Rufen Sie das fünfte Element im Konstantenpool auf, die StringBuilder.

Die oben genannten drei Anweisungen werden verwendet, um ein StringBuilder-Objekt zu generieren.

20: aload_1 : Laden Sie den Wert des ersten Parameters, der „baseStr“ ist.

21: invokevirtual #6: Rufen Sie die Append-Methode des StringBuilder-Objekts auf.

24: ldc #7: Laden Sie das siebte Element („01“) im Konstantenpool in den Stapel.

26: invokevirtual #6: Rufen Sie die StringBuilder.append-Methode auf.

29: invokevirtual #8: Rufen Sie die StringBuilder.toString-Methode auf.

32: astore 5: Ändern Sie die Ergebnisreferenzzuweisung in 29 auf die fünfte lokale Variable, also die Zuweisung zur Variablen str3.

Ergebnis #4: Da str3 tatsächlich das von stringBuilder.append() generierte Ergebnis ist, ist es nicht gleich str1 und das Ergebnis gibt false zurück.

34: ldc #3: Laden Sie das dritte Element („baseStr01“) im Konstantenpool in den Stapel.

36: astore 6: Weisen Sie die Referenz in 34 der sechsten lokalen Variablen zu, also str4="baseStr01";

Ergebnis Nr. 5: Weil str1 und str4 auf Konstanten verweisen Der dritte Element im Pool, daher gibt str1==str4 true zurück. Hier können wir auch ein Phänomen feststellen, bei dem die ständige Ersetzung direkt zur Kompilierungszeit durchgeführt wird, während bei nicht endgültigen Feldern die Zuweisungsverarbeitung zur Laufzeit erfolgt.

38: neu #9: Erstellen Sie ein String-Objekt

41: dup: Kopieren Sie die Referenz und verschieben Sie sie auf den Stapel.

42: ldc #3: Laden Sie das dritte Element („baseStr01“) im Konstantenpool in den Stapel.

44: invokespecial #10: Rufen Sie die Methode „String““ auf und übergeben Sie die Referenz in Schritt 42 als Parameter an die Methode.

47: invokevirtual #11: Rufen Sie die String.intern-Methode auf.

Der entsprechende Quellcode von 38 bis 41 ist new String(“baseStr01″).intern().

50: astore 7: Weisen Sie das in Schritt 47 zurückgegebene Ergebnis der Variablen 7 zu, dh str5 zeigt auf die Position von baseStr01 im Konstantenpool.

Ergebnis Nr. 6: Da sowohl str5 als auch str1 auf dieselbe Zeichenfolge im Konstantenpool verweisen, gibt str1==str5 „true“ zurück.

Führen Sie Codesegment zwei aus. Das Ausgabeergebnis lautet wie folgt:

Eingehende Analyse der intern()-Methode in Java

3. Analyse von Codesegment drei:

Für Codesegment drei gibt es unterschiedliche Ausführungsergebnisse in JDK 1.6 und JDK 1.7. Schauen wir uns zunächst die Laufergebnisse an und erklären dann die Gründe:

Laufergebnisse unter JDK 1.6:

Eingehende Analyse der intern()-Methode in Java

Laufergebnisse unter JDK 1.7:

Eingehende Analyse der intern()-Methode in Java

Laut der Analyse von Codesegment 1 sollte es einfach sein, das Ergebnis von JDK 1.6 zu erhalten, da str2 und str1 ursprünglich auf unterschiedliche Orte verweisen und false zurückgeben sollten.

Das seltsame Problem ist, dass nach JDK 1.7 im ersten Fall „true“ zurückgegeben wird, nach einer Änderung der Position das zurückgegebene Ergebnis jedoch „false“ wird. Der Hauptgrund dafür ist, dass HotSpot nach JDK 1.7 den Konstantenpool von der permanenten Generation in den Metaspace verschoben hat. Aus diesem Grund hat die interne Methode nach JDK 1.7 relativ große Änderungen in der Implementierung erfahren Gehen Sie immer noch zu , um abzufragen, ob bereits im Konstantenpool vorhanden ist. Der Unterschied besteht darin, dass die entsprechende Zeichenfolge vorhanden ist nicht im Konstantenpool gefunden werden kann, wird die Zeichenfolge nicht mehr in den Konstantenpool kopiert, sondern im Konstantenpool ein Verweis auf die Originalzeichenfolge generiert. Also:

Ergebnis Nr. 7: Im ersten Fall wird im Konstantenpool ein Verweis auf „str01“ im Heap generiert, da im Konstantenpool keine Zeichenfolge „str01“ vorhanden ist Bei der Literalzuweisung ist der Konstantenpool bereits vorhanden, sodass die Referenz direkt zurückgegeben werden kann. Daher verweisen str1 und str2 beide auf die Zeichenfolge im Heap und geben „true“ zurück.

Ergebnis Nr. 8: Da der Konstantenpool bei der Literalzuweisung nicht vorhanden ist (String str1 = „str01“), zeigt str1 auf die Position im Konstantenpool und str2 auf den Heap Die interne Methode wird für das Objekt in verwendet. Sie hat keine Auswirkung auf str1 und str2, daher wird false zurückgegeben.

[Verwandte Empfehlungen]

1. Kostenloses Java-Video-Tutorial

2. Zusammenfassung der Erfahrungen mit der intern()-Methode in JAVA

3. Was ist das Konzept der intern-Methode in Java

4. Analysieren Sie die Rolle von intern() in Java

5. Detaillierte Erklärung von intern() im String-Objekt

Das obige ist der detaillierte Inhalt vonEingehende Analyse der intern()-Methode in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Quadratwurzel in Java Quadratwurzel in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Quadratwurzel in Java. Hier diskutieren wir anhand eines Beispiels und seiner Code-Implementierung, wie Quadratwurzel in Java funktioniert.

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Zufallszahlengenerator in Java Zufallszahlengenerator in Java Aug 30, 2024 pm 04:27 PM

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

Armstrong-Zahl in Java Armstrong-Zahl in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Armstrong-Zahl in Java. Hier besprechen wir eine Einführung in die Armstrong-Zahl in Java zusammen mit einem Teil des Codes.

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

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

See all articles