Definition

Java-Compiler

Was ist ein Java-Compiler?

Ein Java-Compiler ist ein Programm, das die Arbeit eines Entwicklers an einer Textdatei in eine plattformunabhängige Java-Datei kompiliert. Zu den Java-Compilern gehören der Java Programming Language Compiler (javac), der GNU Compiler für Java (GCJ), der Eclipse Compiler für Java (ECJ) und Jikes.

Programmierer schreiben die Anweisungen in einer bestimmten Programmiersprache in der Regel Zeile für Zeile mit einem Code-Editor oder einer integrierten Entwicklungsumgebung (IDE). Die resultierende Datei enthält die so genannten Quelltextanweisungen. Der Programmierer führt dann einen Compiler für die entsprechende Sprache aus und gibt den Namen der Datei an, die die Quelltextanweisungen enthält.

Java und Java-Programmierer bilden hier keine Ausnahme. Der Java-Compiler akzeptiert Java-Quellcode auf hoher Ebene und wandelt ihn in Bytecode um, der von einer Java Virtual Machine (JVM) verstanden werden kann, um die gewünschten Ergebnisse zu erzielen.

Zur Laufzeit parst (analysiert) der Compiler alle Sprachanweisungen syntaktisch und erstellt dann in einem oder mehreren aufeinanderfolgenden Schritten oder Durchläufen den Ausgabecode, wobei er sicherstellt, dass Anweisungen, die sich auf andere Anweisungen beziehen, im endgültigen Code korrekt referenziert werden.

Im Allgemeinen werden Java-Compiler ausgeführt und verweisen auf den Code eines Programmierers in einer Textdatei, um eine Klassendatei zur Verwendung durch die JVM auf verschiedenen Plattformen zu erzeugen. Jikes zum Beispiel ist ein Open Source Compiler, der auf diese Weise arbeitet, ebenso wie der primäre Compiler des Java Development Kit (JDK) namens javac. Dieser in Java geschriebene Compiler liest in Java geschriebene Klassen- und Schnittstellendefinitionen und wandelt sie wie Jikes in Bytecode-Klassendateien um.

Um den Java-Compiler auszuführen, muss der Programmierer den Befehl Javac.exe von der Eingabeaufforderung aus starten. Der Compiler ist wie Java plattformunabhängig, das heißt er kann Code kompilieren und ihn dann auf jedem Betriebssystem ausführen. Er ist jedoch sprachspezifisch, das heißt er kann nicht zum Kompilieren und Konvertieren von Quellcode verwendet werden, der in anderen Sprachen wie zum Beispiel Python oder C++ geschrieben wurde.

Abbildung 1: Zu den typischen Compiler-Schritten gehören die lexikalische Analyse, die Syntaxanalyse, die Erzeugung von IR-Code, die Optimierung und die Erzeugung von Ausgabecode.
Abbildung 1: Zu den typischen Compiler-Schritten gehören die lexikalische Analyse, die Syntaxanalyse, die Erzeugung von IR-Code, die Optimierung und die Erzeugung von Ausgabecode.

Was ist der Zweck eines Java-Compilers?

Der Hauptzweck eines Java-Compilers (oder eines Compilers in einer beliebigen Programmiersprache) besteht darin, den Java-Quellcode in eine Maschinencodedatei zu übersetzen, die aus maschinenlesbaren 0en und 1en besteht, und diese Datei dann auszuführen.

Die Kompilierung ist unerlässlich, weil die Maschine eine menschenlesbare Sprache wie Java nicht verstehen kann. Durch die Übersetzung von menschenlesbarem Code in maschinenlesbare Sprache stellt der Java-Compiler sicher, dass der Code ausgeführt wird und die erwartete Ausgabe erzeugt.

Ein Java-Compiler fungiert auch als Fehlererkennungsmechanismus von Java. Sobald er aktiviert ist, prüft er auf Syntaxfehler und erstellt eine Liste aller gefundenen Fehler. Er erzeugt keinen Objektcode, solange der Programmierer die Fehler nicht behebt. Der Compiler kann bei Bedarf auch zusätzlichen Code in das Programm einfügen.

Java-Compiler und Bytecode

Nach der Kompilierung des Quellcodes (einer .java-Datei) erzeugt der Compiler einen Zwischenobjektcode, den sogenannten Bytecode, der eine .class-Datei ist. Bytecode ist nicht dasselbe wie Maschinencode. Vielmehr handelt es sich um einen Binärcode, der von einer JVM auf dem zugrunde liegenden Betriebssystem verstanden und interpretiert werden kann. Da der Bytecode aus einer Reihe von 0en und 1en besteht, ist er nicht für Menschen lesbar oder verständlich. Um Bytecode zu erzeugen, benötigt der Compiler möglicherweise zusätzlichen Speicher.

Wie der Java-Compiler arbeitet

Der Programmierer schreibt den Java-Quellcode und führt dann einen Compiler wie javac aus. Der Compiler prüft, ob die Quelldatei vorhanden ist, und erzeugt Java-Bytecode (.class-Datei). Wenn die Quelldatei nicht gefunden wird, gibt er eine Fehlermeldung aus. Wenn die Quelldatei verfügbar ist und die Bytecode-Datei erzeugt wurde (was unabhängig vom Betriebssystem und der Prozessorarchitektur geschieht), wird die Bytecode-Datei automatisch auf der Festplatte gespeichert. Die JVM interpretiert und führt die Klassendatei zur Laufzeit auf dem zugrunde liegenden Betriebssystem aus.

Wenn der Compiler Fehler findet, erzeugt er eine Liste von Fehlermeldungen. Der Programmierer behebt die Fehler und führt den Compiler erneut aus, um das Programm neu zu kompilieren. Dieser Schritt ist wichtig, um den korrigierten, maschinenlesbaren Objektcode zu erzeugen. Wenn der Compiler keine Fehler findet, erzeugt er den erforderlichen Objektcode.

Optionen des Java-Compilers

Der javac-Compiler bietet zahlreiche Standardoptionen für Programmierer. Dazu gehören:

  • -version. Es werden Informationen über den Compiler angezeigt.
  • -help. Er gibt eine Zusammenfassung der Standardoptionen aus.
  • -nowarn. Schaltet Warnungen aus.
  • -g. Erzeugt Debugging-Informationen (Zeilennummer, Quelldateiinformationen, lokale Variablen).
  • -verbose. Erzeugt eine ausführliche Ausgabe, einschließlich Informationen über kompilierte Quelldateien und geladene Klassen.
  • -d directory. Ermöglicht es dem Programmierer, das Zielverzeichnis (das bereits existieren muss) für kompilierte Klassendateien festzulegen.
  • -deprecation. Es identifiziert zurückgezogene APIs.

Bei allen oben genannten Optionen wird die Groß- und Kleinschreibung beachtet.

Abbildung 2: Die Java Virtual Machine (JVM) interpretiert den Bytecode und wandelt ihn in Maschinensprache um, die plattformspezifisch ist.
Abbildung 2: Die Java Virtual Machine (JVM) interpretiert den Bytecode und wandelt ihn in Maschinensprache um, die plattformspezifisch ist.

Was ist ein Just-in-Time-Compiler?

Ein Just-in-Time-Compiler (JIT) ist im Lieferumfang der Java-VM enthalten. Seine Verwendung ist optional, und er wird auf dem plattformunabhängigen Code ausgeführt. Der JIT-Compiler übersetzt dann den Code in den Maschinencode für verschiedene Hardware, so dass er für verschiedene Architekturen optimiert ist. Sobald der Code vom JIT-Compiler (neu) kompiliert wurde, läuft er in der Regel schneller als der Java-Code, der nur eine Anweisung nach der anderen ausgeführt werden kann.

Java-Compiler versus Java-Interpreter

Java-Programmierer verwenden einen Java-Compiler und einen Interpreter. Beide sind in Hochsprachen wie Java unverzichtbar und spielen eine Rolle bei der Umwandlung von High-Level-Code in Low-Level-Maschinencode. Sie arbeiten jedoch unterschiedlich. Ein Compiler scannt den gesamten Quellcode in einem Durchgang und kombiniert alle Codedateien zu einem ausführbaren Programm (.exe-Datei). Anschließend führt er die gesamte Datei aus und prüft den Code auf Syntax- und andere Fehler. Wenn Fehler entdeckt werden, zeigt es alle Fehler- und Warnmeldungen an.

Sobald die Fehler behoben sind, kann der Compiler erneut ausgeführt werden, um die Fehlerbehebung zu bestätigen und die Codequalität zu überprüfen. Wenn der Compiler keine Fehler findet, wandelt er den Quellcode in Maschinencode um und erzeugt die gewünschten Ergebnisse.

Ein Interpreter hingegen führt die Programmieranweisungen im Quellcode Zeile für Zeile aus. Stellt er einen Fehler fest, markiert er ihn und hält die weitere Ausführung an. Erst wenn der Fehler behoben ist, wird er die Ausführung des Codes wieder aufnehmen. Einfach ausgedrückt, zeigt der Interpreter einen Fehler nach dem anderen an und wartet, bis jeder Fehler behoben ist, bevor er die Ausführung fortsetzt, während ein Compiler alle Fehler gleichzeitig anzeigt und die Ausführung fortsetzt, bis er das Ende der Quellcodedatei erreicht.

Ein weiterer Unterschied besteht darin, dass der Compiler länger braucht, um den Quellcode zu analysieren. Auch die Fehlersuche ist langsamer. Und das Programm wird erst ausgeführt, wenn alle Fehler behoben sind und es vollständig kompiliert wurde. Im Gegensatz dazu braucht ein Interpreter weniger Zeit, um den Code zu analysieren. Auch das Debuggen des Codes ist schneller, und das Programm wird Zeile für Zeile ausgeführt.

Diese Definition wurde zuletzt im April 2024 aktualisiert

Erfahren Sie mehr über Softwareentwicklung