2015-09-11 19 views
5

Ich bin gespannt, wie die staticfinal Felder von der JVM behandelt werden. Ich sah eine ähnliche Frage here, aber es ist nicht das, was ich suche. Lassen Sie uns solches Beispiel betrachten:letzte statische vs endgültige nicht statische Felder und JVM-Optimierung

public class TestClassX { 
    public final int CODE_A = 132; 
    public final int CODE_B = 948; 
    public final int CODE_C = 288; 
    // some other code 
} 

public class TestClassY { 
    public static final int CODE_A = 132; 
    public static final int CODE_B = 948; 
    public static final int CODE_C = 288; 
    // some other code 
} 

In TestClassX Felder, wie sie final sind und nicht geändert werden können, müssen die gleichen Werte in allen Instanzen der TestClassX Klasse. Natürlich kann ich nicht schreiben TestClassX.CODE_A aber ich kann sagen, dass diese Werte tatsächlich für alle Instanzen gemeinsam sind - ich bin sicher, dass jede Instanz ein CODE_A Feld mit dem Wert 132 hat. In der TestClassY kann ich die Syntax TestClassY.CODE_A verwenden, aber auf den ersten Blick ist es nur einfacher für einen Entwickler, der sieht "Oh, diese Werte sind für alle Instanzen üblich".

Meine Hauptfrage: Ich denke, dass JVM, bei TestClassX, verwendet keine zusätzlichen Speicher für final Felder jedes Mal, wenn eine neue Instanz erstellt wird. Macht es? Macht JVM in diesem Fall eine Optimierung und welche Art von Optimierung ist das?

Extra Frage 1) Ich bin mir auch sicher, dass mir hier etwas sehr Wichtiges fehlt, was die Ursache meiner Zweifel ist. Was ist das?

Zusätzliche Frage 2) Btw. Wie kann ich einen Blick darauf werfen, wie mein Java-Quellcode nach der JVM-Optimierung aussieht (damit ich in Zukunft darauf zurückgreifen kann;))? Unterstützt eine IDE eine solche Funktionalität? IntelliJ zum Beispiel? Ich möchte einfach sehen, wie JVM meine TestClassX und TestClassY behandelt.

+0

verwandte - javac inlines immer konstant Instanzvariablen, wahrscheinlich einen Fehler :) - https://groups.google.com/forum/#!topic/java-lang-fans/AyS3UqX4lj4 – ZhongYu

+0

2) Die Optimierungen JVM aren nicht auf eine Weise gemacht, die sich als Java-Quelle ausdrückt. Compiler optimieren eine interne Darstellung dessen, was der Code * tut *.Quellen-> Quellenoptimierer existieren normalerweise nur für Sprachen, die bei jeder Verwendung kompiliert werden müssen (z. B. Javascript). Ihr tatsächliches Ziel sollte hier durch einen Blick auf den Java-Byte-Code oder den Asm, der sich aus dem JIT-Kompilieren für eine bestimmte CPU ergibt, abgedeckt werden. (Oder traditionelle Vor-Kompilierung für Java-Implementierungen wie gcj.) –

Antwort

6
  • Nicht statische Felder sind immer in den Instanzen vorhanden. Sie speichern keine Erinnerung.
  • Im Allgemeinen optimiert JVM nicht statische Felder. Auch wenn sie endgültig sind, können sie durch Reflexion oder Deserialisierung immer noch auf einen anderen Wert eingestellt werden.
  • Es gibt eine experimentelle VM-Option -XX:+TrustFinalNonStaticFields (standardmäßig deaktiviert), die JVM anweist, den Zugriff auf solche Felder zu optimieren, d. H. Sie als Konstanten zu behandeln und Feldlasten zu eliminieren.
  • Es gibt eine -XX:+PrintAssembly VM-Option, um JIT-kompilierten Code zu speichern.
+0

Danke, dass Sie über Reflektion und Deserialisierung gesprochen haben . Und für TrustFinalNonStaticFields Option - ich wusste es nicht! ... ^ –

1

Für den ersten Teil Ihrer Frage, vielleicht this answer kann Ihnen helfen.

Für den zweiten Teil konnten Sie die generierte Baugruppe sehen (wie in this answer angegeben), indem Sie -XX:+PrintOptoAssembly Flag hinzufügen, wenn Sie Ihren Code ausführen/kompilieren.

Ich sollte auch hinzufügen, dass der Assembly-Code, der Ihnen gegeben ist, nicht der echte Opcode ist, der von der jvm erzeugt wird, sondern der Code, der unter Ihrer aktuellen Architektur ausgeführt werden muss.

Hoffe, das hilft!

+0

Entschuldigung, dass ich das nicht als Kommentar gepostet habe, aber ich habe nicht genug Reputation, um das zu tun ... –

Verwandte Themen