Ich habe den folgenden Testcode:
%Vor%Der generierte Bytecode ist:
%Vor% In testPrefix()
wird der Ausdruck "a" + "b" vom Java-Compiler in das String-Literal "ab" kombiniert, aber in testSuffix()
wird der Ausdruck "c" + "d" nicht zu kombiniert Kompilierzeit.
Warum kann der Compiler die String-Literale nicht in der zweiten Methode kombinieren? Die Quelldatei wurde mit dem Standard Oracle JDK 8 javac kompiliert.
Weil der String-Verkettungsoperator (+) ist syntaktisch links assoziativ :
Zum Beispiel der Ausdruck:
%Vor%wird immer als Bedeutung betrachtet:
%Vor%
Zugegeben, wenn b
und c
Strings sind, entspricht der Ausdruck a + (b + c)
. So könnte ein Compiler das tun, was Sie in dieser speziellen Situation vorschlagen , aber es ist nicht durch die Spezifikation vorgeschrieben ...
Das ist keine gute Antwort.
Die Reihenfolge der Addition ist definiert und erfolgt von links.
Dies:
%Vor%Hat Ausgabe erwartet
%Vor%Ich vermute also, dass der Compiler erkennt, dass Literal plus Literal auf "langes Literal" optimiert werden kann, erkennt aber nicht, dass das Umordnen der Operationen das gleiche Ergebnis hätte, so dass der ausführliche Code erzeugt wird.
entspricht
%Vor%Sie könnten argumentieren, dass es diesem Ausdruck entspricht
%Vor%wird für
optimiert %Vor%Ich denke, dies ist der Grund, warum der Byte-Code diese Optimierung nicht enthält. Sprachspezifikation (15.18.1. String Concatenation Operator +) :
Das String-Objekt wird neu erstellt (§12.5), es sei denn, der Ausdruck ist ein konstanter Ausdruck (§15.28).
Mit anderen Worten, (i + "c")
muss eine neue Zeichenfolge sein, und (i + "c") + "d"
muss wieder eine neue Zeichenfolge sein.
Allerdings könnte ein JIT-Compiler die Optimierung intern anwenden, da er die beobachtbare Semantik nicht ändert.
Tags und Links java