L'instruction import en Java
Importez des types en Java avec import, les imports génériques et les imports statiques pour simplifier votre code.
Dès que votre code réside dans un package, tout ce qui est écrit en dehors de ce package doit faire référence à vos types soit par leur nom complet qualifié (com.w3docs.parser.Tokenizer), soit en les important afin que le nom court suffise. Les imports ne chargent rien, ne copient rien et n'affectent pas l'exécution — ce sont de simples facilités à la compilation qui indiquent au compilateur ce que Tokenizer signifie dans ce fichier. Trois formes couvrent tout ce dont vous aurez jamais besoin : à type unique, à la demande (générique) et statique.
Où placer les imports
Tout fichier source Java suit le même ordre fixe :
package com.w3docs.parser; // optional: at most one
import java.util.List; // zero or more imports
import java.util.Map;
public class Tokenizer { /* ... */ }package en premier (le cas échéant), puis les imports, puis les déclarations de types. Tout autre ordre entraîne une erreur de compilation.
Imports à type unique
La forme la plus courante désigne une seule classe :
import java.util.ArrayList;
ArrayList<String> names = new ArrayList<>();Après l'import, chaque mention non qualifiée de ArrayList dans le fichier est résolue en java.util.ArrayList. Vous pouvez toujours écrire le nom complet qualifié dans le même fichier si vous avez besoin de le différencier d'un autre ArrayList quelque part.
Imports à la demande (génériques)
Pour importer tout ce qui se trouve dans un package, utilisez * :
import java.util.*;
List<String> names = new ArrayList<>();
Map<String, Integer> counts = new HashMap<>();Le générique importe chaque classe publique de premier niveau de java.util — mais pas les sous-packages. import java.util.*; ne vous donne rien de java.util.concurrent ; cela nécessite un import java.util.concurrent.*; séparé. Il n'existe pas non plus de raccourci import java.*; — java lui-même ne contient aucune classe, uniquement des sous-packages.
Un débat de style courant : les imports à type unique rendent les dépendances du fichier explicites et lisibles ; les génériques gardent le bloc d'import court. Les IDE gèrent les deux sans difficulté, c'est donc surtout un choix de style de projet. Le Google Java Style Guide interdit les génériques ; de nombreux projets open source les autorisent. Choisissez-en un et soyez cohérent.
Imports statiques
Un import statique amène un membre static — une méthode ou un champ — dans la portée, de sorte que vous pouvez l'appeler sans nommer sa classe :
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
}Les imports statiques brillent dans le code de test — assertEquals(...) est plus lisible que Assertions.assertEquals(...) — et dans les formules mathématiques intensives où le nom de classe n'est que du bruit. Ils deviennent un problème lorsqu'ils sont sur-utilisés : un lecteur du fichier doit parcourir les imports pour comprendre d'où vient un assertThat(...) nu. Utilisez-les lorsque les noms de fonctions sont bien connus et sans ambiguïté dans le contexte.
Vous pouvez également utiliser le générique avec les imports statiques : import static java.lang.Math.*; importe tous les membres statiques publics de Math. Les mêmes mises en garde concernant la clarté s'appliquent.
Ce qui est importé gratuitement
Java importe automatiquement quelques éléments que vous n'avez jamais à écrire :
- Toutes les classes de
java.lang—String,Object,Math,Integer,Thread,Throwableet les autres. - Toutes les classes de votre propre package.
C'est pourquoi vous pouvez utiliser String et System.out.println sans ligne import. Tout le reste doit être importé explicitement.
Résolution des conflits de noms
Deux imports portant le même nom simple ne compilent pas — java.util.Date et java.sql.Date ne peuvent pas être tous les deux importés dans le même fichier. La solution est d'importer l'un et de qualifier l'autre :
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();Un import à type unique l'emporte toujours sur un générique. Si import java.util.*; et import java.sql.Date; sont tous deux présents, un Date nu désigne java.sql.Date — l'import explicite à type unique prend la priorité sur l'import à la demande, donc ce cas compile correctement. Seuls deux imports à type unique pour le même nom simple constituent une erreur.
C'est le même problème que le chapitre sur les packages a mis en évidence, vu du côté des imports.
Un exemple concret
Ce programme importe des types sous les trois formes — unique, générique, statique — puis vérifie à l'exécution que les classes résultantes sont exactement celles de ces packages.
Les trois premiers imports couvrent toutes les formes que le langage possède. Remarquez que le générique import java.util.*; est ce qui rend List, Collections et Date disponibles — l'import java.util.ArrayList; explicite est redondant dans ce fichier, mais c'est le genre de ligne qu'un guide de style de projet pourrait exiger pour la lisibilité.
Prochaine étape
Vous avez vu comment extraire des types de packages. Vous allez maintenant faire l'autre côté — déclarer votre propre package et organiser les fichiers de façon à ce que le compilateur et la JVM soient satisfaits. Continuez avec la création de packages personnalisés en Java.