web-dev-qa-db-de.com

Wie genau erfolgt die Java Kompilierung?

Verwirrt durch den Java Kompilierungsprozess

OK, ich weiß das: Wir schreiben Java Quellcode, der Compiler, der plattformunabhängig ist, übersetzt ihn in Bytecode, und der JVM, der plattformabhängig ist, übersetzt ihn in Maschinencode.

Also schreiben wir von Anfang an Java Quellcode. Der Compiler javac.exe ist eine .exe-Datei. Was genau ist das .exe-Datei? Ist der Java - Compiler nicht in Java geschrieben? Wenn der Compiler-Code in Java geschrieben ist, wird der Compiler-Code in der Kompilierungsphase ausgeführt, da es die Aufgabe der JVM ist, Java Code auszuführen. Wie kann eine Sprache selbst einen eigenen Sprachcode kompilieren? Mir kommt alles wie ein Hühnchen- und Eierproblem vor.

Was genau enthält die .class-Datei? Handelt es sich um einen abstrakten Syntaxbaum in Textform, handelt es sich um tabellarische Informationen, was ist das?

kann mir jemand klar und detailliert sagen, wie mein Java Quellcode in Maschinencode konvertiert wird?.

58
nash

OK, ich weiß das: Wir schreiben Java Quellcode, der Compiler, der plattformunabhängig ist, übersetzt ihn in Bytecode.

Tatsächlich ist der Compiler selbst funktioniert als native ausführbare Datei (daher javac.exe). Und wahr, es wandelt die Quelldatei in Bytecode um. Der Bytecode ist plattformunabhängig, da er auf Java Virtual Machine abzielt.

dann übersetzt die jvm, die plattformabhängig ist, sie in Maschinencode.

Nicht immer. Für Suns JVM gibt es zwei JVMS: Client und Server. Beide können, müssen aber nicht unbedingt zu nativem Code kompiliert werden.

Also schreiben wir von Anfang an Java Quellcode. Der Compiler javac.exe ist eine .exe-Datei. Was genau ist das .exe-Datei? Ist der Java - Compiler nicht in Java geschrieben? Wie kommt es, dass es eine .exe-Datei gibt, die ihn ausführt?

Diese exe - Datei ist ein umbrochener Java Bytecode. Dies dient der Bequemlichkeit - um komplizierte Batch-Skripte zu vermeiden. Es startet eine JVM und führt den Compiler aus.

Wenn der Compiler-Code in Java geschrieben ist, wird der Compiler-Code in der Kompilierungsphase ausgeführt, da es die Aufgabe der JVM ist, Java Code auszuführen.

Genau das macht der Wrapping-Code.

Wie kann eine Sprache selbst einen eigenen Sprachcode kompilieren? Mir kommt alles wie ein Hühnchen- und Eierproblem vor.

Richtig, auf den ersten Blick verwirrend. Es ist jedoch nicht nur Javas Redewendung. Der Compiler der Ada ist auch in Ada selbst geschrieben. Es mag wie ein "Huhn und Ei Problem" aussehen, aber in Wahrheit ist es nur ein Bootstrapping Problem.

Was genau enthält die .class-Datei? Handelt es sich um einen abstrakten Syntaxbaum in Textform, handelt es sich um tabellarische Informationen, was ist das?

Es ist kein abstrakter Syntaxbaum. AST wird nur von Tokenizer und Compiler zur Kompilierungszeit verwendet, um den Code im Speicher darzustellen. Die Datei .class Ist wie eine Assembly, nur für JVM. JVM ist wiederum eine abstrakte Maschine, auf der eine spezielle Maschinensprache ausgeführt werden kann, die nur auf virtuelle Maschinen abzielt. Im einfachsten Fall hat die Datei .class Eine sehr ähnliche Struktur wie die normale Assembly. Am Anfang werden alle statischen Variablen deklariert, dann kommen einige Tabellen mit externen Funktionssignaturen und zuletzt der Maschinencode.

Wenn Sie wirklich neugierig sind, können Sie mit dem Dienstprogramm "javap" in die Klassendatei eintauchen. Hier ist eine (verschleierte) Beispielausgabe des Aufrufs von javap -c Main:

0:   new #2; //class SomeObject
3:   dup
4:   invokespecial   #3; //Method SomeObject."<init>":()V
7:   astore_1
8:   aload_1
9:   invokevirtual   #4; //Method SomeObject.doSomething:()V
12:  return

Du solltest also schon eine Idee haben, was es wirklich ist.

kann mir jemand klar und detailliert sagen, wie mein Java Quellcode in Maschinencode konvertiert wird?.

Ich denke, es sollte jetzt klarer sein, aber hier ist eine kurze Zusammenfassung:

  • Sie rufen javac auf, das auf Ihre Quellcodedatei verweist. Das interne reader (oder Tokenizer) von javac liest Ihre Datei und erstellt daraus ein tatsächliches AST. Alle Syntaxfehler stammen aus dieser Phase.

  • Die javac hat ihren Job noch nicht beendet. Wenn es das AST hat, kann die eigentliche Kompilierung beginnen. Es verwendet ein Besuchermuster zum Durchlaufen von AST und löst externe Abhängigkeiten auf, um dem Code eine Bedeutung (Semantik) hinzuzufügen. Das fertige Produkt wird als .class - Datei mit Bytecode gespeichert.

  • Jetzt ist es Zeit, das Ding zu leiten. Sie rufen Java mit dem Namen der .class-Datei auf. Jetzt startet die JVM erneut, aber um interpretieren Ihren Code. Die JVM kann Ihren abstrakten Bytecode in die native Assembly kompilieren oder nicht. Der HotSpot-Compiler von Sun in Verbindung mit der Just-In-Time-Kompilierung kann dies bei Bedarf tun. Der ausgeführte Code wird ständig von der JVM profiliert und bei Einhaltung bestimmter Regeln in systemeigenen Code neu kompiliert. Am häufigsten wird der hot Code als erster nativ kompiliert.

Edit: Ohne die javac müsste man den Compiler mit etwas ähnlichem aufrufen:

%JDK_HOME%/bin/Java.exe -cp:myclasspath com.Sun.tools.javac.Main fileToCompile

Wie Sie sehen, ruft es die private API von Sun auf, sodass es an die Sun JDK-Implementierung gebunden ist. Es würde Build-Systeme davon abhängig machen. Wenn zu einem anderen JDK gewechselt wird (Wikilisten 5 außer Suns), sollte der obige Code aktualisiert werden, um die Änderung widerzuspiegeln (da es unwahrscheinlich ist, dass sich der Compiler im com.Sun.tools.javac-Paket befindet). Andere Compiler könnten in nativem Code geschrieben sein.

Standardmäßig wird der Wrapper javac mit JDK ausgeliefert.

59
Rekin

Ist der Java Compiler nicht in Java geschrieben, warum gibt es dann eine .exe-Datei, die ihn ausführt?

Woher beziehen Sie diese Informationen? Die ausführbare Datei javac kann in jeder Programmiersprache geschrieben werden. Es ist irrelevant. Wichtig ist nur, dass es sich um eine ausführbare Datei handelt, die .Java Dateien in .class Dateien.

Einzelheiten zur Binärspezifikation einer .class-Datei finden Sie in den folgenden Abschnitten: Java Language Specification nützlich (wenn auch möglicherweise ein wenig technisch):

Sie können sich auch die Virtual Machine Specification ansehen, die Folgendes abdeckt:

16
matt b

Der Compiler javac.exe ist eine .exe-Datei. Was genau ist das .exe-Datei? Ist der Java Compiler nicht in Java geschrieben, warum gibt es dann eine .exe-Datei, die ihn ausführt?

Der Java Compiler (zumindest der mit dem Sun/Oracle JDK gelieferte) ist in der Tat in Java geschrieben. javac.exe ist nur ein Startprogramm, das die Befehlszeilenargumente verarbeitet, von denen einige an die JVM weitergeleitet werden, die den Compiler ausführt, und andere an den Compiler selbst.

Wenn der Compiler-Code in Java geschrieben ist, wird der Compiler-Code in der Kompilierungsphase ausgeführt, da es die Aufgabe des JVM ist, Java code. Wie kann eine Sprache selbst kompilieren? Sprachcode? Mir kommt das alles wie ein Hühnchen- und Ei-Problem vor.

Viele (wenn nicht die meisten) Compiler sind in der Sprache geschrieben, die sie kompilieren. Offensichtlich musste der Compiler zu einem frühen Zeitpunkt von etwas anderem kompiliert werden, aber nach diesem "Bootstrapping" kann jede neue Version des Compilers von einer älteren Version kompiliert werden.

Was genau enthält die .class-Datei? Handelt es sich um einen abstrakten Syntaxbaum in Textform, handelt es sich um tabellarische Informationen, was ist das?

Die Details des Klassendateiformats sind in der Java Virtual Machine-Spezifikation beschrieben.

11

Nun, Javac und JVM sind in der Regel native Binärdateien. Sie sind in C oder was auch immer geschrieben. Es ist sicherlich möglich, sie in Java zu schreiben, nur dass Sie zuerst eine native Version benötigen. Dies wird als "Boot-Strapping" bezeichnet.

Unterhaltsame Tatsache: Die meisten Compiler, die mit nativem Code kompiliert werden, sind in ihrer eigenen Sprache geschrieben. Allerdings mussten alle zuerst eine native Version in einer anderen Sprache (normalerweise C) haben. Im Vergleich dazu wurde der erste C-Compiler in Assembler geschrieben. Ich gehe davon aus, dass der erste Assembler in Maschinencode geschrieben wurde. (Oder mit Schmetterlingen ;)

.class-Dateien sind von javac generierter Bytecode. Sie sind keine Textdateien, sondern Binärcodes, die dem Maschinencode ähneln (jedoch mit einem anderen Befehlssatz und einer anderen Architektur).

Die JVM hat zur Laufzeit zwei Optionen: Sie kann den Bytecode entweder interpretieren (als CPU ausgeben) oder JIT (just-in-time) in systemeigenen Maschinencode kompilieren. Letzteres ist natürlich schneller, aber komplexer.

5
Mike Caron

Die .class-Datei enthält Bytecode, der einer Art sehr High-Level-Assembly ähnelt. Der Compiler könnte sehr gut in Java geschrieben sein, aber die JVM müsste zu nativem Code kompiliert werden, um das Henne/Ei-Problem zu vermeiden. Ich glaube, es ist in C geschrieben, ebenso wie die unteren Ebenen der Standardbibliotheken. Wenn die JVM ausgeführt wird, führt sie eine Just-in-Time-Kompilierung durch, um diesen Bytecode in native Anweisungen umzuwandeln.

3
ZoFreX

Kurze Erklärung

Schreiben Sie Code in einen Texteditor und speichern Sie ihn in einem Format, das der Compiler versteht - ". Java" Dateierweiterung, javac (Java-Compiler) konvertiert dies in " .class " Formatdatei (Bytecode - Klassendatei). JVM führt die .class-Datei auf dem Betriebssystem aus, auf dem sie installiert ist.

Lange Erklärung

Denken Sie immer daran, dass Java nicht die vom Betriebssystem erkannte Basissprache ist. Java Der Quellcode wird vom Übersetzer Java Virtual) für das Betriebssystem interpretiert Machine (JVM. JVM kann den Code, den Sie in einem Editor schreiben, nicht verstehen, er benötigt kompilierten Code. Hier kommt ein Compiler ins Spiel.

Jeder Computerprozess ist mit einer Manipulation des Speichers befasst. Wir können nicht einfach Code in einen Texteditor schreiben und diesen kompilieren. Wir müssen es im Speicher des Computers ablegen, d. H. Es vor dem Kompilieren speichern.

Wie erkennt der Javac (Java-Compiler) den gespeicherten Text als den zu kompilierenden? - Wir haben ein separates Textformat, das der Compiler erkennt, d. H. . Java. Speichern Sie die Datei in der Erweiterung .Java, und der Compiler erkennt sie und kompiliert sie, wenn Sie dazu aufgefordert werden.

Was passiert beim Kompilieren? - Der Compiler ist ein zweiter Übersetzer (kein Fachbegriff), der in den Prozess involviert ist. Er übersetzt die vom Benutzer verstandene Sprache (Java) in die von JVM verstandene Sprache (Bytecode - .class-Format).

Was passiert nach dem Kompilieren? - Der Compiler erzeugt eine .class-Datei, die JVM versteht. Das Programm wird dann ausgeführt, d. H. Die .class-Datei wird von JVM auf dem Betriebssystem ausgeführt.

Fakten, die Sie kennen sollten

1) Java ist nicht plattformunabhängig es ist plattformunabhängig.

2) JVM wird mit C/C++ entwickelt. Einer der Gründe, warum Leute Java eine langsamere Sprache als C/C++ nennen

3) Java Bytecode (.class) ist in "Assemblersprache", der einzigen Sprache, die von JVM verstanden wird. Jeder Code, der beim Kompilieren oder Generieren eine .class-Datei erzeugt Auf der JVM kann Bytecode ausgeführt werden.

2

Windows kann Java vor der Installation einer Java) - Laufzeit nicht aufrufen, und Sun entschied sich für native Befehle, die Argumente sammeln und stattdessen die JVM aufrufen des Bindens des JAR-Suffixes an die Java Engine.