04.03.10 Pakete
Aufgrund der Vielzahl an Klassen, welche bei der Entwicklung von Projekten anfallen können, muss für eine Projekt- bzw. Programmstruktur Sorge getragen werden. Im Java Umfeld ist dabei die Modularisierung von Klassen in entsprechende Pakete üblich.
Pakete
Es ist so gut wie immer sinnvoll die einzelnen Klassen eines Projektes logisch in einer Programmstruktur anzuordnen. Das beste Beispiel hierfür ist Sprache Java selbst. Sie besteht aus einer recht gewaltigen Anzahl aus Klassen, welche alle in entsprechende Pakete aufgeteilt werden. Dies hat mehrere Vorteile:
- Logische Struktur zum schnellen Wiederfinden
- Viele Entwickler können an einem Projekt arbeiten, da zum Beispiel jeder seine eigene Pakete pflegt
- Verhinderung von Namenskonflikten bei mehrfach auftretenden gleichen Klassennamen
Bei der Vergabe von Paketnamen und insbesondere der Paketstruktur gibt es allgemein anerkannte Konventionen. Häufig wird hierbei einfach die URL des Unternehmens, des Projektes oder der Einzelperson in umgekehrter Reihenfolge als Ausgangslage hergenommen.
Haben wir ein Unternehmen mit der Adresse www.meinunternehmen.de, ergibt sich als erste Paketstruktur:
de.meinunternehmen.projektname
Man kann aber auch andere Namen verwenden. Generell werden alle Paketnamen klein geschrieben. Bei der Einteilung in Pakete spricht man auch häufig von Namensraum bzw. Namespace. Die einzelnen Paketnamen werden auf dem Betriebssystem als Ordnerstruktur abgebildet. So befindet sich beispielsweise die Klasse de.meinunternehmen.projektname.MeineKlasse
in dem Ordner de/meinunternehmen/projektname/MeineKlasse.java
.
Dadurch, dass bei der Verwendung einer Paketstruktur nicht mehr alle Klassen in einem Ordner liegen, muss man die entsprechenden Klassen finden und eindeutig identifizieren können. Dies geschieht mit Hilfe der package
und import
Anweisung in unserem Quellcode.
Als Beispiel haben wir folgende Programmstruktur.
de
- meinunternehmen
- tollesprojekt
Start.java
- util
Helper.java
Hierbei soll die Klasse Start
eine main
Methode, enthalten, welche für Ihre Abarbeitung aber die Klasse Helper
im Paket de.meinunternehmen.tollesprojekt.util
benötigt.
Als erstes muss darauf geachtet werden, dass jede Klasse ihren eignen Paketpfad enthält. Dazu wird an den Anfang der Klasse die package
Anweisung gefolgt vom Paketnamen angegeben.
Für unsere Start
Klasse wäre dies:
package de.meinunternehmen.tollesprojekt;
Und für unsere Helper
Klasse
package de.meinunternehmen.tollesprojekt.util;
Somit enthält erst einmal jede Klasse einen Hinweis zu welchem Paket sie eigentlich gehört.
Schauen wir uns nun die Klasse Start
an, welche ja die Klasse Helper
aus einem anderen Paket benötigt.
package de.meinunternehmen.tollesprojekt; import de.meinunternehmen.tollesprojekt.util.Helper; public class Start { public static void main(String[] args) { System.out.println(Helper.ggT(54, 12)); } }
Sie sehen, dass zuerst das eigene Paket angegeben wird. Danach wird die entsprechende Helper
Klasse mit import de.meinunternehmen.tollesprojekt.util.Helper;
importiert. In der Main-Methode wird diese Klasse dann über ihren Namen verwendet.
Die Klasse Helper
hat folgenden Inhalt:
package de.meinunternehmen.tollesprojekt.util; public class Helper { public static int ggT(int aA, int aB) { while (aA != aB) { if (aA > aB) { aA = aA - aB; } else { aB = aB - aA; } } return aA; } }
Sie enthält ebenfalls die package
Anweisung mit der Angabe des Pakets zu welchem sie gehört. Hier fehlt allerdings eine import
Anweisung, da Helper
keine weiteren Klassen verwendet. Die Klasse selbst stellt eine Klassenmethode ggT
zur Verfügung, welche von zwei int
Werten den größten gemeinsamen Teiler berechnet.
Enthält unser Paket util
noch eine weitere Klasse Helper2.java
und wir wollen beide Klassen in unserer Klasse Start
verwenden, kann man dies auf verschiedene Weisen tun.
Man kann alle Klassen einzeln importieren unter Angabe der eindeutigen Klassennamen.
import de.meinunternehmen.tollesprojekt.util.Helper; import de.meinunternehmen.tollesprojekt.util.Helper2; public class Start { /* */ }
Es gibt aber auch die Möglichkeit alle Klassen eines Paketes zu importieren.
import de.meinunternehmen.tollesprojekt.util.*; public class Start { /* */ }
Der Stern (*) nach dem Paket util
bedeutet, dass das ganze Paket util
bei der Suche nach Klassen mit einbezogen werden soll. Es werden aber auch nur die wirklich verwendeten Klassen importiert. Stehen in dem util
Paket weitere Klassen, welche in Start
nicht verwendet werden, so werden diese auch nicht importiert. Als gängige Praxis hat sich aber die Verwendung eindeutiger Klassennamen durchgesetzt. Hier kann man nämlich schon beim Lesen der import
Anweisungen einer Klasse erkennen, was diese Klasse alles importiert.
Was passiert aber, wenn eine weitere Klasse Helper
in einem weiteren Paket help
liegt und ebenfalls in Start
verwendet werden soll? Hierzu gibt es ebenfalls zwei Varianten. Man importiert eine Klasse mittels import
und die andere Klasse mit gleichem Namen wird im Quellcode bei ihrer Verwendung eindeutig angegeben.
package de.meinunternehmen.tollesprojekt; import de.meinunternehmen.tollesprojekt.util.Helper; public class Start { public static void main(String[] args) { System.out.println(Helper.ggT(54, 12)); System.out.println(de.meinunternehmen.tollesprojekt.help.Helper.add(10, 20)); } }
Somit wird jedes mal wenn wir nur Helper
verwenden die Klasse aus dem Paket util
verwendet. Wollen wir aber die Klasse Helper
aus dem Paket help
verwenden, so müssen wir explizit deren eindeutigen Namen angeben und dies jedes Mal wenn wir diese verwenden wollen. Die zweite Möglichkeit ist es komplett auf die import
Anweisungen zu verzichten und immer beide Klassen im Quellcode eindeutig anzusprechen.
package de.meinunternehmen.tollesprojekt; public class Start { public static void main(String[] args) { System.out.println(de.meinunternehmen.tollesprojekt.util.Helper.ggT(54, 12)); System.out.println(de.meinunternehmen.tollesprojekt.help.Helper.add(10, 20)); } }
Fazit
Mit der Gliederung der Klassen in einzelne Pakete ist es möglich diese nach logischen Gesichtspunkten zu strukturieren und zusammengehörige Klassen auch in die gleichen Namensräume zu verpacken. Jede Klasse muss dann allerdings ihr eigenes Paket mit Hilfe der package
Anweisung angeben. Mit der import
Anweisung kann man zu verwendende Klassen importieren. Man kann aber auch komplett auf import
verzichten und immer den vollen eindeutigen Klassennamen angeben. Dies macht vor allem dann Sinn, wenn es in unterschiedlichen Paketen mehrere Klassen mit gleichem Namen gibt.
Hallo liebes Java-Blog-Team,
eigentlich irritiert mich der lange Pfad …/de/meinunternehmen/… . Wird denn jemals in de/ ein weiterer Unterordner parallel zu ‚meinunternehmen‘ abgelegt? Was könnte dieser logischerweise enthalten?
Wie sollte ich beim Kompilieren vorgehen? Ich glaube zu wissen, dass man zunächst Helper.java kompilieren muss und erst dann die Start-Klasse erstellen kann? Welche Rolle spielt diesbezüglich Apache Ant (da war doch was ;)?
Viele Grüße und herzlichen Dank
Hallo Daniel,
in der Regel wird es parallel zu
meinunternehmen
inde
kein Unterverzeichnis geben. Es ist trotzdem gebräuchlich als subpackage nach der Sprache das eigene Unternehmen zu nennen bzw. das Unternehmen, für welches man gerade entwickelt (ein IT-Dienstleister wird häufig für unterschiedliche Firmen Software entwickeln). So hat alles eine klar definierte Struktur.Wie man beim Kompilieren mit mehreren Klassen vorgeht, wird im Kapitel 04.03.04 Umgang mit mehreren Klassen gezeigt.
Apache Ant ist ein „Tool“, welches primär dazu eingesetzt wird, aus verschiedenen Ressourcen eine lauffähige (sei dies eine JAR, eine WAR für einen Server, …) Applikation oder Teile davon automatisiert nach bestimmten Regeln zu erstellen. Für kleine Anwendungen ist Ant jedoch nicht nötig.
Grüße
Stefan
Eine Frage dazu hätte ich noch (zu den Länderkürzeln): Was passiert wenn ich für ein Schweizer/Österreichisches etc. Unternehmen scripte – bleibt es dann bei „de“ oder wird es zu „at“ bzw. „vh“? Oder anders gefragt: Kommt es auf Sprache oder Staat an?
Danke für Antworten! lg.
Sorry, wo ich „vh“ geschrieben habe, meinte ich „ch“ – jetzt geh‘ ich und schähm mich 😉
lg.
Meistens wählt man das am Besten passende Kürzel. Man könnte bspw. für Software im deutschsprachigen Gebiet „de“ wählen, für eine Fahrplanauskunft in Österreich „at“. Oft findet man bspw. auch „com“ oder „org“ im Package.
Grüße
Stefan
Die Konvention für Packagenamen sieht vor, dass das Package mit der umgedrehten Webseiten-URL des Erstellers beginnt. In meinem Fall also mit de.tobiasdemuth (privat) bzw com.viessmann (dienstlich). Bei österreichischen Unternehmen wird in der Regel eine at-Domain vorliegen, so dass sich das führende Kürzel automatisch ergibt.