23.2 Java-Quellen übersetzen
Ein Java-Compiler übersetzt Java-Quellcode-Dateien in Bytecode. Das JDK liefert standardmäßig den Java-Compiler javac mit aus.
23.2.1 Der Java-Compiler des JDK
Der Compiler javac übersetzt den Quellcode einer Datei in Java-Bytecode. Jede in einer Datei deklarierte Klasse übersetzt der Compiler in eine eigene Klassendatei. Wenn bei einer Klasse (nennen wir sie A) eine Abhängigkeit zu einer anderen Klasse (nennen wir sie B) besteht – wenn zum Beispiel A von B erbt und B nicht als Bytecode-Datei vorliegt –, dann verarbeitet der Compiler B automatisch mit. Der Compiler überwacht also automatisch die Abhängigkeiten der Quelldateien. Der allgemeine Aufruf des Compilers ist:
$ javac [ Optionen ] Dateiname(n).java
23.2.2 Alternative Compiler
Neben dem Java-Compiler des JDK gibt es weitere Compiler, die Java-Quellcode in Bytecode abbilden, doch sie haben keine große Bedeutung, da javac frei ist und einfach die »Referenz« bildet. Die Entwicklungsumgebung Eclipse nutzt einen eigenen Java-Compiler (EJC), um flexibel zu sein und einfach während des Speichers und Tippens schon Teile übersetzen zu können.
Wie auch javac ist der Eclipse-Compiler selbst in Java implementiert und generiert Bytecode[ 285 ](Natürlich gibt es da ein Henne-Ei-Problem: Wie sollte ein neuer in Java geschriebener Compiler durch Java übersetzt werden? Daher entsteht der erste Compiler immer in einer anderen Sprache, und die übersetzt eine kleine Teilmenge der Zielsprache, und dann wird ein neuer Compiler in der Minisprache entwickelt. Im nächsten Schritt wachsen und vergrößern sich Grammatik und Compiler. In der Sprache der Compilerbauer heißt der Prozess Bootstrapping. Bei Java war das ein Prozess über mehrere Stufen. Patrick Naughton schreibt im Buch »The Java Handbook« dazu: »Arthur van Hoff rewrote the compiler in Oak itself, replacing the C version that James originally wrote.« Und aus Oak wurde später Java. ). Es gibt aber auch Java-Compiler in C(++), wie den GNU Compiler for Java (gcj)[ 286 ](https://web.archive.org/web/20120219133307/http://gcc.gnu.org/java/) oder den Jikes-Compiler[ 287 ](http://tutego.de/go/jikes), doch die beiden letzten Projekte wurden lange nicht aktualisiert und spielen praktisch keine Rolle mehr.
23.2.3 Native Compiler
Eine in Java geschriebene Applikation lässt sich erst einmal nur mit einer Java-Laufzeitumgebung ausführen. Einige Hersteller haben jedoch Compiler entwickelt, die direkt unter Windows oder einem anderen Betriebssystem ausführbare Programme erstellen. Die Compiler, die aus Java-Quelltext – oder Java-Bytecode – Maschinencode der jeweiligen Architektur erzeugen, nennen sich native oder Ahead-of-time-Compiler (kurz AOT). Das Ergebnis ist eine direkt ausführbare Datei, die keine Java-Laufzeitumgebung nötig macht. Je nach Anwendungsfall kann das Programm performanter sein, eine Garantie dafür gibt es allerdings nicht. Die Startzeiten sind im Allgemeinen geringer, und das Programm ist viel schwieriger zu entschlüsseln, was das Reverse Engineering[ 288 ](Das Zurückverwandeln von unstrukturiertem Binärcode in Quellcode ) angeht.
Existierende Laufzeitumgebungen erreichen mittlerweile eine ausreichende Geschwindigkeit, einen vertretbaren Speicherverbrauch und annehmbare Startzeiten. Um die Startzeiten noch weiter zu reduzieren, bietet die GraalVM Native Image an, ein natives Image zu erzeugen. Details zu dem Projekt bietet http://www.graalvm.org/docs/reference-manual/native-image/.