Ich weiß String-Pool in JVM und Unterschiede zwischen Literalen und String-Objekten . Ich weiß, dass Literale automatisch interniert werden, aber was ist der Zweck dieser Zeile dann:
%Vor% Auf meine Frage finde ich immer eine Menge Text, der mich mit dem Unterschied zwischen Literalen und Objekten gleichsetzt und die bereits internierten Literale erwähnt. Daher würde ich gerne wissen, wie man diese knifflige Zeile mit intern()
über Literal verwendet.
Der Hauptvorteil dieses Codetyps besteht darin, zu verhindern, dass Kompilierzeitkonstanten inline werden.
Angenommen, Sie haben eine Konstante in einer Klasse und viele andere Klassen verweisen auf diese Konstante. Wenn Sie den konstanten Wert ändern, müssen Sie normalerweise alle beteiligten Klassen neu kompilieren. Die Verwendung von intern()
für das Feld verhindert das Inlining der Konstanten und bedeutet, dass es ausreichend wäre, nur Ihre konstante Klasse neu zu kompilieren. Theoretisch hätte dieser Ansatz eine schlechtere Leistung, obwohl ich keine Ahnung habe, wie bedeutend das sein könnte.
Diese SO-Frage deckt das gleiche Thema ab und ist eine nützliche Lektüre.
Der einzige Anwendungsfall, den ich mir vorstellen kann, ist zu verhindern, dass als Kompilierzeitkonstante betrachtet wird, so dass Inlining verhindert wird.
Nun kann ein Grund dafür sein, dass jemand den Wert mithilfe von Reflection ändern kann, was nur funktioniert, wenn die Zeichenfolge wie folgt deklariert wird.
Außerdem können Sie die Klassendatei ändern, die eine Konstante enthält, wie von @Duncan in seiner Antwort angegeben. Das ist auch ein guter Grund.
Wenn Sie String
als public static final String CONST = "abc";
deklarieren, handelt es sich um eine Zeitkonstante für die Kompilierung, die in der Klasse mit dieser Konstante eingebunden wird.
Nach dem Kompilieren finden Sie
, wenn Sie die Klasse dekompilieren %Vor% Wenn Sie es jedoch mit .intern()
oder einer anderen Methode deklarieren, kann es nicht als Kompilierzeitkonstante und jedes Mal, wenn der Wert aus der Klasse abgerufen wird, betrachtet werden. Java macht das effizient.
Beispiel aus @ Markos Kommentar:
Die SWT-Bibliothek verwendet einen ähnlichen Trick, um das Inlinen von int zu stoppen Konstanten, und der einzige Grund ist, in Bezug auf Aktualisieren der SWT-Bibliothek
Java automatisch Praktikanten Stringliterale. Dies bedeutet, dass der Operator == in vielen Fällen für Strings auf die gleiche Weise funktioniert wie für Ints oder andere primitive Werte.
Da das Interning für String-Literale automatisch ist, sollte die Methode intern()
für Strings verwendet werden, die mit new String()
Verwenden Sie Ihr Beispiel:
%Vor%gibt zurück:
%Vor%Erklärung in einfachen Worten:
- & gt; In String pooled region
Wenn wir annehmen, haben wir "Shoaib" als String, dessen Referenz lautet 2020
- & gt; Jetzt Jedes Objekt, das Sie mit new String("Shoaib")
erstellen, zeigt auf eine andere Referenz, zB 3030
- & gt; Wenn Sie jedoch reference
von "Shoaib" in der Poolregion "String" auf new String("Shoaib")
zuweisen möchten, verwenden wir intern ().
Also oben haben Sie gefragt, dass "value" .intern () was im Falle eines Praktikums keinen Sinn macht.
Der intern () wird verwendet, um auf die Referenz-ID Ihres String-Konstantenpools zuzugreifen.
Es ist möglich, dass Ihre Variable denselben Wert enthält, so dass wir sie nicht erneut zuordnen müssen.
Wir verwenden nur intern (), um zu überprüfen, ob es bereits in String Constant Pool ist oder nicht?
Wenn es nicht im Pool ist, dann wird nur JVM im Poolbereich zugeordnet und es wird die Referenz-ID & amp; Wir haben das gleiche Datenelement gemeinsam genutzt und profitieren davon, dass wir denselben Speicher verwenden.
Der Zweck dieser Zeile
%Vor%wird nur verwendet, um aus dem String-Konstantenpool zu überprüfen. Wenn es verfügbar ist, wird es zurückgegeben, nicht erneut im Pool hinzugefügt.