Titel   Inhalt   Suchen   Index   API  Go To Java 2, Zweite Auflage, Handbuch der Java-Programmierung
 <<    <     >    >>  Kapitel 13 - Strukturierung von Java-Programmen

13.3 Der Entwicklungszyklus



13.3.1 Schematische Darstellung

Der Turn-around-Zyklus beim Entwickeln von Java-Programmen unterscheidet sich in mehrfacher Hinsicht von dem in traditionellen kompilierten Programmiersprachen.

Abbildung 13.1 zeigt den schematischen Ablauf bei der Entwicklung eines Java-Programms, das aus den Klassen A, B und C besteht.

Abbildung 13.1: Der Entwicklungszyklus in Java

Da der Java-Bytecode plattformunabhängig ist, hätten die Klassen A, B und C aber auch ebensogut von verschiedenen Entwicklern auf drei unterschiedlichen Plattformen entwickelt werden können, um später auf einer vierten Plattform ausgeführt zu werden. Abbildung 13.2 zeigt dies beispielhaft.

Abbildung 13.2: Plattformübergreifende Entwicklung in Java

13.3.2 Projektverwaltung

Getrenntes Kompilieren

Wie die Abbildungen deutlich machen, spielen die .class-Files für den Entwicklungsprozeß und die Portierbarkeit von Java-Programmen eine entscheidende Rolle. Jede .class-Datei enthält den Bytecode für eine übersetzte Klasse. Zusätzlich sind in ihr Informationen enthalten, um dynamisches Linken und Late-Bindung zu unterstützen und gegebenenfalls Symbole, Zeilennummern und andere Informationen für den Debugger zur Verfügung zu stellen.

Eine der Grundregeln bei der Entwicklung von Java-Programmen ist es, genau eine Klassendefinition je Quelldatei aufzunehmen. Anders als etwa in C++, ist es in Java grundsätzlich nicht möglich, die Quellen einer einzigen Klasse auf mehrere Dateien zu verteilen (und auf diese Weise weniger als eine Klasse in einer Quelldatei zu speichern). Obwohl es - wie wir gleich sehen werden - möglich ist, mehr als eine Klasse in einer Quelldatei abzulegen, sollte dies in der Regel nicht getan werden. Wenn diese Regeln eingehalten werden, ergibt sich eine eindeutige Abbildung zwischen Klassen und Quelldateien, die bei der sauberen Strukturierung eines Projektes hilft. Durch die Verwendung von Paketen kann eine Verteilung der Quelltexte auf verschiedene Verzeichnisse und Unterverzeichnisse erreicht werden.

 Hinweis 

Wie bereits angedeutet, dürfen tatsächlich auch zwei oder mehr Klassen in einer Quelldatei enthalten sein. Voraussetzung dafür ist allerdings, daß höchstens eine von ihnen als public deklariert wurde. Eine solche Vorgehensweise kann beispielsweise bei sehr kleinen Projekten, die nur aus ganz wenigen Klassen bestehen, sinnvoll sein, um alle Klassen in eine einzige Datei zu bekommen. Sie kann auch angewendet werden, wenn kleine Hilfsklassen benötigt werden, die nur für eine einzige andere Klasse von Bedeutung sind. Der Compiler erzeugt in jedem Fall eine separate .class-Datei für jede Klasse, die in einer Quelldatei enthalten ist. Wurde in einer Quelldatei mehr als eine Klasse public deklariert, gibt es einen Compiler-Fehler.

Wichtig ist in dem Zusammenhang auch, daß der Name der public-Klasse und der Name der Quelldatei identisch sein müssen. Dabei muß die Groß- und Kleinschreibung eingehalten werden, und auch bei Klassennamen, die länger als 8 Zeichen sind, muß der Dateiname so lang wie der Klassenname sein. Klassen- und Dateiname unterscheiden sich also nur durch die Extension .java. So befindet sich beispielsweise die Klasse Integer in einer Datei mit dem Namen Integer.java und die Klasse InterruptedException in einer Datei mit dem Namen InterruptedException.java. Da die Extension einer Java-Quelldatei in jedem Fall .java (und damit vierstellig) ist, ist eine vernünftige Portierung von Java auf Plattformen, die nur 8+3-Dateinamen unterstützen, kaum sinnvoll möglich und bisher auch nur ansatzweise gelungen.

 Warnung 

Interessanterweise bietet Java volle Typsicherheit auch über die Grenzen von Quelldateien hinweg, ohne daß dazu Header-Dateien oder andere Interface-Beschreibungen nötig wären. Der Compiler verwendet während der Übersetzung einer Java-Klasse die .class-Dateien aller eingebundenen Klassen und entnimmt diesen die Signatur der aufgerufenen Methoden. Die Notwendigkeit zur Bereitstellung von separaten Header-Dateien (wie beispielsweise in C++) und das fehlerträchtige Management der Abhängigkeiten zwischen ihnen und ihren Quelltexten entfällt daher.

Java und make

Genau aus diesem Grund ist aber auch die Verwendung des make-Tools zur Verwaltung der Dateiabhängigkeiten in Java-Projekten schwierig. Anstelle der klar definierten Abhängigkeit einer Quelldatei von einigen Headerdateien besitzt eine Java-Quelle meist eine Vielzahl von (teilweise impliziten oder indirekten) Abhängigkeiten zu anderen Java-Quellen. Diese korrekt zu pflegen ist nicht einfach, und ein makefile kann leicht unvollständige Abhängigkeitsregeln enthalten. Die daraus entstehenden Inkonsistenzen können zu schwer zu lokalisierenden Laufzeitfehlern führen.

Ein anderes Problem bei der Verwendung von make ist die Vielzahl der separaten Compiler-Aufrufe. Da der Java-Compiler selbst in Java geschrieben wurde, verursacht jeder Aufruf einen größeren Overhead durch das erforderliche Starten der virtuellen Maschine, der sich bei umfangreichen Projekten in unzumutbaren Wartezeiten niederschlägt.

Aus diesen Gründen ist es bei kleineren und mittleren Projekten manchmal sinnvoll, auf den Einsatz von make zu verzichten und die Programme bei Bedarf durch Aufruf von javac *.java komplett neu zu kompilieren. Der Aufruf-Overhead entsteht in diesem Fall nur einmal, und der Compiler braucht nicht wesentlich länger, als wenn lediglich eine einzige Quelle übersetzt würde.

 Tip 


 Titel   Inhalt   Suchen   Index   API  Go To Java 2, Zweite Auflage, Addison Wesley, Version 2.0
 <<    <     >    >>  © 2000 Guido Krüger, http://www.gkrueger.com