Statische Initialisierung durch JVM

8

Sprache: Java-
Version: 12.0.2
String-Quellcode wie folgt:

 /* @implNote
 * The actual value for this field is injected by JVM. The static
 * initialization block is used to set the value here to communicate
 * that this static final field is not statically foldable, and to
 * avoid any possible circular dependency during vm initialization.
 */
static final boolean COMPACT_STRINGS;

static {
    COMPACT_STRINGS = true;
}

So verstehen Sie diesen Satz: 'Der statische Initialisierungsblock wird verwendet, um den Wert hier festzulegen, um zu kommunizieren, dass dieses statische Endfeld nicht statisch faltbar ist, und um mögliche zirkuläre Abhängigkeiten während der VM-Initialisierung zu vermeiden.'

Xiu
quelle
Gute Frage! Dies kann ein Anfang sein: en.wikipedia.org/wiki/Constant_folding Aber ich habe keine Ahnung von "zirkulärer Abhängigkeit während der VM-Initialisierung".
Alex 75
@Alex 75 In meiner Idee, wenn sie so geschrieben hätten: 'static final boolean COMPACT_STRINGS = true'. Eine mögliche zirkuläre Abhängigkeit kann weiterhin vermieden werden, da 'COMPACT_STRINGS' einen bestimmten Wert zugewiesen wurde. Aber es konnte nicht vermeiden, statisch faltbar zu sein.
Xiu

Antworten:

7

Dies ist ein Implementierungshinweis für JVM-Implementierer. Es ist nicht Teil der öffentlichen Dokumentation und kein Problem für Entwickler, die es verwenden java.lang.String.

Aber wenn Sie wissen wollen:

Stellen Sie sich vor, sie hätten geschrieben:

static final boolean COMPACT_STRINGS = true;

Dann wäre es eine Konstante gewesen, dass der Compiler sie trueüberall COMPACT_STRINGSdort durch den Wert ersetzen könnte, wo sie verwendet wurde (nur im java.langPaket, da es sich um eine paketlokale Variable mit Gültigkeitsbereich handelt).

Durch die Angabe des Werts truein einem statischen Initialisierer weiß der Compiler nicht mehr, dass es sich um eine Konstante handelt, und der gesamte Code, der sie verwendet, muss den tatsächlichen Wert zur Laufzeit nachschlagen.

In diesem Fall ist dies nützlich, da die JVM diesen Wert zur Laufzeit ändert (obwohl finaldie JVM ihn dennoch ändern kann), wie im Implementierungshinweis erwähnt.

Erwin Bolwidt
quelle
Können Sie den Teil erklären, even though it's final, the JVM can still change itwarum JVM ihn ändern kann? Ich war verwirrt darüber, wie JVM es schafft, konstante Variablen zu ändern.
Francis stellen Frage
1
@Francisaskquestion Es ist die JVM, die es endgültig macht, und es kann die Regeln brechen, die es für die Anwendung festlegt.
user207421
@ user207421 ahh dann mit etwas Wissen über JVM, kann es auch andere Variablen ändern?
Francis stellen Frage
1
Die JVM kann es tun. Es kann Tricks geben, die Reflektion und / oder unsicheren Zugriff verwenden und in aktuellen JVMs funktionieren, die es einer Anwendung ermöglichen, dies zu tun, aber diese funktionieren möglicherweise (und werden wahrscheinlich die Anweisungen von Oracle berücksichtigen) in zukünftigen Versionen der JVM nicht mehr.
Erwin Bolwidt
1
@Francisaskquestion Die JVM kann machen, was sie will.
user207421