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.

6 Replies to “04.03.10 Pakete”

  1. Daniel

    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

  2. Stefan Kiesel

    Hallo Daniel,

    in der Regel wird es parallel zu meinunternehmen in de 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

  3. [MuhTuhls.}

    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.

  4. [MuhTuhls.}

    Sorry, wo ich „vh“ geschrieben habe, meinte ich „ch“ – jetzt geh‘ ich und schähm mich 😉

    lg.

  5. Stefan Kiesel

    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

  6. Tobias

    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.

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.