W3docs

Java import-Anweisung

Typen in Java mit import-Anweisungen, Wildcard-Imports und statischen Imports in den Gültigkeitsbereich bringen.

Sobald Ihr Code in einem Package lebt, muss jeder Code außerhalb dieses Packages auf Ihre Typen entweder über ihren vollqualifizierten Namen (com.w3docs.parser.Tokenizer) verweisen oder sie importieren, damit der Kurzname ausreicht. Imports laden nichts, kopieren nichts und haben keinen Einfluss auf die Laufzeit — sie sind eine rein compilerzeitliche Komfortfunktion, die dem Compiler mitteilt, was Tokenizer in dieser Datei bedeutet. Drei Varianten decken alles ab, was Sie je brauchen werden: Einzeltyp, On-Demand (Wildcard) und statisch.

Wo Imports stehen

Jede Java-Quelldatei folgt der gleichen festen Reihenfolge:

package com.w3docs.parser;          // optional: at most one

import java.util.List;              // zero or more imports
import java.util.Map;

public class Tokenizer { /* ... */ }

Zuerst package (falls vorhanden), dann imports, dann Typdeklarationen. Alles andere ist ein Compilerfehler.

Einzeltyp-Imports

Die häufigste Form benennt eine Klasse:

import java.util.ArrayList;

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

Nach dem Import löst jede unqualifizierte Erwähnung von ArrayList in der Datei zu java.util.ArrayList auf. Sie können in der gleichen Datei immer noch den vollqualifizierten Namen schreiben, falls Sie ihn gegenüber einem anderen ArrayList irgendwo disambiguieren müssen.

On-Demand-Imports (Wildcard)

Um alles aus einem Package hereinzuholen, verwenden Sie ein *:

import java.util.*;

List<String> names = new ArrayList<>();
Map<String, Integer> counts = new HashMap<>();

Der Wildcard importiert jede öffentliche Top-Level-Klasse von java.util — aber keine Subpackages. import java.util.*; gibt Ihnen nichts aus java.util.concurrent; dafür braucht man ein separates import java.util.concurrent.*;. Es gibt auch keine import java.*;-Abkürzung — java selbst enthält keine Klassen, nur Subpackages.

Eine häufige Stildebatten: Einzeltyp-Imports machen die Abhängigkeiten der Datei explizit und lesbar; Wildcards halten den Import-Block kurz. IDEs handhaben beide problemlos, also ist es meistens eine Entscheidung des Projektstils. Der Google Java Style Guide verbietet Wildcards; viele Open-Source-Projekte erlauben sie. Wählen Sie eines und bleiben Sie konsistent.

Statische Imports

Ein statischer Import bringt ein static-Member — eine Methode oder ein Feld — in den Gültigkeitsbereich, sodass Sie es aufrufen können, ohne seine Klasse zu benennen:

import static java.lang.Math.PI;
import static java.lang.Math.sqrt;

double hypotenuse(double a, double b) {
  return sqrt(a * a + b * b);   // not Math.sqrt
}

Statische Imports glänzen in Testcode — assertEquals(...) liest sich besser als Assertions.assertEquals(...) — und in mathematisch intensiven Formeln, wo der Klassenname nur Lärm ist. Sie werden zum Problem, wenn sie übermäßig eingesetzt werden: Ein Leser der Datei muss den Imports nachspüren, um herauszufinden, woher ein bloßes assertThat(...) kommt. Verwenden Sie sie, wenn die Funktionsnamen bekannt und im Kontext eindeutig sind.

Sie können statische Imports auch als Wildcard verwenden: import static java.lang.Math.*; holt jedes öffentliche Statische von Math herein. Dieselben Vorbehalte bezüglich der Klarheit gelten.

Was kostenlos importiert wird

Java importiert einige Dinge automatisch, die Sie nie schreiben müssen:

  • Jede Klasse in java.langString, Object, Math, Integer, Thread, Throwable und die anderen.
  • Jede Klasse im eigenen Package.

Deshalb können Sie String und System.out.println ohne eine import-Zeile verwenden. Alles andere muss explizit hereingebracht werden.

Namenskonflikte auflösen

Zwei Imports für den gleichen einfachen Namen kompilieren nicht — java.util.Date und java.sql.Date können nicht beide in dieselbe Datei importiert werden. Die Lösung besteht darin, eine zu importieren und die andere zu qualifizieren:

import java.util.Date;            // imported short

// Use java.sql.Date by its full name where it appears:
java.sql.Date dbDate = resultSet.getDate(1);
Date now = new Date();

Ein Einzeltyp-Import gewinnt immer über einen Wildcard. Wenn import java.util.*; und import java.sql.Date; beide vorhanden sind, bedeutet ein bloßes Date java.sql.Date — der explizite Einzeltyp-Import hat Vorrang vor dem On-Demand-Import, also kompiliert dieser Fall sauber. Nur zwei Einzeltyp-Imports für den gleichen einfachen Namen sind ein harter Fehler.

Dies ist dasselbe Problem, das das Packages-Kapitel hervorgehoben hat, von der Import-Seite aus betrachtet.

Ein ausgearbeitetes Beispiel

Dieses Programm importiert Typen in allen drei Formen — einzeln, Wildcard, statisch — und überprüft dann zur Laufzeit, dass die resultierenden Klassen genau die aus diesen Packages sind.

java— editable, runs on the server

Die ersten drei Imports decken jede Form ab, die die Sprache hat. Beachten Sie, dass der Wildcard import java.util.*; das ist, was List, Collections und Date verfügbar macht — der explizite import java.util.ArrayList; ist in dieser Datei redundant, aber es ist die Art von Zeile, die ein Projektstil-Leitfaden aus Gründen der Lesbarkeit verlangen könnte.

Was als nächstes kommt

Sie haben gesehen, wie man Typen aus Packages herausholt. Als nächstes machen Sie die andere Seite — Ihr eigenes Package deklarieren und die Dateien so anordnen, dass sowohl der Compiler als auch die JVM zufrieden sind. Weiter zu eigene Packages in Java erstellen.

Übungen

Übung
Was bringt `import java.util.*;` tatsächlich in den Gültigkeitsbereich?
Was bringt `import java.util.*;` tatsächlich in den Gültigkeitsbereich?
Was this page helpful?