Ich habe an dem grundlegenden Java-Programm gearbeitet und ich fand sehr lustige Dinge, die ich mit euch teile. foo () gibt output (s == s1) = false und bar gibt (s == s1) = true.
Ich möchte wissen, warum das passiert.
%Vor%Im letzteren Fall optimiert der Compiler die String-Verkettung. Da dies zur Kompilierzeit erfolgen kann, verweisen beide auf das gleiche konstante String-Objekt.
Im ersten Fall kann der Aufruf length()
während der Kompilierzeit nicht optimiert werden. Zur Laufzeit wird ein neues String-Objekt erzeugt, das nicht identisch mit der String-Konstante ist (aber gleich ist)
Die String-Verkettung in bar()
kann zur Kompilierzeit durchgeführt werden, da es sich um einen Ausdruck handelt, der nur aus Kompilierzeitkonstanten besteht. Obwohl die Länge der Zeichenfolge s
zur Kompilierzeit offensichtlich bekannt ist, weiß der Compiler nicht, dass length()
diesen bekannten Wert zurückgibt, sodass er nicht als Konstante verwendet wird.
Wenn Sie eine Codezeile wie folgt schreiben:
%Vor%dann ist der Compiler schlau genug, um dies zu optimieren:
%Vor% Literale Strings in Java werden in einem String-Pool verwaltet. Wenn Sie zwei Literalzeichenfolgen mit demselben Inhalt haben (z. B. s
und s1
in Ihrem zweiten Beispiel), wird nur ein String
-Objekt erstellt, das von den beiden Variablen gemeinsam genutzt wird.
Der Operator ==
in Java überprüft, ob zwei Variablen auf dasselbe Objekt verweisen. Da es im zweiten Beispiel nur ein String
-Objekt gibt, ist s == s1
true
.
Wenn ich raten müsste, würde ich sagen, dass der Java-Compiler eine Optimierung auf bar () durchführt. Bei compiletime ist klar, dass "str" + "4" durch "str4" ersetzt werden kann, das (da Strings unveränderliche Objekte sind) tatsächlich dasselbe Objekt ist wie "str4" -String, das für die s-Initialisierung verwendet wird.
>Innerhalb von foo () ist die Optimierung nicht so stark vorwärts. Im Allgemeinen kann der Wert s1-Variable nicht sehr einfach vorhergesagt werden (in der Tat ist dieses Beispiel ziemlich genau). Also wird der Java-Compiler zwei verschiedene Variablen für s und s1 erzeugen.
Der Operator "==" vergleicht den Wert der Strings nicht! Es prüft, ob es sich um die gleichen Objekte handelt. Um die Werte der Strings zu vergleichen, verwenden Sie die Methode "equals" wie folgt:
%Vor%Sie sollten versuchen, mit der internen Methode der String-Klasse zu spielen. Java speichert so etwas wie ein Wörterbuch, in dem alle verschiedenen Zeichenfolgen gespeichert sind. Wenn Sie ein Zeichenfolgenobjekt erstellen, das zur Kompilierzeit ausgewertet werden kann, durchsucht es Java in seinem Wörterbuch. Wenn die Zeichenfolge gefunden wird, speichert sie nur eine Referenz auf diese Zeichenfolge (die tatsächlich von der internen Methode zurückgegeben wird).
Sie sollten Folgendes bemerken:
"str4" == ("str" + "str4".length())
gibt false zurück, aber
"str4" == ("str" + "str4".length()).intern()
gibt true zurück, weil der einzige "Wrapper" ein anderes Objekt ist.
Tags und Links java