Packages, java namespace
Package = ensemble de classes (ou d'interfaces) ; sert à regrouper du code et à fournir un espace de nommage (namespace) aux classes qu'ils contiennent.Par convention, les noms de packages sont en lettres minuscules.
Utilités :
- Eviter les collisions de nom.
- Organiser son code en sous-ensembles cohérents.
- Permet aux classes et méthodes d'avoir une visibilité
package
, importante dans des gros programmes.
NOTE : concevoir ses packages en n'utilisant qu'un nombre mimimum de classes publiques est conseillé, afin de renforcer l'encapsulation au niveau package.
Si une classe n'a pas vocation a être utilisée par d'autres package, donnez-lui une visibilité package : simplifie l'API publique et vous permet de faire évoluer le package sans perturber le code client.
Exemple : Comparer la doc du package javax.swing.colorchooser et le code source.
Les classes centrales de l'API sont dans un package qui commence par
java
.
En particulier java.lang
et java.util
, aussi java.io
, java.net
.
javax*
= eXtensions qui ont été intégrées à la plateforme.
Oracle contrôle les packages commençant par
java
, javax
, sun
.
Une classe a donc à la fois un nom simple et un fully qualified name.
Nom simple :
System
Fully qualified name : java.lang.System
2 classes de même nom simple ne peuvent être différenciées que par leur fully qualified name, par exemple
java.util.List
et java.awt.List
.
Par défaut, pour référencer une classe dans le code, il faut utilser son fully qualified name, à 3 exceptions :
- les classes de
java.lang
- les classes du package courant
- les classes qui ont été importées dans la package courant avec la déclaration
import
.
Une toute petite application peut être écrite dans un répertoire sans spécifier le package, elle se trouve dans le package par défaut.
Mais dès qu'une application grossit, elle est packagée ; le nom du package courant est spécifié en utilisant l'instruction
package
.
Les clauses
import
doivent apparaître en début de fichier, juste après la clause package
.
package myapp.mypackage; import java.io.File; // single type import import java.io.*; // on-demand type import - ne s'applique pas aux sub-packagesOn-demand import équivalent à simple type import uniquement pour les classes que l'on utilse.
Conflits
import java.util.List; import java.awt.List;Génère une erreur de compilation.
import java.util.*; import java.awt.*;est légal, mais l'utilisation de
List
dans le code génère une erreur de compilation.
Dans ce cas, on peut faire :
import java.util.*; import java.awt.*; import java.util.List; // pour lever l'ambiguïtéDans le code, l'identifiant "
List
" désignera une java.util.List
et pour utiliser java.awt.List
, on doit faire :
java.awt.List = new java.awt.List(...)
import static
Introduit en java 5.Les imports "normaux" permettent d'importer des noms de types référence (classes, interfaces...).
Les imports static permettent d'importer les membres statiques (variables et méthodes) d'une classe, en faisant :
import static java.lang.System.out;Permet par exemple d'utiliser dans le code
out.println()
au lieu de System.out.println()
.
Utilisation courante :
import static java.lang.Math.*; // permet de remplacer : Math.sqrt(Math.abs(Math.sin(x))) // par sqrt(abs(sin(x)))Aussi utile pour les constantes (utiliser
PI
au lieu de Math.PI
).
Mais ATTENTION, à utiliser avec parcimonie car diminue la lisibilité du code : il faut faire des efforts pour savoir si une variable est locale ou vient d'un
import static
(pire en cas de multiples import static *
). Favoriser l'import des variables une par une plutôt que la syntaxe avec *
.
Structure d'une application java
En java, le code est écrit dans des fichiers .java.Les fichiers .java doivent être compilés (transformés en bytecode lisible par la JVM) en utilisant javac. Le bytecode est stocké dans des fichiers .class.
La (quasi ?) totalité des projets java stocke les .java et les .class dans deux dossiers séparés.
La structure typique d'un projet java est :
projet/ ├── bin // contient les .class └── src // contient les .javaIl y a obligatoirement une correspondance entre la hiérarchie des packages et la hiérarchie des fichiers.
Exemple :
src/ └── projet ├── package1 │ └── Class1.java <- package projet.package1; ├── package2 │ └── Class2.java <- package projet.package2 └── Projet.java <- package projet;
La même hiérarchie se trouve dans
bin/
:
bin/ └── projet ├── package1 │ └── Class1.class ├── package2 │ └── Class2.class └── Projet.classUne manière assez répandue de nommer les packages utilise l'url de(s) auteur(s) pour former le nom du package principal.
Par exemple
http://commons.apache.org
met ses projets dans les packages
org.apache.commons.projet1
org.apache.commons.projet2
Ce qui correspond à une hiérarchie de fichiers
org/apache/commons/projet1
et org/apache/commons/projet2
Modules
La notion de module a été introduite en java 9. Un module regroupe un ou plusieurs packages.Java SE a été découpé en modules, ce qui permet de déployer une application en n'incluant que les modules utiles.
Voir https://www.oracle.com/corporate/features/understanding-java-9-modules.html
Exercice : TP Conversion Celcius Fahrenheit