Stories
Cyrille Ngassam Nkwenga 29 septembre 2023 22:14
Introduction sur les packages dans Java
Introduction sur les packages dans Java

Dans cet article nous allons examiner un des concept les plus important ajouté au langage de programmation Java: Les packages. Les packages sont des groupes de classes qui sont plus ou moins liées. Les packages permettent d'organiser ton code et offrent un niveau d'encapsulation. Les packages offrent un grand contrôle sur l'organisation d'un programme informatique.

Les Packages

En général, en programmation il est souvent nécessaire de regrouper les parties de l'application qui sont reliées entre-elles. Chaque langage de programmation viens avec des solutions pour cette situation. On parle souvent dans ce cas de librairie ou de bibliothèque. Ceci est réalisé en Java avec les packages. Dans Java un package joue deux rôles. Le premier rôle est de permettre de regrouper les parties d'une application qui sont liées entre elles. La conséquence est que les classes définies dans un package doivent être accédées à travers le nom de leur package. Le deuxième rôle est de définir un contrôle d'accès sur les classes de ce package. Les classes définies à l'intérieur d'un package peuvent être marquées comme étant privée et ne pas être accessible à l'extérieur de ce package.

Quand on donne un nom à une classe, nous réservons ce nom d'un espace nommé en programmation namespace. Un namespace défini une région déclarative. Dans Java il est interdit pour deux classes d'avoir le même nom au sein d'un namespace. Dans l'exemple de code présenté dans Compilation de code Java nous avons vu un exemple de package : org.examples.hello qui était défini à la première ligne de code. Dans un programme plus large il est fréquent, voir normal de voir plusieurs packages être crées pour mieux organiser le code.

Nous avons vu que le deuxième rôle des packages est de définir les droit d'accès aux classes qu'ils contient. Ceci permet de définir si un package A peut accéder aux classes définies dans un package B. Nous avons là un moyen de confinement pour nos classes.

Définir un package

Pour commencer, toutes les classes dans Java appartiennent à un package. Quand le package contenant une classe n'est pas défini explicitement, alors le package par défaut est utilisé: Le package global. Ce package n'a pas de nom. C'est grâce au package global que vous n'avez pas de problème de compilation lorsque vous ne définissez pas explicitement un package pour vos classes.

Pour créer un package, place la commande package au début du fichier source de votre classe Java. Une fois cette commande ajouté, les classes contenant cette commande appartiennent au package défini. Nous avons vu les namespaces, un package défini un namespace et donc deux classes ne peuvent pas avoir le même nom.

La forme générale de la commande package est la suivante:

package pkg;

Ici pkg représente le nom du package. La commande suivante défini exemple comme étant le nom du package:

package exemple;

Java utilise le système de fichier pour stocker les packages. Chaque package est stocker dans son propre dossier. Les fichiers .class des classes déclarées dans le package exemple doivent être placés dans un dossier nommé exemple. La nomination des packages dans Java est sensible aux majuscules et minuscules. Par convention les minuscules sont utilisées pour le nom des packages. Le même package peut être dans plusieurs classes définies dans des fichiers différents.

En utilisant les packages leurs nombres peut croître. Les packages peuvent être organisés par ordres hiérarchique. Chaque niveau est séparé par un point. La forme générale est indiquée comme suit:

package pkg1.pkg2.pkg3...pkgN;

Cette commande exige de créer les dossiers dans votre projet qui réalisent cette hiérarchie. Par exemple:

package org.exemple.hello;

doit être stocké dans .../org/exemple/hello où ... représente le chemin vers les dossiers crée. ex: src/org/exemple/hello.

└── src └── org └── example └── hello

ClASSPATH

Nous venons de voir que les packages sont stockés dans des dossiers qui reflètent la hiérarchie de ceux-ci. Il y a une question qui se pose: Comment est-ce que Java (ici le JRE) sait où trouver les packages que nous avons crée ?

Par défaut, le JRE utilise le dossier actuel depuis lequel il est exécuté. Donc si le sous-dossier contenant vos packages sont situés dans le dossier courant alors vos packages seront vu par le JRE et l'exécution se déroulera sans problème. Une solution alternative est d'ajouter le chemin du dossier contenant les packages dans la variable d'environnement CLASSPATH. Une troisième solution est de passer l'option -classpath au compilateur javac pour indiquer le chemin du dossier contenant les packages.

Utilisation de package

Après l'introduction sur les packages, le moment est venu mettre tout ça en pratique. Nous allons utiliser le fameux «hello world» comme exemple, avec une légère modification: nous allons introduire l'utilisation des packages. Vous pouvez utiliser un IDE pour cet exemple, mais le but est d'utiliser soi-même le compilateur javac afin de comprendre le mécanisme qui se cache derrière tout ça. Le helloworld est programme qui affiche le texte «Hello World !» à la console. Nous allons créer un package qui contient un module ConsoleGreetingService.java dont le rôle est d'afficher à la console tout texte qu'on lui passe à l'entrée. Le module sera placé dans le package org.example.greetings. Notre application principale, App.java, sera placée dans le package org.example.hello. Notre dossier aura la structure suivante:

helloworld ├── README.md └── src └── org └── example ├── greetings │   ├── ConsoleGreetingService.java └── hello └── App.java

ConsoleGreetingService.java

package org.example.greetings; //← ce fichier est dans le package org.example.greetings public class ConsoleGreetingService{//← ConsoleGreetingService fait parti de org.example.greetings public void greet(String greetings) { System.out.println(greetings); } }

App.java : Importation de package

package org.example.hello;//← ce fichier est dans le package org.example.hello import org.example.greetings.ConsoleGreetingService;//nous importons un module est dans le package org.example.greetings public class App { public static void main(String[] args) throws Exception { ConsoleGreetingService greetingService = new ConsoleGreetingService(); greetingService.greet("Hello, World!"); } }

Erreur de compilation

nous nous plaçons dans le dossier principal  helloworld et nous compilons le fichier App.java

~helloworld$ javac src/org/example/hello/App.java src/org/example/hello/App.java:2: error: package org.example.greetings does not exist import org.example.greetings.ConsoleGreetingService; ^ src/org/example/hello/App.java:6: error: cannot find symbol ConsoleGreetingService greetingService = new ConsoleGreetingService(); ^ symbol: class ConsoleGreetingService location: class App src/org/example/hello/App.java:6: error: cannot find symbol ConsoleGreetingService greetingService = new ConsoleGreetingService(); ^ symbol: class ConsoleGreetingService location: class App 3 errors

L'erreur ici est que le compilateur ne voit pas le package org.example.greetings. Nous avons vu plus haut au paragraphe de la variable CLASSPATH que le chemin du package devrait soit être indiqué dans la variable d'environnement CLASSPATH, soit on passe l'option -classpath à javac suivi du chemin où se trouve le package org.example.greetings, soit on se place le dossier qui contient le package org.example.greetings, nous allons opter pour cette solution et nous placer dans le dossier src(voir la structure du dossier plus haut) et compiler le fichier App.java.

helloworld$ cd src/ helloworld/src$ javac org/example/hello/App.java helloworld/src$

Comme on peut le voir, le compilateur javac n'a plus affiché d'erreurs. Vérifions donc si les fichiers .class sont présents:

├── README.md └── src └── org └── example ├── greetings │   ├── ConsoleGreetingService.class │   ├── ConsoleGreetingService.java └── hello ├── App.class └── App.java

Nous voyons que les fichiers .class sont présents dans le package concerné. En général on place les fichiers .class dans un dossier dédié. Pour vous rafraîchir sur la compilation veuillez voir cet article sur la compilation. Nous allons indiquer un dossier nommé build(vous pouvez choisir un autre nom) en passant l'option -d suivi du nom du dossier:

src$ javac org/example/hello/App.java -d ../build

On peut voir que les fichiers .class sont maintenant placés dans le dossier build en respectant la hiérarchie des dossiers du package:

├── build │   └── org │   └── example │   ├── greetings │   │   └── ConsoleGreetingService.class │   └── hello │   └── App.class ├── helloworld.iml ├── README.md └── src └── org └── example ├── greetings │   ├── ConsoleGreetingService.java └── hello └── App.java

Exécution

Pour exécuter notre application, nous allons nous placer dans le dossier build et ensuite utiliser la commande java en lui passant comme argument le fichier App.class. Notez qu'ici aussi, les packages nécessaire doivent être visible depuis le dossier build, ce qui est les cas de notre exemple, notez aussi que le chemin en suivant la notation des packages org.example.hello.App :

helloworld$ cd build/ /helloworld/build$ java org.example.hello.App Hello, World!

Conclusion

Bravo,vous êtes maintenant capable de compiler vous-même votre application. Nous venons de voir ce que fait votre IDE, certes votre IDE fait encore plus, mais en substance c'est ce qui se passe dans votre IDE. Dans cet article,  je n'ai pas montré l'exemple qui utilise l'option -classpath pour indiquer le chemin où se trouve votre package. Je l'ai laissé à titre d'exercice pour vous entraîner. L'importance de cet exercice est de voir les bases de l'organisation des parties d'un programme, ce qui sera important plus tard dans votre carrière.

0
  • Soyez le premier à commenter