/
/
·
·
/
/
·
·
  • Einführung
  • Die Idee in einem Satz
  • Package-Deklaration
  • Import: Klassen nutzen
  • classpath und modulepath: wie Java die Klassen findet
  • java.lang ist auto-importiert
  • Typische IDE-Fehler
  • Sichtbarkeit auf Paket-Ebene
  • Namens-Konflikte lösen
  • Sichtbarkeits-Übersicht mit Paketen
  • Beispiel: Mini-Projekt-Struktur
  • Klausur-Faustregeln
  • Häufige Stolpersteine
  • Klausur-Beispielaufgabe
ThemenProgrammiergrundlagenPakete & Imports
Programmiergrundlagen·4Lerneinheiten·38min·Stand17.07.2026

Pakete & Imports.

Stell dir vor du baust ein größeres Programm. Hunderte Klassen. Manche heißen Util, List, Logger. Wie verhinderst du, dass deine User mit der User aus einer fremden Library kollidiert, ohne ständig den vollen Pfad mitzuschleppen? Pakete sind Javas Antwort: zusammengehörige Klassen werden in Namensräumen gebündelt, organisiert wie Ordner. Und Imports holen dir Klassen aus anderen Paketen herein, sodass du sie kurz beim Namen nennen kannst statt jedes Mal den langen Paket-Pfad davorzuschreiben.

Du lernst hier, wie eine package-Deklaration eine Klasse einem Namensraum zuordnet, wie der voll qualifizierte Name (fully qualified name = Paket plus Klassenname, z. B. java.util.ArrayList) entsteht, wie import, Wildcard-Import und import static funktionieren. Außerdem, warum java.lang automatisch verfügbar ist, was der Source-Root mit der Verzeichnisstruktur zu tun hat, wie classpath/modulepath die Klassen zur Laufzeit findet und welche IDE-Fehlermeldungen typisch sind. Wie genau Sichtbarkeit (public, protected, package-private, private) zwischen Paketen wirkt, schauen wir uns weiter unten in den Abschnitten Sichtbarkeit auf Paket-Ebene und Sichtbarkeits-Übersicht mit Paketen an, das ist der zweite große Klausur-Block dieses Themas.

Klausur-Relevanz: package/import ist in WInf-Prog-1-Klausuren ein typischer Frage-Block. Übliche Formulierungen sind: "Wie sieht der Import-Pfad aus?", "Was ist der Unterschied zwischen package und import?", "Welche package-Zeile gehört in diese Datei?".

Paket (package): Eine Gruppe zusammengehöriger Klassen mit eindeutigem Namensraum, organisiert wie Ordner. Import: Mache Klassen aus anderen Paketen ohne ihren vollen Paket-Pfad (den voll qualifizierten Namen) nutzbar.

package de.unihamburg.studi;  // erste Code-Zeile in der Datei!

public class Student {
    private String name;
    // ...
}

Konvention: Pakete sind kleingeschrieben, durch Punkte getrennt, oft mit umgekehrtem Domain-Namen als Präfix (com.firma.projekt, de.uni.fachbereich). Damit machst du weltweit eindeutige Namen sehr wahrscheinlich, sofern du eine eigene Domain bzw. Organisation als Präfix nutzt. Technisch erzwingt Java das aber nicht.

Sprachregel vs. Projektkonvention

Hier lohnt sich eine präzise Unterscheidung, die in Klausuren oft schwammig dargestellt wird:

  • Sprachregel (gilt immer, JLS): Die package-Zeile bestimmt den voll qualifizierten Namen der Klasse. Aus package de.unihamburg.studi; plus class Student wird de.unihamburg.studi.Student. Das ist unabhängig davon, in welchem Ordner die Datei physisch liegt.
  • Projekt- und Tooling-Konvention (Standardfall): In normalen IDE-, Maven- oder Gradle-Projekten muss die Ordnerstruktur relativ zum Source-Root zum Paketnamen passen, sonst findet das Build-Tool die Klasse oft nicht korrekt oder meckert beim Kompilieren. Eclipse, IntelliJ, Maven und Gradle erwarten de/unihamburg/studi/Student.java unter dem Source-Root.

Fortgeschrittenes Detail (nicht klausurrelevant): Der nackte javac-Compiler ist toleranter: Über -sourcepath und -d (Ausgabeordner) kann er Quelldateien auch aus anderen Ordnern übersetzen. Verlass dich darauf aber nie im Projektalltag, halte dich an die Konvention, dann passt alles automatisch.

Kleingedrucktes zur package-Zeile: Falls eine package-Deklaration vorhanden ist, steht sie vor allen imports und Typdeklarationen, davor höchstens Kommentare/Whitespace oder Package-Annotationen. Eine Datei ganz ohne package-Zeile liegt im Default-Package (in echten Projekten unüblich).

Standard-Verzeichnisstruktur (so erwartet es deine IDE):

src/                         ← Source-Root (zählt NICHT zum Paketnamen)
└── de/
    └── unihamburg/
        └── studi/
            └── Student.java   ← package de.unihamburg.studi;

Lies die Baumstruktur von oben nach unten: Jeder Ordner unter dem Source-Root src/ ist ein Stück des Paketnamens. Der Source-Root selbst (src/) gehört nicht dazu, deshalb heißt das Paket de.unihamburg.studi und nicht src.de.unihamburg.studi. Weiter unten im Abschnitt Interaktiv verstehen kannst du mit dem Paket-Baum-Visualizer genau dieses Zusammenspiel aus package-Zeile, Dateipfad und Import live durchklicken.

Ohne Import musst du den voll qualifizierten Namen (fully qualified name, also Paket plus Klassenname) schreiben:

java.util.ArrayList<String> liste = new java.util.ArrayList<>();

Mit Import wird das kurz:

import java.util.ArrayList;

ArrayList<String> liste = new ArrayList<>();

Import-Varianten:

import java.util.ArrayList;    // Einzelimport
import java.util.*;             // Alles aus java.util (Wildcard)
import static java.lang.Math.PI; // Statische Member direkt nutzbar

Nach import static java.lang.Math.PI kannst du PI statt Math.PI schreiben, nützlich, aber es kann unklar werden, wenn du nicht weißt, woher das Symbol kommt.

Der import löst nur den kurzen Namen auf, er sagt nichts darüber, wo die .class-Dateien physisch liegen. Das übernimmt der classpath (klassisch) bzw. der modulepath (ab dem Java-Modulsystem, Java 9+).

  • classpath: eine Liste von Verzeichnissen und JAR-Dateien, in denen der Compiler und die JVM nach kompilierten Klassen suchen. Setzbar über -classpath / -cp oder die Umgebungsvariable CLASSPATH. Findet die JVM die Klasse zur Laufzeit nicht, fliegt eine NoClassDefFoundError oder ClassNotFoundException, obwohl der Code sauber kompiliert hat. Faustregel: Bei normal referenzierten Klassen siehst du meist einen NoClassDefFoundError; eine ClassNotFoundException kommt typischerweise beim expliziten Laden über Class.forName(...) oder ClassLoader.loadClass(...).
  • modulepath: das modernere Pendant, wenn dein Projekt eine module-info.java mit requires/exports hat. Im Studium reicht in der Regel das classpath-Modell, das Modulsystem ist meist nur ein Randthema.

Merke: import ist reine Kompilierzeit-Bequemlichkeit (kurzer Name statt voll qualifiziert), classpath/modulepath ist die Laufzeit-Suchstrategie für die Bytecode-Dateien. Beides hat nichts miteinander zu tun, ein fehlender Import ist ein anderes Problem als eine Klasse, die nicht im classpath liegt.

Klassen aus java.lang (String, System, Math, Integer, Object ...) sind automatisch importiert (laut Sprachregel immer verfügbar; in modernen Java-Versionen stammen sie aus dem Standardmodul java.base). Du musst sie NIE explizit importieren. Deshalb funktioniert System.out.println ohne import.

Diese Meldungen siehst du in Eclipse oder IntelliJ am häufigsten, und sie sind fast immer Paket-/Import-bezogen:

  • "The declared package X does not match the expected package Y" (Eclipse): Deine package-Zeile und der Ordnerpfad unter dem Source-Root passen nicht zusammen. Datei verschieben oder package-Zeile anpassen.
  • "cannot find symbol" / "Cannot resolve symbol 'ArrayList'": Der Import fehlt oder ist falsch geschrieben. IDE-Quickfix (Alt+Enter in IntelliJ, Strg+Shift+O in Eclipse) ergänzt ihn automatisch.
  • "package X does not exist": Das Paket ist nicht im classpath, oft eine fehlende Bibliothek/Dependency oder ein Tippfehler im Paketnamen.

Erinnerung aus dem Sichtbarkeits-Topic: ohne Modifier ist eine Klasse / ein Feld / eine Methode package-private, nur im selben Paket zugreifbar.

package de.unihamburg.studi;

class InternalHelper {  // package-private!
    void log(String msg) { /* ... */ }
}

Diese Klasse ist NICHT von außerhalb de.unihamburg.studi zugreifbar. Praktisch für interne Helper-Klassen, die nicht Teil der öffentlichen API sein sollen.

Du hast zwei Klassen mit gleichem Namen aus unterschiedlichen Paketen:

import java.util.Date;
// import java.sql.Date;  // Geht NICHT, Konflikt mit oberer Zeile

java.util.Date heute = new java.util.Date();
java.sql.Date dbDatum = new java.sql.Date(0);

Lösung: Eine importieren, die andere voll qualifiziert nutzen.

ModifierEigene KlasseSelbes PaketSubklasse (anderes Paket)Anderes Paket
public✅✅✅✅
protected✅✅✅❌
(kein)✅✅❌❌
private✅❌❌❌

Bei Klausur-Fragen "Hat Klasse Z in Paket P Zugriff auf Feld f in Klasse X in Paket Q?" → diese Tabelle ist deine Antwort.

Feinheit bei protected (Java-Spezialfall): Eine Subklasse in einem anderen Paket darf ein geerbtes protected-Member nur über this/super oder über eine Referenz vom eigenen Subklassen-Typ nutzen, nicht über eine fremde Instanz der Superklasse. Beispiel: web.OnlineKonto extends bank.Konto darf this.saldo lesen (geerbt), aber fremdesKonto.saldo (eine reine bank.Konto-Instanz) ist verboten. protected ist also offener als package-private, aber kein freier Zugriff von überall.

// in web.OnlineKonto extends bank.Konto (anderes Paket als bank)
this.saldo = 100;          // OK: eigenes geerbtes Member ueber this
OnlineKonto eigenes = new OnlineKonto();
eigenes.saldo = 100;       // OK: Zugriff ueber den eigenen Subklassen-Typ
Konto fremd = new Konto();
fremd.saldo = 50;          // FEHLER: reine Superklassen-Instanz, protected greift hier nicht
src/
├── de/uni/main/
│   └── App.java               // package de.uni.main; public class App { ... }
├── de/uni/model/
│   ├── Student.java           // package de.uni.model; public class Student { ... }
│   └── Kurs.java
└── de/uni/util/
    └── Logger.java            // package de.uni.util; public class Logger { ... }

In App.java:

package de.uni.main;

import de.uni.model.Student;
import de.uni.model.Kurs;
import de.uni.util.Logger;

public class App {
    public static void main(String[] args) {
        Student s = new Student("Anna");
        Kurs k = new Kurs("Java");
        Logger.log("App gestartet");
    }
}

1. package muss erste Code-Zeile sein. Davor nur Kommentare. Sonst Compile-Error.

2. Dateipfad passt zum Paket (Projektkonvention). In IDE-/Maven-/Gradle-Projekten gehört package de.uni.test; in die Datei unter <source-root>/de/uni/test/. Sprachlich bestimmt die package-Zeile nur den voll qualifizierten Namen, aber die Build-Tools erwarten genau diese Ordnerstruktur.

3. import kommt zwischen package und Klasse. Reihenfolge: package → imports → class.

4. java.lang ist auto-importiert. String, System, Math, Object brauchen kein import.

5. Wildcard-Import vs. Einzelimport: java.util.* ist erlaubt, erschwert aber die Lesbarkeit, weil man nicht sofort sieht, welche Klassen tatsächlich genutzt werden. IDE-Standard ist der Einzelimport.

1. Falsche package-Zeile. Wenn die Datei unter src/de/uni/Student.java liegt, aber package com.firma; deklariert, beschwert sich die IDE bzw. das Build-Tool ("declared package does not match expected package"). Entweder die Datei in den passenden Ordner verschieben oder die package-Zeile korrigieren.

2. import * macht Wildcard-Member NICHT zugreifbar. import java.util.* lädt nur Klassen, nicht statische Member. Für PI brauchst du import static java.lang.Math.PI.

3. Inneres Paket nicht implizit importiert. import java.util.* importiert NICHT java.util.concurrent.*. Du musst jede Unterebene separat importieren.

4. package-private vs. public verwechselt. Ohne public ist die Klasse nur im selben Paket nutzbar. Für eine wirklich öffentliche Klasse: public class.

5. protected ≠ "geschützt vor anderen Paketen". Genau das Gegenteil: protected ERLAUBT Zugriff aus anderen Paketen für SUBKLASSEN. package-private wäre stricter.

Beispiel (typischer Klausur-Stil, zur Übung konstruiert).

Gegeben ist folgende Projektstruktur unter dem Source-Root src/:

src/
├── de/uni/model/
│   └── Student.java     // public class Student, Feld: protected String name
└── de/uni/main/
    └── App.java         // soll Student nutzen

(a) Welche package-Zeile gehört an den Anfang von Student.java? (b) Welche import-Zeile braucht App.java, damit es Student mit kurzem Namen verwenden kann, und wo im Datei-Aufbau steht sie? (c) App liegt im Paket de.uni.main und ist keine Subklasse von Student. Kann App direkt auf das Feld name (protected) zugreifen? Begründe mit der Sichtbarkeits-Tabelle.

Lösung:

  • (a) package de.uni.model; als erste Code-Zeile (vor dieser Zeile nur Kommentare). Der Source-Root src/ zählt nicht zum Paketnamen.
  • (b) import de.uni.model.Student;. Die Reihenfolge in der Datei ist fest: zuerst die package de.uni.main;-Zeile, dann die import-Zeilen, danach die public class App.
  • (c) Nein. protected erlaubt Zugriff im selben Paket und aus Subklassen, aber App ist in einem anderen Paket (de.uni.main statt de.uni.model) und keine Subklasse von Student. In der Tabelle entspricht das der Spalte "Anderes Paket" für protected → ❌. Lösungswege: name auf public setzen oder einen public String getName()-Getter anbieten.

So liest du solche Aufgaben: Erst die Paketzugehörigkeit jeder Klasse bestimmen, dann pro Zugriff in die Sichtbarkeits-Tabelle schauen (selbes Paket? Subklasse? anderes Paket?).

Eine Mini-Projekt-Struktur mit 3 Paketen. Klick auf eine Klasse: du siehst, welche Imports sie braucht und welche Sichtbarkeits-Beziehungen zu anderen Klassen existieren.

Wechsle zwischen den Paketen, um zu sehen, wann ein Import nötig wird und wann nicht. So entwickelst du ein Gefühl, wie Pakete und Imports in einem realen Projekt zusammenspielen.

Statische Vorschau (Fallback für PDF/Print) derselben Struktur, die der Visualizer interaktiv macht:

src/                          ← Source-Root (kein Teil des Paketnamens)
└── de/uni/
    ├── main/App.java         → package de.uni.main;   import de.uni.model.Student;
    ├── model/Student.java    → package de.uni.model;  public class Student
    └── util/Logger.java      → package de.uni.util;   public class Logger

Jeder Ordner unter src/ ist ein Stück des Paketnamens; App braucht Imports für Student und Logger, weil beide in anderen Paketen liegen.

Lade Visualisierung...

Klausur-Tipp: Bei Klausurfragen zur Sichtbarkeit zwischen Paketen, zeichne dir die Paket-Baum-Struktur kurz auf, markiere die Modifier (public/protected/private/package-private) und gehe die Tabelle durch. Spart Fehler.


Drei interaktive Demos zu den Kernmechanismen dieses Themas. Klick Step oder Auto und beobachte, wie sich der aufgelöste Klassenname, die Variablen und die Konsole pro Schritt verändern.

1. Import-Auflösung: voll qualifiziert vs. import

Der Compiler ersetzt den kurzen Namen ArrayList gedanklich durch den voll qualifizierten Namen java.util.ArrayList. Genau das macht der import für dich.

Lade Visualisierung...

Ohne die import-Zeile wäre exakt derselbe Code nur mit voll qualifiziertem Namen möglich: java.util.ArrayList<String> liste = new java.util.ArrayList<>();. Der import spart dir also nur Tipparbeit, an der Funktion ändert er nichts.

2. Namens-Konflikt auflösen: zwei Date-Klassen

java.util.Date und java.sql.Date heißen beide Date. Du kannst nur eine davon importieren, die andere musst du voll qualifiziert ansprechen.

Lade Visualisierung...

Merke: Ein zweiter Import import java.sql.Date; zusätzlich zum ersten gäbe einen Compile-Fehler, weil der kurze Name Date dann doppelt belegt wäre. Die saubere Lösung ist immer: eine Klasse importieren, die andere voll qualifiziert nutzen.

3. Sichtbarkeit zwischen Paketen: protected im Zugriffstest

Klasse Konto (Paket bank) hat protected double saldo. Wir prüfen Schritt für Schritt, wer darauf zugreifen darf, der häufigste Klausur-Aufgabentyp.

Lade Visualisierung...

Klausur-Tipp: Bei "Hat Klasse Z Zugriff auf Member m?" immer zwei Fragen klären: (1) Liegt Z im selben Paket wie die deklarierende Klasse? (2) Ist Z eine Subklasse, und greift sie über den eigenen Typ (this/super) oder über eine fremde Superklassen-Instanz zu? Mit diesen zwei Fragen plus der Sichtbarkeits-Tabelle löst du solche Aufgaben sicher.

Anmelden, um den Fortschritt zu speichern.

Nächster Schritt

Wenn du fertig bist: jetzt üben.

Aktives Abrufen festigt Wissen schneller als nochmal lesen.

War das hilfreich?

Verwandte Themen

  • Variablen und Datentypen
  • Bedingungen
  • Schleifen
  • Funktionen
  • Rekursion

Tools

Bald: Karteikarten · Spaced-Repetition · Mind-Map-Export

Fachliche Qualität
S-Tier · GoldstandardZuletzt geprüft am 12.06.2026

Diese Lerneinheit wurde für typische Bachelor-Klausuren konzipiert. So prüfen wir · Fehler entdeckt? Melde ihn uns oder markiere die fragliche Stelle direkt im Text oben.

Klausur-ÜbersichtKomplette Übersicht: alle Tabs als linearer Text zum Lernen
▾

Alle Tabs der Lerneinheit (Erklärung · Interaktiv verstehen · Praxis-Übung · Klausur-Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).

Inhalt dieser Übersicht

  1. Erklärung(Erklärung)
  2. Interaktiv verstehen(Visualisierung / Interaktiv)
  3. Praxis-Übung(Quiz / Klausurfragen)
  4. Klausur-Quiz(Quiz / Klausurfragen)
Teil 1·Erklärung

Erklärung

Stell dir vor du baust ein größeres Programm. Hunderte Klassen. Manche heißen Util, List, Logger. Wie verhinderst du, dass deine User mit der User aus einer fremden Library kollidiert, ohne ständig den vollen Pfad mitzuschleppen? Pakete sind Javas Antwort: zusammengehörige Klassen werden in Namensräumen gebündelt, organisiert wie Ordner. Und Imports holen dir Klassen aus anderen Paketen herein, sodass du sie kurz beim Namen nennen kannst statt jedes Mal den langen Paket-Pfad davorzuschreiben.

Du lernst hier, wie eine package-Deklaration eine Klasse einem Namensraum zuordnet, wie der voll qualifizierte Name (fully qualified name = Paket plus Klassenname, z. B. java.util.ArrayList) entsteht, wie import, Wildcard-Import und import static funktionieren. Außerdem, warum java.lang automatisch verfügbar ist, was der Source-Root mit der Verzeichnisstruktur zu tun hat, wie classpath/modulepath die Klassen zur Laufzeit findet und welche IDE-Fehlermeldungen typisch sind. Wie genau Sichtbarkeit (public, protected, package-private, private) zwischen Paketen wirkt, schauen wir uns weiter unten in den Abschnitten Sichtbarkeit auf Paket-Ebene und Sichtbarkeits-Übersicht mit Paketen an, das ist der zweite große Klausur-Block dieses Themas.

Klausur-Relevanz: package/import ist in WInf-Prog-1-Klausuren ein typischer Frage-Block. Übliche Formulierungen sind: "Wie sieht der Import-Pfad aus?", "Was ist der Unterschied zwischen package und import?", "Welche package-Zeile gehört in diese Datei?".

Die Idee in einem Satz

Paket (package): Eine Gruppe zusammengehöriger Klassen mit eindeutigem Namensraum, organisiert wie Ordner. Import: Mache Klassen aus anderen Paketen ohne ihren vollen Paket-Pfad (den voll qualifizierten Namen) nutzbar.

Package-Deklaration

package de.unihamburg.studi;  // erste Code-Zeile in der Datei!

public class Student {
    private String name;
    // ...
}

Konvention: Pakete sind kleingeschrieben, durch Punkte getrennt, oft mit umgekehrtem Domain-Namen als Präfix (com.firma.projekt, de.uni.fachbereich). Damit machst du weltweit eindeutige Namen sehr wahrscheinlich, sofern du eine eigene Domain bzw. Organisation als Präfix nutzt. Technisch erzwingt Java das aber nicht.

Sprachregel vs. Projektkonvention

Hier lohnt sich eine präzise Unterscheidung, die in Klausuren oft schwammig dargestellt wird:

  • Sprachregel (gilt immer, JLS): Die package-Zeile bestimmt den voll qualifizierten Namen der Klasse. Aus package de.unihamburg.studi; plus class Student wird de.unihamburg.studi.Student. Das ist unabhängig davon, in welchem Ordner die Datei physisch liegt.
  • Projekt- und Tooling-Konvention (Standardfall): In normalen IDE-, Maven- oder Gradle-Projekten muss die Ordnerstruktur relativ zum Source-Root zum Paketnamen passen, sonst findet das Build-Tool die Klasse oft nicht korrekt oder meckert beim Kompilieren. Eclipse, IntelliJ, Maven und Gradle erwarten de/unihamburg/studi/Student.java unter dem Source-Root.

Fortgeschrittenes Detail (nicht klausurrelevant): Der nackte javac-Compiler ist toleranter: Über -sourcepath und -d (Ausgabeordner) kann er Quelldateien auch aus anderen Ordnern übersetzen. Verlass dich darauf aber nie im Projektalltag, halte dich an die Konvention, dann passt alles automatisch.

Kleingedrucktes zur package-Zeile: Falls eine package-Deklaration vorhanden ist, steht sie vor allen imports und Typdeklarationen, davor höchstens Kommentare/Whitespace oder Package-Annotationen. Eine Datei ganz ohne package-Zeile liegt im Default-Package (in echten Projekten unüblich).

Standard-Verzeichnisstruktur (so erwartet es deine IDE):

src/                         ← Source-Root (zählt NICHT zum Paketnamen)
└── de/
    └── unihamburg/
        └── studi/
            └── Student.java   ← package de.unihamburg.studi;

Lies die Baumstruktur von oben nach unten: Jeder Ordner unter dem Source-Root src/ ist ein Stück des Paketnamens. Der Source-Root selbst (src/) gehört nicht dazu, deshalb heißt das Paket de.unihamburg.studi und nicht src.de.unihamburg.studi. Weiter unten im Abschnitt Interaktiv verstehen kannst du mit dem Paket-Baum-Visualizer genau dieses Zusammenspiel aus package-Zeile, Dateipfad und Import live durchklicken.

Import: Klassen nutzen

Ohne Import musst du den voll qualifizierten Namen (fully qualified name, also Paket plus Klassenname) schreiben:

java.util.ArrayList<String> liste = new java.util.ArrayList<>();

Mit Import wird das kurz:

import java.util.ArrayList;

ArrayList<String> liste = new ArrayList<>();

Import-Varianten:

import java.util.ArrayList;    // Einzelimport
import java.util.*;             // Alles aus java.util (Wildcard)
import static java.lang.Math.PI; // Statische Member direkt nutzbar

Nach import static java.lang.Math.PI kannst du PI statt Math.PI schreiben, nützlich, aber es kann unklar werden, wenn du nicht weißt, woher das Symbol kommt.

classpath und modulepath: wie Java die Klassen findet

Der import löst nur den kurzen Namen auf, er sagt nichts darüber, wo die .class-Dateien physisch liegen. Das übernimmt der classpath (klassisch) bzw. der modulepath (ab dem Java-Modulsystem, Java 9+).

  • classpath: eine Liste von Verzeichnissen und JAR-Dateien, in denen der Compiler und die JVM nach kompilierten Klassen suchen. Setzbar über -classpath / -cp oder die Umgebungsvariable CLASSPATH. Findet die JVM die Klasse zur Laufzeit nicht, fliegt eine NoClassDefFoundError oder ClassNotFoundException, obwohl der Code sauber kompiliert hat. Faustregel: Bei normal referenzierten Klassen siehst du meist einen NoClassDefFoundError; eine ClassNotFoundException kommt typischerweise beim expliziten Laden über Class.forName(...) oder ClassLoader.loadClass(...).
  • modulepath: das modernere Pendant, wenn dein Projekt eine module-info.java mit requires/exports hat. Im Studium reicht in der Regel das classpath-Modell, das Modulsystem ist meist nur ein Randthema.

Merke: import ist reine Kompilierzeit-Bequemlichkeit (kurzer Name statt voll qualifiziert), classpath/modulepath ist die Laufzeit-Suchstrategie für die Bytecode-Dateien. Beides hat nichts miteinander zu tun, ein fehlender Import ist ein anderes Problem als eine Klasse, die nicht im classpath liegt.

java.lang ist auto-importiert

Klassen aus java.lang (String, System, Math, Integer, Object ...) sind automatisch importiert (laut Sprachregel immer verfügbar; in modernen Java-Versionen stammen sie aus dem Standardmodul java.base). Du musst sie NIE explizit importieren. Deshalb funktioniert System.out.println ohne import.

Typische IDE-Fehler

Diese Meldungen siehst du in Eclipse oder IntelliJ am häufigsten, und sie sind fast immer Paket-/Import-bezogen:

  • "The declared package X does not match the expected package Y" (Eclipse): Deine package-Zeile und der Ordnerpfad unter dem Source-Root passen nicht zusammen. Datei verschieben oder package-Zeile anpassen.
  • "cannot find symbol" / "Cannot resolve symbol 'ArrayList'": Der Import fehlt oder ist falsch geschrieben. IDE-Quickfix (Alt+Enter in IntelliJ, Strg+Shift+O in Eclipse) ergänzt ihn automatisch.
  • "package X does not exist": Das Paket ist nicht im classpath, oft eine fehlende Bibliothek/Dependency oder ein Tippfehler im Paketnamen.

Sichtbarkeit auf Paket-Ebene

Erinnerung aus dem Sichtbarkeits-Topic: ohne Modifier ist eine Klasse / ein Feld / eine Methode package-private, nur im selben Paket zugreifbar.

package de.unihamburg.studi;

class InternalHelper {  // package-private!
    void log(String msg) { /* ... */ }
}

Diese Klasse ist NICHT von außerhalb de.unihamburg.studi zugreifbar. Praktisch für interne Helper-Klassen, die nicht Teil der öffentlichen API sein sollen.

Namens-Konflikte lösen

Du hast zwei Klassen mit gleichem Namen aus unterschiedlichen Paketen:

import java.util.Date;
// import java.sql.Date;  // Geht NICHT, Konflikt mit oberer Zeile

java.util.Date heute = new java.util.Date();
java.sql.Date dbDatum = new java.sql.Date(0);

Lösung: Eine importieren, die andere voll qualifiziert nutzen.

Sichtbarkeits-Übersicht mit Paketen

ModifierEigene KlasseSelbes PaketSubklasse (anderes Paket)Anderes Paket
public✅✅✅✅
protected✅✅✅❌
(kein)✅✅❌❌
private✅❌❌❌

Bei Klausur-Fragen "Hat Klasse Z in Paket P Zugriff auf Feld f in Klasse X in Paket Q?" → diese Tabelle ist deine Antwort.

Feinheit bei protected (Java-Spezialfall): Eine Subklasse in einem anderen Paket darf ein geerbtes protected-Member nur über this/super oder über eine Referenz vom eigenen Subklassen-Typ nutzen, nicht über eine fremde Instanz der Superklasse. Beispiel: web.OnlineKonto extends bank.Konto darf this.saldo lesen (geerbt), aber fremdesKonto.saldo (eine reine bank.Konto-Instanz) ist verboten. protected ist also offener als package-private, aber kein freier Zugriff von überall.

// in web.OnlineKonto extends bank.Konto (anderes Paket als bank)
this.saldo = 100;          // OK: eigenes geerbtes Member ueber this
OnlineKonto eigenes = new OnlineKonto();
eigenes.saldo = 100;       // OK: Zugriff ueber den eigenen Subklassen-Typ
Konto fremd = new Konto();
fremd.saldo = 50;          // FEHLER: reine Superklassen-Instanz, protected greift hier nicht

Beispiel: Mini-Projekt-Struktur

src/
├── de/uni/main/
│   └── App.java               // package de.uni.main; public class App { ... }
├── de/uni/model/
│   ├── Student.java           // package de.uni.model; public class Student { ... }
│   └── Kurs.java
└── de/uni/util/
    └── Logger.java            // package de.uni.util; public class Logger { ... }

In App.java:

package de.uni.main;

import de.uni.model.Student;
import de.uni.model.Kurs;
import de.uni.util.Logger;

public class App {
    public static void main(String[] args) {
        Student s = new Student("Anna");
        Kurs k = new Kurs("Java");
        Logger.log("App gestartet");
    }
}

Klausur-Faustregeln

1. package muss erste Code-Zeile sein. Davor nur Kommentare. Sonst Compile-Error.

2. Dateipfad passt zum Paket (Projektkonvention). In IDE-/Maven-/Gradle-Projekten gehört package de.uni.test; in die Datei unter <source-root>/de/uni/test/. Sprachlich bestimmt die package-Zeile nur den voll qualifizierten Namen, aber die Build-Tools erwarten genau diese Ordnerstruktur.

3. import kommt zwischen package und Klasse. Reihenfolge: package → imports → class.

4. java.lang ist auto-importiert. String, System, Math, Object brauchen kein import.

5. Wildcard-Import vs. Einzelimport: java.util.* ist erlaubt, erschwert aber die Lesbarkeit, weil man nicht sofort sieht, welche Klassen tatsächlich genutzt werden. IDE-Standard ist der Einzelimport.

Häufige Stolpersteine

1. Falsche package-Zeile. Wenn die Datei unter src/de/uni/Student.java liegt, aber package com.firma; deklariert, beschwert sich die IDE bzw. das Build-Tool ("declared package does not match expected package"). Entweder die Datei in den passenden Ordner verschieben oder die package-Zeile korrigieren.

2. import * macht Wildcard-Member NICHT zugreifbar. import java.util.* lädt nur Klassen, nicht statische Member. Für PI brauchst du import static java.lang.Math.PI.

3. Inneres Paket nicht implizit importiert. import java.util.* importiert NICHT java.util.concurrent.*. Du musst jede Unterebene separat importieren.

4. package-private vs. public verwechselt. Ohne public ist die Klasse nur im selben Paket nutzbar. Für eine wirklich öffentliche Klasse: public class.

5. protected ≠ "geschützt vor anderen Paketen". Genau das Gegenteil: protected ERLAUBT Zugriff aus anderen Paketen für SUBKLASSEN. package-private wäre stricter.

Klausur-Beispielaufgabe

Beispiel (typischer Klausur-Stil, zur Übung konstruiert).

Gegeben ist folgende Projektstruktur unter dem Source-Root src/:

src/
├── de/uni/model/
│   └── Student.java     // public class Student, Feld: protected String name
└── de/uni/main/
    └── App.java         // soll Student nutzen

(a) Welche package-Zeile gehört an den Anfang von Student.java? (b) Welche import-Zeile braucht App.java, damit es Student mit kurzem Namen verwenden kann, und wo im Datei-Aufbau steht sie? (c) App liegt im Paket de.uni.main und ist keine Subklasse von Student. Kann App direkt auf das Feld name (protected) zugreifen? Begründe mit der Sichtbarkeits-Tabelle.

Lösung:

  • (a) package de.uni.model; als erste Code-Zeile (vor dieser Zeile nur Kommentare). Der Source-Root src/ zählt nicht zum Paketnamen.
  • (b) import de.uni.model.Student;. Die Reihenfolge in der Datei ist fest: zuerst die package de.uni.main;-Zeile, dann die import-Zeilen, danach die public class App.
  • (c) Nein. protected erlaubt Zugriff im selben Paket und aus Subklassen, aber App ist in einem anderen Paket (de.uni.main statt de.uni.model) und keine Subklasse von Student. In der Tabelle entspricht das der Spalte "Anderes Paket" für protected → ❌. Lösungswege: name auf public setzen oder einen public String getName()-Getter anbieten.

So liest du solche Aufgaben: Erst die Paketzugehörigkeit jeder Klasse bestimmen, dann pro Zugriff in die Sichtbarkeits-Tabelle schauen (selbes Paket? Subklasse? anderes Paket?).

Teil 2·Visualisierung / Interaktiv

Interaktiv verstehen

Paket-Baum-Visualizer

Eine Mini-Projekt-Struktur mit 3 Paketen. Klick auf eine Klasse: du siehst, welche Imports sie braucht und welche Sichtbarkeits-Beziehungen zu anderen Klassen existieren.

Wechsle zwischen den Paketen, um zu sehen, wann ein Import nötig wird und wann nicht. So entwickelst du ein Gefühl, wie Pakete und Imports in einem realen Projekt zusammenspielen.

Statische Vorschau (Fallback für PDF/Print) derselben Struktur, die der Visualizer interaktiv macht:

src/                          ← Source-Root (kein Teil des Paketnamens)
└── de/uni/
    ├── main/App.java         → package de.uni.main;   import de.uni.model.Student;
    ├── model/Student.java    → package de.uni.model;  public class Student
    └── util/Logger.java      → package de.uni.util;   public class Logger

Jeder Ordner unter src/ ist ein Stück des Paketnamens; App braucht Imports für Student und Logger, weil beide in anderen Paketen liegen.

Interaktive Visualisierung

Interaktive Komponente: probiere sie im Topic-Player oben aus.

Klausur-Tipp: Bei Klausurfragen zur Sichtbarkeit zwischen Paketen, zeichne dir die Paket-Baum-Struktur kurz auf, markiere die Modifier (public/protected/private/package-private) und gehe die Tabelle durch. Spart Fehler.


Code-Stepper: Schritt für Schritt durchspielen

Drei interaktive Demos zu den Kernmechanismen dieses Themas. Klick Step oder Auto und beobachte, wie sich der aufgelöste Klassenname, die Variablen und die Konsole pro Schritt verändern.

1. Import-Auflösung: voll qualifiziert vs. import

Der Compiler ersetzt den kurzen Namen ArrayList gedanklich durch den voll qualifizierten Namen java.util.ArrayList. Genau das macht der import für dich.

Interaktive Visualisierung

Interaktive Komponente: probiere sie im Topic-Player oben aus.

Ohne die import-Zeile wäre exakt derselbe Code nur mit voll qualifiziertem Namen möglich: java.util.ArrayList<String> liste = new java.util.ArrayList<>();. Der import spart dir also nur Tipparbeit, an der Funktion ändert er nichts.

2. Namens-Konflikt auflösen: zwei Date-Klassen

java.util.Date und java.sql.Date heißen beide Date. Du kannst nur eine davon importieren, die andere musst du voll qualifiziert ansprechen.

Interaktive Visualisierung

Interaktive Komponente: probiere sie im Topic-Player oben aus.

Merke: Ein zweiter Import import java.sql.Date; zusätzlich zum ersten gäbe einen Compile-Fehler, weil der kurze Name Date dann doppelt belegt wäre. Die saubere Lösung ist immer: eine Klasse importieren, die andere voll qualifiziert nutzen.

3. Sichtbarkeit zwischen Paketen: protected im Zugriffstest

Klasse Konto (Paket bank) hat protected double saldo. Wir prüfen Schritt für Schritt, wer darauf zugreifen darf, der häufigste Klausur-Aufgabentyp.

Interaktive Visualisierung

Interaktive Komponente: probiere sie im Topic-Player oben aus.

Klausur-Tipp: Bei "Hat Klasse Z Zugriff auf Member m?" immer zwei Fragen klären: (1) Liegt Z im selben Paket wie die deklarierende Klasse? (2) Ist Z eine Subklasse, und greift sie über den eigenen Typ (this/super) oder über eine fremde Superklassen-Instanz zu? Mit diesen zwei Fragen plus der Sichtbarkeits-Tabelle löst du solche Aufgaben sicher.

Teil 3·Quiz / Klausurfragen

Praxis-Übung

Pakete & Imports, Praxis-Übung

6 Aufgaben zu Paket-Deklaration, Imports, Sichtbarkeits-Regeln.

Klausurfragen mit Lösungen (6)

F1.Welche Zeile muss in einer Java-Datei ZUERST stehen (nach Kommentaren)?

Antwort: Die package-Deklaration

Erklärung: Reihenfolge ist FEST: package → imports → class. Wenn package falsch oder fehlt, gibt's Compile-Error. import kommt danach, dann erst die Klassen-Deklaration.

F2.Aus welchem Paket sind Klassen wie String, System, Math, Object IMMER ohne import nutzbar?

Antwort: java.lang

Erklärung: java.lang ist auto-importiert. Deshalb funktioniert System.out.println ohne import. Alle anderen Pakete (java.util, java.io, java.nio) brauchen explizite Imports.

F3.Eine Klasse OHNE Modifier (z.B. class Helper { ... }) ist von überall im selben Paket zugreifbar.

Antwort: Wahr

Erklärung: RICHTIG. Ohne Modifier ist die Sichtbarkeit package-private (auch 'default'). Im selben Paket erreichbar, in anderen Paketen NICHT (auch nicht via import).

Typ: Wahr/Falsch

F4.Welcher Import erlaubt direkten Zugriff auf PI (statt Math.PI)?

Antwort: import static java.lang.Math.PI;

Erklärung: import static erlaubt direkten Zugriff auf statische Member. Mit `import static java.lang.Math.PI` schreibst du `double u = 2 * PI * r;` statt `Math.PI`. Wildcard ginge: `import static java.lang.Math.*;`

F5.Welche Aussagen über Pakete sind RICHTIG?

Richtige Antworten: Paket-Namen sind kleingeschrieben (Konvention); package-Deklaration muss vor allen imports stehen; In IDE-/Maven-/Gradle-Projekten muss die Datei-Position (relativ zum Source-Root) zum Paket passen; java.lang ist auto-importiert

Erklärung: Richtig: lowercase, package vor import, java.lang ist auto. Auch richtig: In gängigen IDE-/Maven-/Gradle-Projekten muss der Dateipfad relativ zum Source-Root zum Paket passen (Tooling-Konvention; sprachlich bestimmt die package-Zeile allein den voll qualifizierten Namen). Falsch: Wildcard-Import importiert KEINE Unter-Pakete (java.util.concurrent muss separat); für statische Member braucht's `import static`.

Typ: Multi-Select

F6.Ordne den Sichtbarkeits-Modifier dem Zugriff zwischen Paketen zu:

Zuordnungen:

  • public → Überall, auch in anderen Paketen
  • protected → Selbes Paket + Subklassen (auch in anderen Paketen)
  • (kein Modifier) → Nur im selben Paket
  • private → Nur in der eigenen Klasse

Erklärung: Klassische Sichtbarkeits-Matrix. Bei Klausurfragen 'kann Z von Paket P auf X.f zugreifen?' diese Tabelle anlegen.

Typ: Zuordnung

Teil 4·Quiz / Klausurfragen

Klausur-Quiz

Klausurfragen mit Lösungen (6)

F1.Datei unter src/de/uni/test/A.java. Welche package-Deklaration ist korrekt?

Antwort: package de.uni.test;

Erklärung: Der Source-Root (`src/`) zählt NICHT zum Paket-Namen. Paket = Verzeichnis-Pfad RELATIV zum Source-Root, mit Punkten statt Schrägstrichen.

F2.Klasse A in Paket p1, Klasse B extends A in Paket p2. Welcher Modifier in A erlaubt B, das geerbte Feld f über this.f/super.f zu nutzen?

Antwort: protected

Erklärung: protected: erlaubt Zugriff aus Subklassen, auch in anderen Paketen, allerdings nur über den eigenen Subklassen-Typ (`this.f`/`super.f` oder eine `B`-Referenz), NICHT über eine fremde `A`-Instanz (`A a = new A(); a.f` wäre verboten). package-private wäre zu strikt (nur selbes Paket). private nur in A selbst. public erlaubt, aber nicht nötig.

F3.Du kannst in einer Java-Datei mehrere package-Deklarationen haben.

Antwort: Falsch

Erklärung: FALSCH. Genau EINE package-Deklaration pro Datei (oder gar keine = default-Paket). Mehrere imports sind erlaubt, aber package ist einmalig.

Typ: Wahr/Falsch

F4.Du importierst java.util.Date und java.sql.Date in derselben Datei. Was passiert?

Antwort: Compile-Fehler, Namens-Konflikt

Erklärung: Compile-Fehler: zwei Imports mit gleichem Klassennamen sind nicht erlaubt. Lösung: einen importieren, den anderen voll qualifiziert nutzen (`java.sql.Date dbDate = ...`).

F5.Pakete sind {{1}} geschrieben. Die {{2}}-Deklaration muss die ERSTE Code-Zeile sein. Klassen aus {{3}} sind automatisch importiert. Ohne Modifier ist eine Klasse {{4}} (auch default genannt).

Lösungen pro Lücke:

  • {{1}}: klein / kleingeschrieben / lowercase
  • {{2}}: package
  • {{3}}: java.lang
  • {{4}}: package-private / package private

Erklärung: Standard-Pflichtwissen über Pakete. lowercase-Konvention, package zuerst, java.lang auto, package-private als Default.

Typ: Lückentext

F6.Sortiere die Reihenfolge in einer Java-Datei:

Richtige Reihenfolge:

  1. Kommentar / Lizenz-Header
  2. package de.uni.test;
  3. import java.util.ArrayList; (und weitere)
  4. public class MyClass { ... }

Erklärung: Reihenfolge ist FEST in Java: optionale Kommentare → package (genau 1) → imports (beliebig viele) → Klassen. Tauschen → Compile-Error.

Typ: Reihenfolge

Zur KategorieProgrammiergrundlagen.Mehr Themen entdeckenZum Themen-Hub.

UniProMax ist eine themenbasierte Lernplattform für Studierende an deutschen Unis.

Wir glauben, dass Verstehen besser ist als Auswendiglernen. Wir bauen Lerneinheiten die zeigen statt erzählen. Code, Visualisierung, Quiz. Auf Deutsch.

Marke

UniProMaxUniProMax

Themenbasiert, visuell, interaktiv.

Inhalte

  • Alle Themen (Hub)
  • Programmiergrundlagen
  • Algorithmen
  • Mathematik
  • Statistik
  • Datenbanken
  • Rechnungswesen
  • VWL

Studiengang-Filter

  • Informatik
  • Wirtschaftsinformatik
  • BWL
  • Data Science
  • VWL
  • Wirtschaftsingenieurwesen
  • Mathe
  • Psychologie
  • weitere Studiengänge folgen

Plattform

  • Mein Fortschritt
  • Impressum
  • Datenschutz
© 2026 UniProMaxAlle Systeme onlinev0.2 / Sommersemester 2026
UniProMaxUniProMaxUniProMaxUniProMax