java module imports feature imagejava module imports feature image
HappyCoders Glasses

import module in Java: Module Import Declarations

Sven Woltmann
Sven Woltmann
Aktualisiert: 7. Juni 2026

In diesem Artikel erfährst du:

  • Wie können mit import module ganze Java-Module importiert werden?
  • Wie können dabei Mehrdeutigkeiten aufgelöst werden?
  • Was sind transitive Modul-Importe, und wie funktionieren sie?
  • Welche Module werden standardmäßig importiert?

Beginnen wir mit einem ganz kurzen Rückblick...

Java Imports

Seit Java 1.0 können wir mit dem import-Statement einzelne Klassen („single-type-import declaration“) oder ganze Pakete („type-import-on-demand declaration“) importieren, z. B. wie folgt:

import java.util.*;
import java.util.stream.Stream;Code-Sprache: Java (java)

Die Klassen des Pakets java.lang werden seit jeher automatisch importiert. Deshalb müssen wir für Klassen wie Object, String, Integer, Exception, usw. keine import-Statements angeben.

Module Import Declarations

Mit import module können wir seit Java 25 (und in Java 23 und Java 24 im Preview-Modus) auch ganze Module importieren. Dadurch können wir alle Klassen, die sich innerhalb eines Moduls befinden und von diesem exportiert werden, direkt verwenden.

Im folgenden Beispiel importieren wir das Modul java.base und können dadurch die Klassen List, Map, Stream und Collectors verwenden, ohne sie einzeln oder paketweise importieren zu müssen (String und Character liegen im Paket java.lang und wurden daher schon immer automatisch importiert).

import module java.base;

public class ModuleImportTest {

    public static Map<Character, List<String>> groupByFirstLetter(String... values) {
        return Stream.of(values).collect(
                Collectors.groupingBy(s -> Character.toUpperCase(s.charAt(0))));
    }
}Code-Sprache: Java (java)

Wenn du dieses Code-Beispiel in der Datei ModuleImportTest.java speicherst, kannst du die Klasse seit Java 25 wie folgt kompilieren (in Java 23/24 war import module ein Preview-Feature und musste mit --enable-preview --source <Version> aktiviert werden):

javac ModuleImportTest.javaCode-Sprache: Klartext (plaintext)

Um import module zu verwenden, ist es – wie im vorangegangenen Beispiel gesehen – nicht nötig, dass sich die importierende Klasse selbst in einem Modul befindet.

Compact Source Files (zuvor bekannt als „Implizit deklarierte Klassen“ und „simple source files“) und JShell importieren automatisch das java.base-Modul, d. h. Klassen wie List und Map kannst du dort ohne explizite Imports verwenden.

Mehrdeutige Klassennamen

Manchmal kommt es vor, dass ein Klassenname nicht eindeutig ist. In folgendem Beispiel gibt es eine List-Klasse sowohl im importierten Modul java.base (java.util.List) als auch im Modul java.desktop (java.awt.List):

import module java.base;     // ← Contains java.util.List
import module java.desktop;  // ← Contains java.awt.List

public class Ambiguous {
    List list;               // ← Ambiguous reference to List
}Code-Sprache: Java (java)

Wenn du die Datei unter Ambiguous.java abspeicherst und dann wie folgt kompilierst:

javac Ambiguous.javaCode-Sprache: Klartext (plaintext)

... dann bricht der Compiler mit folgender Fehlermeldung ab:

Ambiguous.java:5: error: reference to List is ambiguous
  List list;
  ^
  both class java.awt.List in java.awt and interface java.util.List in java.util matchCode-Sprache: Klartext (plaintext)

Das bedeutet, dass der Compiler nicht weiß, welche der beiden List-Typen gemeint ist.

Mehrdeutige Klassennamen auflösen

Nehmen wir an, du möchtest java.util.List verwenden (und nicht java.awt.List). Dann hast du zwei Möglichkeiten, um diese Mehrdeutigkeit aufzulösen:

Option 1: Du importierst zusätzlich die Klasse java.util.List direkt:

import module java.base;
import module java.desktop;

import java.util.List;  // ← Ambiguity resolved by single-type-import declaration

public class Ambiguous {
    List list;
}Code-Sprache: Java (java)

Option 2: Du importierst zusätzlich das Paket java.util (in der Java-Terminologie heißt das übrigens nicht „Package Import“ sondern „Type-Import-on-Demand Declaration“):

import module java.base;
import module java.desktop;

import java.util.*;  // ← Ambiguity resolved by type-import-on-demand declaration

public class Ambiguous {
    List list;
}Code-Sprache: Java (java)

Die zweite Option ist erst seit Java 24 verfügbar. Wenn du das letzte Beispiel mit Java 23 kompilierst, führt dies ebenfalls zur Fehlermeldung „reference to List is ambiguous“.

Mehrdeutige Klassennamen kann es übrigens auch – wenn auch selten – geben, wenn du nur ein Modul importierst. Beispielsweise enthält das Modul java.desktop sowohl das Interface javax.swing.text.Element als auch die Klasse javax.swing.text.html.parser.Element.

Transitive Modul-Importe

Wenn ein mit import module importiertes Modul ein drittes Modul transitiv importiert, dann sind auch alle Klassen der exportierten Pakete dieses dritten Moduls ohne explizite Imports nutzbar.

Ich möchte dir das am Beispiel der Module java.sql und java.xml erklären.

  • Das Modul java.sql hat (u. a.) eine transitive Abhängigkeit auf das Modul java.xml.
  • Das Modul java.sql exportiert die Pakete java.sql und javax.sql.
  • Das Modul java.xml exportiert u. a. die Pakete javax.xml, javax.xml.parsers und org.w3c.dom.

Die folgende Grafik zeigt die Module, ihre Abhängigkeiten und die exportierten Pakete:

java module import declarations

In der Modul-Deklaration des java.sql-Moduls sieht das so aus:

module java.sql {
    . . .
    requires transitive java.xml;

    exports java.sql;
    exports javax.sql;
    . . .
}Code-Sprache: Java (java)

Und in der Modul-Deklaration von java.xml so:

module java.xml {
    exports javax.xml;
    exports javax.xml.parsers;
    . . .
}Code-Sprache: Java (java)

Wenn wir nun ein Programm schreiben, das das Modul java.sql importiert, dann benötigen wir beispielsweise keine expliziten Imports für die Klassen SAXParserFactory und SAXParser aus dem Paket javax.xml.parsers des java.xml-Moduls – und auch keinen expliziten Import dieses Moduls:

import module java.sql;  // ← Transitively imports module java.xml
                         //   and its exported packages, e.g. javax.xml.parsers
. . .
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
. . .Code-Sprache: Java (java)

Denn aus der transitiven Abhängigkeit von Modul java.sql auf Modul java.xml und der Tatsache, dass java.xml das Paket javax.xml.parsers exportiert, folgt, dass das Programm auch ohne explizite Imports auf alle Klassen des Pakets javax.xml.parsers zugreifen kann.

Beachte, dass in Java 23 ein Import des Moduls java.se (ein Aggregator-Modul mit Abhängigkeiten auf alle Module der Java Standard Edition „Java SE“) nicht die Klassen des java.base-Moduls verfügbar macht. Dies wurde in Java 24 geändert.

Automatischer java.base-Import in JShell

Seit Java 25 importiert JShell das Modul java.base automatisch:

$ jshell
|  Welcome to JShell -- Version 26.0.1
|  For an introduction type: /help intro

jshell> /imports
|    import java.baseCode-Sprache: Klartext (plaintext)

Wenn du JShell mit Java 24 oder älter startest und das /imports-Kommando eingibst, wirst du hingegen die folgenden zehn standardmäßigen Paket-Importe sehen:

$ jshell
|  Welcome to JShell -- Version 24
|  For an introduction type: /help intro

jshell> /imports
|    import java.io.*
|    import java.math.*
|    import java.net.*
|    import java.nio.file.*
|    import java.util.*
|    import java.util.concurrent.*
|    import java.util.function.*
|    import java.util.prefs.*
|    import java.util.regex.*
|    import java.util.stream.*Code-Sprache: Klartext (plaintext)

Fazit

Module Import Declarations können Java-Programme kürzer und leichter wartbar machen, indem nicht mehr einzelne Klassen und Pakete, sondern ganze Module importiert werden. Andererseits können sie auch die ewige Diskussion darüber, ob man Klassen einzeln oder paketweise importieren soll, weiter ausufern lassen.

In Compact Source Files (bzw. Simple Source Files bzw. implizit deklarierten Klassen) und JShell wird automatisch das java.base-Modul importiert, so dass hier alle Klassen dieses Moduls ohne Imports direkt verwendet werden können.

Module Import Declarations waren bis Java 24 ein Preview-Feature und mussten mit --enable-preview --source <Version> aktiviert werden. Seit Java 25 sind sie finalisiert und fester Bestandteil der Sprache – ohne zusätzliche Flags nutzbar.

Java-Schulungen
(online oder vor Ort)
»