Pakete
Java Pakete
Java Pakete (packages)
- Helfen dabei größere Software-Systeme zu strukturieren
- Können Klassen und selbst wieder Pakete enthalten
Programme können sehr schnell auf viele tausend Klassen anwachsen. Sie würden dann ausgesprochen unübersichtlich, wenn es oberhalb der Klassen keinen weiteren Mechanismus zur Gruppierung gäbe. Genau hier kommen Pakete zur Hilfe. Pakete erlauben, eine beliebige Anzahl von Klassen zu einer Einheit zusammenzufassen, also ein „Paket von Klassen“, die zusammengehören, zu schnüren.
Das package Statement
In Java dient das package
-Statement dazu, Klassen und Interfaces in logische Gruppen zu unterteilen und eine Namensraumhierarchie zu schaffen. Es stellt sicher, dass Klassen und Interfaces innerhalb eines Paketes eindeutige Namen haben, indem ihnen der Paketname vorangestellt wird. Dadurch wird es einfacher, Klassen und Interfaces zu organisieren, zu verwalten und wiederzuverwenden.
- Klasse ordnet sich selbst durch das
package
Statement einem Paket zu - Eine Klasse kann nur einem Paket angehören
package
muss als erstes Statement in der Klasse stehen- In einem Paket kann es jeden Klassennamen nur einmal geben
- Fehlt das
package
, gehört die Klasse zum namenlosen default-Paket - Paketnamen sind hierarchisch und durch Punkte getrennt
package firma.domain;
public class Mitarbeiter { ... }
Die Syntax für das package-Statement ist
package <top_pkg_name>[.<sub_pkg_name>]*;
Kommentare vor dem package Statement sind erlaubt, andere Statements aber nicht.
Die Verwendung des default-Pakets, durch Weglassen des package
-Statements, ist schlechter Stil und sollte daher in Java-Programmen nicht vorkommen. Sie sollten jede Java-Klasse explizit einem Paket zuordnen.
Die Konvention ist, dass man den Namen des Pakets mit dem umgedrehten Domain-Namen der Firma oder Organisation anfangen lässt, die dieses Paket verantwortet. Da Domain-Namen weltweit eindeutig sind, kann man hierdurch gewährleisten, dass die Paketnamen eindeutig sind. So fangen z. B. alle Paketnamen der Apache Foundation mit org.apache
an. Beachten Sie, dass in Paketnamen (im Gegensatz zu Domainnamen) kein Bindestrich erlaubt ist. Die Java-Konvention sieht vor, einen Bindestrich im Domainnamen durch einen Underscore (_) im Paketnamen zu ersetzen: aus hs-mannheim.de
würde dann de.hs_mannheim
.
Das import Statement
- Der volle Name (fully qualified name) einer Klasse besteht aus dem Paket und dem Namen der Klasse, z. B.
java.util.Date
- Um nicht immer den vollen Namen schreiben zu müssen, kann man dem Compiler kurze Namen über
import
bekannt machen - Die
import
Statements müssen nach dempackage
Statement aber vor der Klassendeklaration im Quelltext stehen
package firma.db;
import firma.domain.Mitarbeiter;
import java.sql.Connection;
import java.util.*;
public class DbMitarbeiter { ... }
Die Syntax des import
-Statements ist
import <pkg_name>[.<sub_pgk_name>].<class_name>;
bzw.
import <pkg_name>[.<sub_pkg_name>].*;
Mit *
kann man alle Namen aus einem Paket importieren. Dies sollte aber vermieden werden, da es den Namensraum der Klasse verschmutzt und durch Lesen der import
-Statements nicht mehr klar wird, welche Klassen und Interfaces aus dem Paket überhaupt benutzt werden. Da moderne IDEs, wie Eclipse, die Erzeugung der import
-Statements komplett automatisieren, gibt es heutzutage keinen Grund mehr für die Verwendung von *
im Import.
Ob man einen Import per *
oder einzeln durchführt, hat keinen Einfluss auf die Compile- oder Laufzeit des Programms, da Compiler und VM intern ohnehin nur mit den fully qualified name arbeiten.
Der Stern bezieht sich immer nur auf die Klassen innerhalb des Paketes nicht aber auf Unterpakete. Man kann damit also keine ganzen Paktehierarchien importieren. Klassen aus Unterpakten werden durch den *
somit nicht erfasst.
Das import static Statement
- Seit Java 5 kann man static imports durchführen
- Macht statische Variablen oder Methoden anderer Klassen bekannt, sodass man sie ohne Angabe des Klassennamens verwenden kann
- Syntax:
import static packageName.className.staticMemberName;
Auch beim import static
kann man den Stern (*
) als Wildcard verwenden. In diesem Fall werden alle statischen Variablen und statischen Methoden der Klasse importiert. Auch hier gibt aber das oben bereits gesagte: man sollte auf Imports per *
grundsätzlich verzichten und die statischen Elemente einzeln importieren.
Sichtbarkeit von Klassen
- Klassen könne zwei mögliche Sichtbarkeiten haben
- default - Nur Klassen innerhalb desselben Pakets dürfen zugreifen
public
- Jeder darf zugreifen- Nur wenn die Klasse selbst öffentlich ist, sind die öffentlichen Methoden oder Variablen außen sichtbar
package sichtbarkeit; package sichtbarkeit;
public class A { class B {
private int a; private int a;
int b; int b;
public int c; public int c;
private void m1() {} private void m1() {}
void m2() {} void m2() {}
public void m3() {} public void m3() {}
} }
Klassen, die nur innerhalb des Paktes sichtbar sind, nennt man auch paketprivate Klassen (package private class). Klassen, die mit public
gekennzeichnet sind, bezeichnet man als öffentliche Klasse (public class).
Die Sichtbarkeit von Methoden und Variablen wird noch einmal später genauer erläutert.
In diesem Beispiel gilt Folgendes.
In Klasse A
ist die Variable a
nur innerhalb der Klasse, b
im ganzen Paket und c
für alle sichtbar. Dasselbe gilt für die Methoden m1
(nur innerhalb der Klasse), m2
(im ganzen Paket) und m3
(überall sichtbar).
Da die Klasse B
selbst nicht öffentlich ist, sind die Sichtbarkeiten hier: a
nur innerhalb der Klasse, b
und c
nur innerhalb des Paketes. m1
nur innerhalb der Klasse, m2
und m3
nur innerhalb des Pakets.
Klassen und Dateien
- Jede öffentliche Klasse (public class)
ClassName
muss in einer eigenen Datei mit dem NamenClassName.java
abgelegt werden
package pr2;
public class PublicClass {
}
- Mehrere paketprivate Klassen (package private class) können in einer Datei abgelegt werden
package pr2;
class PackagePrivateClass {
}
class NochEineKlasse {
}
class UndNochEine {
}
Ablage der Dateien
- Kompilierten Java-Klassen (
.class
) werden entsprechend der Paketzugehörigkeit in Verzeichnissen abgelegt - Java-Sourcen (
.java
-Dateien) sollten ebenfalls nach Paketen organisiert werden - Die IDE (z. B. Eclipse) übernimmt diese Aufgabe automatisch

Java verlangt nicht, dass die Quellen nach Paketen organisiert werden, nur die kompilierten Klassen müssen so abgelegt werden. Aus Gründen der Übersichtlichkeit werden aber die Quellen üblicherweise nach Paketen sortiert. Eclipse macht dies standardmäßig.
Nutzen von Paketen
- Neben der reinen Strukturierung werden Pakete für das Information Hiding eingesetzt
- Klassen mit Sichtbarkeit auf Paket-Ebene können von außen nicht verwendet werden, daher kann man sie vor externen Verwendern geheim halten
Verwendung von existierenden Paketen
Die Java VM bringt bereits eine ganze Reihe von Paketen und Klassen mit. Hierbei gilt
java.lang
wird immer automatisch importiert, alle anderen Pakete muss man explizit importierenjava.*
kann man frei benutzen, Oracle hält die Pakete kompatibel- Deprecation dient zum Abkündigen von Funktionen aus den
java.*
Paketen - Auf keinen Fall sollte man Klassen aus
sun.*
undcom.sun.*
verwenden
In java.lang
finden sich die grundlegenden Klassen, die man ohnehin in nahezu jedem Java-Programm benötigt: Object
, String
, etc. Aus diesem Grund muss man das Paket nicht importieren, sondern der Compiler macht dies automatisch.
Die Klassen in sun.*
und com.sun.*
sind rein interne Implementierungen und unterliegen keinerlei Kompatibiltätsgarantien. Außerdem sind sie nicht Teil der Java-Spezifikation und fehlen auf VMs anderer Hersteller ganz. Wer also solche Klassen verwendet, gibt damit die Plattformunabhängigkeit seiner Java-Programme auf, ein Schritt, den man normalerweise nicht gehen möchte.
Die Datei package-info.java
- Pakete werden implizit durch die
package
-Deklarationen der Klassen erzeugt - Man kann eine besondere Datei namens
package-info.java
in den Ordner des Paketes legen - Sie nimmt auf
- JavaDoc des Pakets
- Annotationen die sich auf das ganze Paket beziehen
Annotationen (annotations) werden zwar an einigen Stellen in der Vorlesung PR2 benutzt. Die Zeit reicht allerdings nicht aus, um sie grundlegend einzuführen.
Da in Java-Klassennamen keine Bindestriche vorkommen dürfen, besteht keine Konfliktgefahr zwischen der package-info.java
-Datei und Klassen.
Beispiel: package-info.java
/**
* Dokumentation für das Paket packages.
*
* <p>
* Wer dieses Paket verwenden möchte sollte beachten,
* dass es sich um ein reines Demonstrationspaket handelt.
* </p>
*
* @author Thomas Smits
* @version 1.0
*/
package pr2.packages;
Grenzen von Java-Paketen
Java-Pakete haben Schwächen
- Pakete bilden keine echte Hierarchie
- Man hat nur die Wahl zwischen package private oder public
Neuere Konzepte versuchen diese Schwächen zu umgehen
- OSGi Bundles
- Module (seit Java 9)
Obwohl die Namen der Java-Pakete und die Ablage in verschachtelten Ordnern den Eindruck erwecken, es handele sich um eine Hierarchie (obere Abbildung), ist es in der Realität anders. Die Hierarchie wird flachgeklopft und es existieren Pakete mit Namen, die einen Punkt enthalten (untere Abbildung). Das Paket d
im Beispiel befindet sich also gar nicht im Paket c
, sondern es hat einfach einen Namen, in dem c
vorkommt, nämlich a.b.c.d
.
Als Ergebnis haben die Pakete c
und d
kein anderes Verhältnis zueinander als die Pakete d
und f
.
Module werden im nächsten Kapitel behandelt.