javaseiten.de   |   Version 0.6
 

1.5. Pakete

1.5.1. Grundlagen

Einzelne Klassen können zu Paketen (engl. packages) zusammengefasst werden. Die Klassen werden dann auch als Mitglieder (engl. members) des Pakets bezeichnet. Um eine Klasse einem bestimmten Paket zuzuordnen, kann innerhalb des Java-Quelltextes das Schlüsselwort package verwendet werden. Die package-Angabe wird vor der eigentlichen Deklaration der Klasse notiert. Nach dem Schlüsselwort folgt dann der gewählte Name des Pakets.

package PaketName;

Das anschließende Listing deklariert die Klasse PackageExample1. Direkt zu Beginn folgt nach package der gewählte Name des Pakets p1. Die Beispielklasse ist also durch diese Angabe Mitglied des Pakets p1.

Listing 1.18. PackageExample1.java. Die Klasse PackageExample1 wird dem Paket p1 zugeordnet.

/* PackageExample1.java */

package p1;

public class PackageExample1 {
  
  public static int a1 = 3;
   
  public static void method11() {
    System.out.println("method11");
  }
}

Pakete bzw. die darin enthaltenen Klassen können innerhalb des Dateisystems in Ordnern bzw. Unterordnern organisiert werden. Ein Paketname wird in ein korrespondierendes Dateiverzeichnis transformiert, in dem die Quell- und Klassendateien lokalisiert sind. Ausgehend von einem gewählten Ausgangsverzeichnis erzwingt die package-Angabe im Beispiel einen Unterordner mit dem Namen p1. In diesen Ordner kann dann die Datei PackageExample1.java kopiert werden.

Ausgangsverzeichnis/p1: PackageExample1.java

Auch weitere Klassen, die mit package p1 diesem Paket zugeordnet werden sollen, können in diesen speziellen Unterordner kopiert werden. Im Ordner p1 sind also alle Klassen enthalten bzw. organisiert, die Bestandteil des Pakets p1 sind. Im Zusammenhang mit Paketen wird auch von einem voll qualifizierten Namen einer Klasse gesprochen. Im Beispiel ist der voll qualifizierte Name der deklarierten Klasse p1.PackageExample1. Der verwendete Paketname wird also dem Klassennamen vorangestellt und die beiden Namensbezeichnungen sind durch einen Punkt voneinander getrennt.

 

Paket im Paket

Ein Paket kann Teil eines anderen Pakets sein. Ein Paket kann also auch weitere Unterpakete besitzen. Soll z.B. eine Klasse innerhalb eines Unterpakets angeordnet sein, könnte die im Quelltext verwendete package-Angabe den folgenden Aufbau besitzen:

package PaketName1.PaketName2;

Der folgende Quelltext enthält eine derartig aufgebaute package-Angabe. Dies hat zur Folge, dass die Klasse PackageExample2 dem Paket p2 zugeordnet wird. p2 ist wiederum Unterpaket von p1.

Listing 1.19. PackageExample2.java. Das Paket p2 ist Teil des Pakets p1.

/* PackageExample2.java */

package p1.p2;

public class PackageExample2 {
  
  public int a2 = 4;
  
  public void method21() {
    System.out.println("method21");
  } 
}

Entsprechend der Paket-Konvention wäre demnach die Datei PackageExample2.java, ausgehend von einem gewählten Ausgangsverzeichnis, im Unterordner p1/p2 abzuspeichern.

Ausgangsverzeichnis/p1/p2: PackageExample2.java

 

Das Default-Paket

Es ist nicht verpflichtend, eine Klasse in ein Paket zu packen. D.h. die Verwendung des Schlüsselwortes package ist nicht notwendig. Eine Klasse, die nicht explizit einem Paket zugeordnet wurde, befindet sich per Vorgabe automatisch im sogenannten Default-Paket (unnamed package). Bei der Erstellung von kleineren Programmen wird oft auf eine Paketzuordnung der beteiligten Klassen verzichtet. Bei größeren Anwendungen ist die Strukturierung der erstellten Klassen durch die Verwendung von Paketen allerdings oft unverzichtbar.

 

Eindeutige Paketnamen

In Listing 1.19 ist der voll qualifizierte Name der Unterpakets p1.p2. Bei größeren Softwareprojekten wird versucht, Paketen einen eindeutigen Namen zu geben. Einzelne Pakete werden mitunter weltweit genutzt und die Wahrscheinlichkeit, dass ein weiteres Paket ebenfalls den Namen p1.p2 hat ist natürlich groß - dies führt zu Verwechslungen und ein Paket kann nicht eindeutig, z.B. einem bestimmten Softwareersteller, zugeordnet werden. Es wird deshalb vorgeschlagen Internet-Domainnamen zu benutzen, um eine eindeutige Namensbezeichnung von Paketen zu gewährleisten. Der Beispiel-Domainname javaseiten.de kann dazu umgekehrt werden zu de.javaseiten. Die Top-Level-Domain de wird zuerst notiert, anschließend folgt die Second-Level-Domain javaseiten. Um die in den vorangehenden Beispielen verwendeten Paketnamen p1 und p2 in eindeutiger Weise festzulgen, könnten diese mit den folgenden voll qualifizierten Namen notiert werden:

de.javaseiten.p1
de.javaseiten.p1.p2

Diese Paketnamen, bei denen der Domainname verwendet wurde, erfordern eine entsprechende package-Angabe in den Java-Quelltexten:

/* PackageExample1.java */ 
package de.javaseiten.p1;
...

/* PackageExample2.java */
package de.javaseiten.p1.p2;
...

Da die package-Angaben im Quelltext direkt mit einer entsprechenden Ordnerstruktur korrespondieren, ist eine dem Paketnamen angepasste Ordnerstruktur notwendig. Die im Beispiel verwendeten Quelltextdateien PackageExample1.java und PackageExample2.java, die den einzelnen Paketen angehören, müssten dann innerhalb der folgendn Ordnerstruktur angeordnet sein.

Ausgangsverzeichnis/de/javaseiten/p1:    PackageExample1.java
Ausgangsverzeichnis/de/javaseiten/p1/p2: PackageExample2.java

1.5.2. Importieren von Klassen und Paketen

Mit Hilfe des Schlüsselwortes import können einzelne Klassen aus bestimmten Paketen oder ganze Pakete "importiert" werden. Die Bezeichnung "importieren" ist in dem Sinne zu verstehen, dass z.B. eine Klasse durch die Angabe ihres einfachen Namens genutzt werden kann. Ohne eine import-Angabe zu Beginn eines Quelltextes müsste eine Klasse, die sich z.B. im Paket p1 befindet, mit ihrem voll qualifizierten Namen adressiert werden. Dem einfachen Namen der Klasse müsste also der Paketname p1, gefolgt von einem Punkt, vorangestellt werden. Um die im Quelltext benötigten Klassen eines Pakets pauschal zu importieren, kann nach dem Paketnamen und dem obligatorischen Punkt das Zeichen "*" folgen. Falls lediglich eine einzelne Klasse importiert werden soll, kann das Sternsymbol durch den entsprechenden Klassennamen ersetzt werden. In der folgenden Übersicht kann PaketName angepasst werden, um auch Pakete innerhalb weiterer Pakete zu adressieren.

import PaketName.*;
import PaketName.KlassenName;

Das anschließende Beispiel PackageExample3.java verwendet zwei import-Angaben. Die zuvor in Listing 1.18 und Listing 1.19 definierten Klassen sollen im Beispiel verwendet werden. Der Quelltext bzw. die zugehörige Klassendatei PackageExample3.class befinden sich im gewählten Ausgangsverzeichnis und die benötigten zwei Klassendeklarationen mit Paketzugehörigkeit sind in entsprechenden Unterordnern abgespeichert.

Ausgangsverzeichnis:       PackageExample3.java
Ausgangsverzeichnis/p1:    PackageExample1.java
Ausgangsverzeichnis/p1/p2: PackageExample2.java

Bei der Verwendung von import ist zu beachten, dass eine zu importierende Klasse als public deklariert wurde. Andernfalls ist die Klasse außerhalb des Pakets nicht zugänglich. Die erste import-Angabe des Beispiels macht die Klassen des Pakets p1 zugänglich (das Paket im Beispiel enthält nur eine Klasse). Mit der zweiten Verwendung des Schlüsselworts import wird gezielt die Klasse PackageExample2 im entsprechenden Unterpaket adressiert. Der Quelltext führt nach dessen Übersetzung und Ausführung zur Ausgabe "3", "method11", "4" und "method21".

Listing 1.20. PackageExample3.java. Importieren der Klassen PackageExample1 und PackageExample2.

/* PackageExample3.java */

import p1.*;
import p1.p2.PackageExample2;

public class PackageExample3 {
  
  public static void main(String[] args) {
    int c1 = PackageExample1.a1;
    System.out.println(c1);
    PackageExample1.method11();
    
    PackageExample2 pe2 = new PackageExample2();
    int c2 = pe2.a2;
    System.out.println(c2);
    pe2.method21();
  }
}

Das Beispiel könnte auch ohne die beiden import-Angaben realisiert werden. Ein entsprechendes Äquivalent des Quelltextes könnte dann so aussehen:

/* PackageExample3.java */

public class PackageExample3 {
  
  public static void main(String[] args) {
    int c1 = p1.PackageExample1.a1;
    System.out.println(c1);
    p1.PackageExample1.method11();
    
    p1.p2.PackageExample2 pe2 = new p1.p2.PackageExample2();
    int c2 = pe2.a2;
    System.out.println(c2);
    pe2.method21();
  }
}

 

Statischer Import

Innerhalb einer Importdeklaration kann auch das Schlüsselwort static verwendet werden. Damit können zugängliche statische Bestandteile einer bestimmten Klasse importiert werden.

import static PaketName.KlassenName.*;
import static PaketName.KlassenName.StatischesMitgliedName;

Das folgende Beispiel macht von dieser Möglichkeit Gebrauch. Im Vergleich zu Listing 1.20 kann dadurch auf das statische Feld a1 und die statische Methode method11 direkt zugegriffen werden.

Listing 1.21. PackageExample4.java. Importieren der satischen Bestandteile der Klasse PackageExample1.

/* PackageExample4.java */

import static p1.PackageExample1.*;

public class PackageExample4 {
  
  public static void main(String[] args) {
    int c1 = a1;
    System.out.println(c1);
    method11();
  }
}

 

Automatischer Import

Innerhalb von Listing 1.20 wurde zweimal das Schlüsselwort import verwendet, um ein Paket bzw. eine einzelne Klasse zu importieren. Es wird aber generell auch ein automatischer Import des Pakets java.lang durchgeführt. Das Paket ist Bestandteil des Java Development Kits (JDK) bzw. der Java-Laufzeitumgebung (JRE). Es beinhaltet fundamentale Klassen für die Programmerstellung, die sich in der Archivdatei rt.jar befinden. Der Import des Pakets java.lang wird bei der Erstellung einer Klasse automatisch durchgeführt und bedarf keiner expliziten import-Angabe. Die Klasse System ist z.B. Bestandteil des Pakets java.lang. Die Klasse wurde bei vorhergehenden Beispielen bereits oft verwendet, um mit Hilfe der Methode println eine Konsolenausgabe zu erzeugen. Ohne den beschriebenen automatischen Import wäre die Klasse System nicht verfügbar und der Compiler javac würde dies mit einer Fehlermeldung anzeigen.

 

 

 

Diese Seite nutzt Google-Dienste - siehe dazu Datenschutz.

Copyright © 2006, 2007 Harald Roeder