package.
Exemple 101. Déclaration d'un paquet dans une classe
package transport ; // la classe Voiture appartient au paquet transport public class Voiture { // rangée dand un fichier transport/Voiture.java // corps de la classe }
Voiture.java soit rangé dans un répertoire
transport.
Il est bien sûr possible de créer des sous-paquets dans des paquets parent. Il suffit pour cela de le déclarer dans la directive
package. Comme on le sait, le caractère de séparation des répertoires varie avec le système d'exploitation sur lequel on travaille. Afin de s'affranchir de cette subtilité (et pour d'autres raisons), Java code le chemin complet d'un
package avec le point comme caractère de séparation. Ainsi la classe suivante est-elle rangée dans le répertoire
transport/motorise.
Exemple 102. Rangement d'une classe dans un sous-paquet
package transport.motorise ; // la classe Voiture appartient au paquet transport.motorise public class Voiture { // rangée dand un fichier transport/motorise/Voiture.java // corps de la classe }
javac ne fait pas ce rangement automatiquement, si l'on compile avec la ligne de commande, il faut le faire manuellement, en respectant bien sûr les majuscules / minuscules au niveau des noms de répertoires. Tous les outils intégrés de développement Java savent ranger les classes compilées dans la bonne structure de répertoires, cela va de soi.
Le nom
complet
d'une classe
Voiture rangée dans le paquet
transport.motorise sera
transport.motorise.Voiture. Le fichier compilé
Voiture.class se trouvera lui dans le répertoire
transport/motorise.
La bibliothèque standard Java est entièrement structurée de cette façon là. Nous avons déjà plusieurs exemples de noms de classes complets :
java.lang.Object ou
java.lang.String. Nous savons donc maintenant que ces deux classes doivent être rangées quelque part dans un répertoire
java/lang.
.class. La distribution standard Java 1.4 comporte un peu plus de 3500 classes. Il serait très peu optimal de charger toutes ces classes systématiquement au lancement de la machine Java, surtout si l'application que l'on exécute ne doit en utiliser qu'une dizaine.
Java supporte donc complètement le chargement dynamique des classes. Quand une classe est instanciée, elle est chargée en mémoire, ainsi que toutes les classes dont elle a besoin pour fonctionner, notamment celles dont elle hérite.
Ces 3500 classes étant rangées dans quelques centaines de répertoires, il serait également trop lourd pour le système d'examiner systématiquement le contenu de toute la hiérarchie à la recherche de quelques classes données. Il existe donc un système pour indiquer à la machine Java les répertoires où elle doit aller chercher ses classes dans la hiérarchie.
Ce système consiste à utiliser la directive
import.
Exemple 103. Directive
import sur un package complet
package vehicule.motorise ;
import java.util.* ; // importation de tout le package java.util, dont la classe Date
public class Voiture {
private Date dateAchat ;
}
java/util pour trouver les classes utilisées dans ce fichier source. Si elle rencontre une classe inconnue, et qu'elle ne la trouve pas dans
java/util, elle génèrera une erreur à la compilation.
Remarquons qu'avec cette directive d'import, la machine Java ne cherche les classes que dans le répertoire
java/util, elle ne descend pas dans les sous-niveaux d'arborescence. Dans notre exemple, il existe bien une classe
Date dans la package
java.util, donc la compilation pourra se faire. Notons également que l'on aurait pu importer la classe
Date explicitement avec la directive suivante.
Exemple 104. Directive
import sur une classe particulière
package vehicule.motorise ;
import java.util.Date ; // importation d'une classe unique
public class Voiture {
private Date dateAchat ;
}
java.lang est toujours importé par défaut, il n'y a pas besoin de le déclarer explicitement. Il contient toutes les classes de base, dont la classe
Object.
public class, mais on ne peut y accéder que grâce à son chemin complet, tout comme un fichier. Cela signifie qu'il est possible d'avoir deux classes qui portent le même nom en deux endroits différents de la hiérarchie. Si les deux répertoires sont chargés il y aura conflit de nom. Afin de lever ce conflit, il est possible d'appeler chaque classe par son chemin complet. Par exemple
java.util.Date et
java.sql.Date peuvent être appelées de cette façon dans un même fichier source, sans qu'il y ait de conflit.
Exemple 105. Utilisation de deux classes portant le même nom dans le même fichier
public class Voiture { private java.util.Date dateAchat ; private java.sql.Data dateMiseEnCirculation ; }
ibm.com, placera les classes de ses applications et bibliothèques dans une hiérarchie
com.ibm. De même pour Sun, qui utilise (ou utilisait)
com.sun, ou Oracle, qui utilise
com.oracle, et qui peut maintenant utiliser aussi
com.sun. Tous les programmeurs Java utilisent cette convention, qui permet automatiquement de gérer les conflits de noms en interne des entreprises de développement. Il en va de même pour les très nombreux logiciels open-source, qui diffusent tous des packages portant leur nom :
org.hibernate,
org.apache,
net.sourceforge.
La bibliothèque standard utilise deux hiérarchies qu'il est interdit de modifier :
java. et
javax.. La hiérarchie
java. est utilisée pour la bibliothèque standard,
javax. pour les extensions de la bibliothèque standard. Toute machine Java possède l'intégralité de la bibliothèque standard, mais elle n'est pas tenue de posséder toutes les extensions.
Il existe une exception à cette règle, ce sont les machines Java utilisées dans le domaine des terminaux mobiles : PDA, smartphones et téléphones mobiles. L'édition Java pour ce type de terminal est J2ME : Java 2 micro édition. La J2ME définit deux types de configurations : la CDC (Connected Device Configuration) et la CLDC (Connected Limited Device Configuration). La CDC s'adresse plutôt aux PDAs haut de gamme. Dans la mesure où les espaces mémoire dans lesquels fonctionnent ces JVM sont parfois très restreints, la librairie standard est réduite.
La configuration CDC se fonde sur une machine Java appelée CVM, qui supporte les paquets
util,
io,
net,
security,
text et une partie de
lang. CLDC se fonde elle sur la KVM, qui ne supporte qu'
util et
io, une partie de
lang, et des classes spécifiques, rangées dans
javax.microedition. Des paquets optionnels sont disponibles pour les deux constructions. Notons qu'une machine KVM est capable de se lancer dans seulement 40ko de mémoire !
String
StringBuffer et
StringBuilder