Guide de survie Java : Code et commandes
Guide de survie Java : Code et commandes
J
a
v
a
L
E
G
U
I
D
E
D
E
S
U
R
V
I
E
Fisher
LE GUI DE DE SURVI E
J ava
LESSENTIEL DU CODE ET DES COMMANDES
Ce Guide de sur vie vous livre tout le code dont vous avez
besoin pour raliser rapidement et efcacement vos projets
de dveloppement en J ava.
CONCIS ET MANIABLE
Facile transporter, facile utiliser nis les livres
encombrants !
PRATIQUE ET FONCTIONNEL
Plus de 100 fragments de code personnalisables
pour programmer du J ava fonctionnel dans toutes les
situations.
Timot hy Fisher est un professionnel du dveloppement de
logiciels J ava depuis 1997. Il est actuellement consultant
pour lentreprise Compuware Corporation Dtroit dans le
Michigan. Il aime crire sur cette technologie et a contribu
aux deux ouvrages Java Developer s Journal et XML Journal.
Tim est galement passionn par lducation et lutilisation
des technologies Internet avances dans ce domaine.
Niveau : Int ermdiaire
Cat gorie : Programmat ion
Con gurat ion : Mult iplat e-forme
LE GUI DE DE SURVI E
LESSENTIEL DU CODE ET DES COMMANDES
J ava
Phrasebook
Traduit de lamricain par :
Patrick Fabre
ISBN original : 0-672-32907-7
Copyright 2007 by Sams Publishing
[Link]
Tous droits rservs
Sams Publishing
800 East 96th,
Indianapolis, Indiana 46240 USA
ISBN : 978-2-7440-4004-7
Copyright 2009
Table des matires
Introduction 1
1 Les bases 5
Compiler un programme Java 7
Excuter un programme Java 8
Dfinir le chemin de classe 9
2 Interagir avec l'environnement 11
Obtenir des variables d'environnement 12
Dfinir et obtenir des proprits systme 13
Parser des arguments en ligne de commande 14
3 Manipuler des chanes 17
Comparer des chanes 18
Rechercher et rcuprer des sous-chanes 21
Traiter une chane caractre par caractre 22
Renverser une chane par caractre 23
Renverser une chane par mot 24
Convertir une chane en majuscules ou en minuscules 25
Supprimer les espaces au dbut et la fin d'une chane 26
Parser une chane spare par des virgules 27
IV Java
4 Travailler avec des structures de donnes 31
Redimensionner un tableau 32
Parcourir une collection en boucle 33
Crer une collection mappe 35
Stocker une collection 36
Trouver un objet dans une collection 38
Convertir une collection en un tableau 40
5 Dates et heures 41
Retrouver la date d'aujourd'hui 42
Conversion entre les objets Date et Calendar 42
Imprimer une date/une heure dans un format spcifi 44
Parser des chanes en dates 47
Additions et soustractions avec des dates
ou des calendriers 48
Calculer la diffrence entre deux dates 49
Comparer des dates 50
Retrouver le jour de la semaine/ du mois/de l'anne
ou le numro de la semaine 51
Calculer une dure coule 52
6 Retrouver des motifs avec des expressions rgulires 55
Les expressions rgulires en Java 56
Retrouver une portion de texte
l'aide d'une expression rgulire 58
Remplacer du texte mis en correspondance 61
Retrouver toutes les occurrences d'un motif 63
Imprimer des lignes contenant un motif 64
Retrouver des caractres de nouvelle ligne dans du texte 65
V Table des matires
7 Nombres 67
Vrifier si une chane est un nombre valide 68
Comparer des nombres virgule flottante 69
Arrondir des nombres virgule flottante 71
Formater des nombres 72
Formater des devises 74
Convertir un entier en nombre binaire,
octal et hexadcimal 74
Gnrer des nombres alatoires 75
Calculer des fonctions trigonomtriques 76
Calculer un logarithme 77
8 Entre et sortie 79
Lire du texte partir d'une entre standard 80
Ecrire vers une sortie standard 80
Formater la sortie 81
Ouvrir un fichier par son nom 86
Lire un fichier dans un tableau d'octets 87
Lire des donnes binaires 88
Atteindre une position dans un fichier 89
Lire une archive JAR ou ZIP 89
Crer une archive ZIP 90
9 Travailler avec des rpertoires et des fichiers 93
Crer un fichier 94
Renommer un fichier ou un rpertoire 95
Supprimer un fichier ou un rpertoire 96
Modifier des attributs de fichier 97
VI Java
Obtenir la taille d'un fichier 98
Dterminer si un fichier ou un rpertoire existent 99
Dplacer un fichier ou un rpertoire 99
Obtenir un chemin de nom de fichier absolu
partir d'un chemin relatif 101
Dterminer si un chemin de nom de fichier
correspond un fichier ou un rpertoire 102
Lister un rpertoire 103
Crer un nouveau rpertoire 106
10 Clients rseau 107
Contacter un serveur 108
Retrouver des adresses IP et des noms de domaine 109
Grer les erreurs rseau 110
Lire du texte 111
Ecrire du texte 112
Lire des donnes binaires 113
Ecrire des donnes binaires 114
Lire des donnes srialises 115
Ecrire des donnes srialises 117
Lire une page Web via HTTP 118
11 Serveurs rseau 121
Crer un serveur et accepter une requte 122
Retourner une rponse 123
Retourner un objet 124
Grer plusieurs clients 126
Servir du contenu HTTP 128
VII Table des matires
12 Envoyer et recevoir des e-mails 131
Vue d'ensemble de l'API JavaMail 132
Envoyer des e-mails 133
Envoyer des e-mails MIME 135
Lire un e-mail 137
13 Accs aux bases de donnes 141
Se connecter une base de donnes via JDBC 142
Envoyer une requte via JDBC 144
Utiliser une instruction prpare 146
Rcuprer les rsultats d'une requte 148
Utiliser une procdure stocke 149
14 XML 153
Parser du XML avec SAX 155
Parser du XML avec DOM 157
Utiliser une DTD pour vrifier un document XML 159
Crer un document XML avec DOM 161
Transformer du XML avec des XSLT 163
15 Utiliser des threads 165
Lancer un thread 166
Arrter un thread 168
Attendre qu'un thread se termine 169
Synchroniser des threads 171
Suspendre un thread 174
Lister tous les threads 176
VIII Java
16 Programmation dynamique par rflexion 179
Obtenir un objet Class 180
Obtenir un nom de classe 182
Dcouvrir des modificateurs de classe 182
Trouver des superclasses 183
Dterminer les interfaces implmentes par une classe 185
Dcouvrir des champs de classe 186
Dcouvrir des constructeurs de classe 187
Dcouvrir des informations de mthode 189
Retrouver des valeurs de champ 191
Dfinir des valeurs de champ 192
Invoquer des mthodes 193
Charger et instancier une classe de manire dynamique 195
17 Empaquetage et documentation des classes 197
Crer un paquetage 198
Documenter des classes avec JavaDoc 200
Archiver des classes avec Jar 203
Excuter un programme partir d'un fichier JAR 204
Index 207
Au sujet de l'auteur
Timothy Fisher est un professionnel du dveloppement
de logiciels Java depuis 1997. Il a revtu de nombreuses
casquettes, dont celle de dveloppeur, de chef d'quipe
et d'architecte en chef. Il est actuellement consultant pour
l'entreprise Compuware Corporation Dtroit dans le
Michigan. Il aime crire sur des sujets techniques et a
contribu aux deux ouvrages
Java Developer's Journal
et
XML Journal
.
Tim est galement passionn par l'ducation et l'utilisa-
tion des technologies Internet avances dans ce domaine.
Pour le contacter et consulter son blog (en anglais),
rendez-vous l'adresse
[Link]
.
Introduction
En dbut danne, un diteur de Pearson ma demand
dcrire ce
Guide de survie
consacr au Java, opus dune
collection regroupant un certain nombre dautres ouvra-
ges, dont Christian Wenz avait crit le premier consacr
au PHP (premire partie du
Guide de survie PHP et
MySQL
). Lide de la collection
Guide de survie
est tire
des guides de conversation pour le tourisme dans les pays
trangers qui proposent des listes de phrases pour sexpri-
mer dans une autre langue. Ces manuels sont trs utiles
pour ceux qui ne connaissent pas la langue locale. Le prin-
cipe des ouvrages de la collection
Guide de
survie
est ana-
logue. Ils montrent au lecteur comment raliser des tches
courantes dans le cadre dune technologie particulire.
Le but de ce
Guide de survie
est de fournir une liste
dexemples de code couramment utiliss en programma-
tion Java. Ce livre doit tre utile la fois au programmeur
Java confirm et celui qui dbute avec ce langage. Sil
peut tre lu de bout en bout afin dacqurir une vue
densemble du langage Java, il est avant tout conu
comme un ouvrage de rfrence qui peut tre consult
la demande lorsque le programmeur doit savoir comment
raliser une tche courante en Java. Vous pouvez aussi
explorer ce livre afin de dcouvrir des fonctionnalits et
des techniques Java que vous navez pas encore matrises.
2 Introduction
Ce livre nest pas un manuel dapprentissage ou dintro-
duction au Java ni une rfrence complte de ce langage.
Il existe bien dautres classes et API que celles prsentes
ici. Dexcellents livres ont dj t publis qui vous per-
mettront dapprendre le Java ou serviront de rfrence en
abordant toutes les fonctionnalits possibles et imagina-
bles. Si votre but est dacqurir une comprhension trs
vaste dune technologie spcifique, il est prfrable de
consulter un livre adapt.
La plupart des exemples prsents dans ce livre nincluent
pas de code de gestion des erreurs. Bon nombre de ces
fragments de code sont cependant susceptibles de lever
des exceptions quil vous faudra imprativement grer
dans vos propres applications. Le code de gestion des
erreurs et des exceptions est volontairement omis ici, afin
que le lecteur puisse se concentrer spcifiquement sur la
notion illustre par lexemple, sans tre distrait par dautres
considrations. Si les exemples avaient inclus lensemble
du code de gestion des exceptions, ils nauraient pour la
plupart pas pu prendre la forme compacte et synthtique
qui est la leur et vous nauriez pas mieux compris les
notions abordes. La JavaDoc du JDK Java est une excel-
lente source dinformations pour retrouver les exceptions
qui peuvent tre leves par les mthodes contenues dans
les classes Java rencontres dans ce livre. Pour la consulter,
rendez-vous ladresse
[Link]
docs/api/
.
Les exemples de ce livre doivent tre indpendants du
systme dexploitation. Le mot dordre de la plate-forme
Java ("programm une fois, excut partout") doit
sappliquer tous les exemples contenus dans ce livre.
Le code a t test sous le JDK 1.5 aussi appel Java 5.0.
3
La plupart des exemples fonctionnent aussi sous les ver-
sions prcdentes du JDK, sauf mention spciale ce sujet.
Tous les exemples ont t tests et doivent tre exempts
derreurs. Je souhaite pour ma part que le livre ne
contienne pas la moindre erreur, mais il faut videm-
ment admettre quaucun livre technique ne peut par
dfinition y prtendre. Toutes les erreurs qui pourraient
tre trouves dans louvrage seront signales sur le site
[Link]
.
En rdigeant ce livre, jai tent de trouver les exemples les
plus utiles tout en mastreignant lexigence de concision
de la collection
Guide de survie
. Il est immanquable qu
un moment ou un autre, vous rechercherez un exemple
qui ne figurera pas dans ce livre. Si vous estimez quun
exemple important manque, signalez-le moi. Si vous pen-
sez linverse que dautres exemples du livre ne sont pas
si utiles, indiquez-le moi galement. En tant quauteur,
japprcie toujours de connatre le sentiment des lecteurs.
A lavenir, il est possible quune seconde dition du livre
voit le jour. Vous pouvez me contacter en consultant
mon site Web ladresse
[Link]
.
1
Les bases
Ce chapitre prsente les premiers exemples avec lesquels
vous aurez besoin de vous familiariser pour dmarrer un
dveloppement Java. Ils sont en fait requis pour raliser
quelque action que ce soit en Java. Vous devez pouvoir
compiler et excuter votre code Java et comprendre les
chemins de classe Java. A la diffrence dautres langages
comme le PHP ou le Basic, le code source Java doit tre
compil sous une forme appele "code-octet" (
bytecode
)
avant de pouvoir tre excut. Le compilateur place le
code-octet dans des fichiers de classe Java. Tout program-
meur Java doit donc comprendre comment compiler son
code source en fichiers de classe et savoir excuter ces
fichiers de classe. La comprhension des chemins de classe
Java est importante la fois pour compiler et pour ex-
cuter le code Java. Nous commencerons donc par ces
premiers exemples.
Il est aujourdhui courant de travailler au dveloppement
Java dans un EDI (environnement de dveloppement int-
gr) comme le projet libre Eclipse (
[Link]
.org
). Pour ce chapitre, nous considrerons que vous ra-
liserez vos tches en ligne de commande.
6 CHAPITRE 1 Les bases
Si lessentiel de votre dveloppement peut parfaitement se
faire avec un EDI, tout dveloppeur se doit cependant
dtre familiaris avec la configuration et la ralisation de
ces tches en dehors dun EDI. La procdure propre aux
tches effectues dans un EDI varie selon lEDI : il est donc
prfrable dans ce cas de consulter le manuel de lEDI
concern pour obtenir de laide ce sujet.
Pour excuter les instructions contenues dans ce chapitre,
vous devez obtenir une distribution Java auprs de Sun.
Sun diffuse la technologie Java sous plusieurs formes. Les
distributions Java les plus courantes sont le Java Standard
Edition (SE), le Java Enterprise Edition (EE) et le Java
Micro Edition (ME). Pour suivre tous les exemples de ce
livre, vous naurez besoin que du paquetage Java SE. Java
EE contient des fonctionnalits supplmentaires permettant
de dvelopper des applications dentreprise. Java ME est
destin au dveloppement dapplications pour les pri-
phriques tels que les tlphones cellulaires et les assistants
personnels. Tous ces paquetages peuvent tre tlchargs
depuis le site Web de Sun ladresse
[Link]
.
A lheure o ces lignes sont crites, J2SE 5.0 est la version
la plus rcente du Java SE. A moins que vous nayez une
raison particulire dutiliser une version antrieure, utili-
sez donc cette version avec ce livre. Vous trouverez deux
paquetages tlcharger dans le J2SE 5.0 : le JDK et le
JRE. Le JDK est le kit de dveloppement Java. Il est
ncessaire pour dvelopper des applications Java. Le JRE
(
Java runtime edition
) ne permet que dexcuter des appli-
cations Java et non den dvelopper. Pour ce livre, vous
aurez donc besoin de la distribution JDK du paquetage
J2SE 5.0.
7 Compiler un programme Java
Info
J2SE 5.0 et JDK 5.0 sont souvent aussi mentionns sous la
rfrence JDK 1.5. Sun a dcid de changer officiellement le
nom de la version 1.5 en lappelant 5.0.
Pour obtenir de laide lors de linstallation de la version
la plus rcente du Java J2SE JDK, voir
[Link]
.com/j2se/1.5.0/[Link]
.
Compiler un programme Java
Cet exemple compile le fichier source
[Link]
en code-octet. Le code-octet est la reprsentation Java
indpendante de toute plate-forme des instructions dun
programme. La sortie sera place dans le fichier
Hello-
[Link]
.
Lexcutable
javac
est inclus dans la distribution Java JDK.
Il est utilis pour compiler les fichiers source Java que
vous crivez dans des fichiers de classe Java. Un fichier de
classe Java est une reprsentation en code-octet de la source
Java compile. Pour plus dinformations sur la commande
javac
, consultez la documentation du JDK. De nombreu-
ses options peuvent tre utilises avec
javac
qui ne sont
pas traites dans ce livre.
Pour la plupart de vos projets de programmation,
lexception des petits programmes trs simples, vous utili-
serez sans doute un EDI ou un outil comme Ant dApache
pour raliser votre compilation. Si vous compilez autre
javac [Link]
8 CHAPITRE 1 Les bases
chose quun trs petit projet avec des fichiers source mini-
maux, il est vivement conseill de vous familiariser avec
Ant. Si vous connaissez loutil de compilation Make utilis
par les programmeurs C, vous comprendrez limportance
dAnt. Ant est en quelque sorte lquivalent de Make
pour Java. Il permet de crer un script de compilation
pour spcifier les dtails de la compilation dune applica-
tion complexe puis de gnrer automatiquement lappli-
cation complte laide dune seule commande. Pour plus
dinformations sur Ant et pour tlcharger le programme,
rendez-vous ladresse
[Link]
.
Excuter un programme Java
Dans cet exemple, nous utilisons dabord le compilateur
javac
pour compiler notre source Java dans un fichier
[Link]
. Ensuite, nous excutons le programme
HelloWorld en utilisant la commande
java
laquelle
nous passons le nom de la classe compile,
HelloWorld
.
Notez que lextension
.class
nest pas incluse dans le
nom qui est pass la commande
java
.
Lexcutable
java
est inclus avec la distribution Java JDK
ou la distribution Java JRE. Il est utilis pour excuter les
fichiers de classe Java compils. Il fait office dinterprteur
et compile en temps rel le code-octet en code natif ex-
cutable sur la plate-forme utilise. Lexcutable
java
est
un lment de Java dpendant de la plate-forme dexcu-
tion. Chaque plate-forme qui supporte Java possde ainsi
son propre excutable
java
compil spcifiquement pour
elle. Cet lment est aussi appel la
machine virtuelle
.
javac [Link] // compilation du fichier source
java HelloWorld // excution du code-octet
9 Dfinir le chemin de classe
Dnir le chemin de classe
Le chemin de classe est utilis par lexcutable
java
et le
compilateur
java
pour trouver les fichiers de classe com-
pils et toutes les bibliothques empaquetes sous forme
de fichiers JAR requis pour excuter ou compiler un pro-
gramme. Les fichiers JAR sont le moyen standard
dempaqueter des bibliothques dans une ressource pre-
nant la forme dun fichier unique. Lexemple prcdent
montre comment le chemin de classe peut tre dfini lors
de lexcution dun programme Java en ligne de com-
mande. Par dfaut, le chemin de classe est obtenu depuis
la variable denvironnement systme
CLASSPATH
. Dans cet
exemple, une classe spcifique appele
[Link]
et
situe dans le dossier
classes
est ajoute au chemin de
classe dfini par la variable denvironnement. Une biblio-
thque appele
[Link]
situe dans le rpertoire
libs
est galement ajoute au chemin de classe. Si la variable
denvironnement
CLASSPATH
nest pas dfinie et que
loption
classpath
nest pas utilise, le chemin de classe
par dfaut correspond au rpertoire courant. Si le chemin
de classe est dfini avec lune de ces options, le rpertoire
courant nest pas automatiquement inclus dans le chemin
de classe. Il sagit l dune source frquente de problmes.
Si vous dfinissez un chemin de classe, vous devez expli-
citement rajouter le rpertoire courant. Vous pouvez tou-
tefois ajouter le rpertoire courant au chemin de classe en
le spcifiant par "." dans le chemin de classe.
set CLASSPATH = /utilisateur/projets/classes
java classpath =
CLASSPATH%;classes/[Link];libs/[Link]
10 CHAPITRE 1 Les bases
Attention
Notez que si toutes les classes se trouvent dans un rpertoire
inclus dans le chemin de classe, il faut nanmoins que les
fichiers JAR soient explicitement inclus dans le chemin de
classe pour tre trouvs. Il ne suffit pas dinclure le rpertoire
dans lequel ils rsident lintrieur du chemin de classe.
Les problmes lis aux chemins de classe sont trs courants
chez les programmeurs novices comme chez les program-
meurs expriments et peuvent souvent tre trs agaants
rsoudre. Si vous prenez le temps de bien comprendre
le fonctionnement des chemins de classe et de bien savoir
les dfinir, vous devriez pouvoir viter ces problmes dans
vos applications. Pour plus dinformations sur la confi-
guration et lutilisation des chemins de classe, consultez
la page [Link]
windows/[Link].
2
Interagir avec
lenvironnement
Ce chapitre regroupe lensemble des exemples qui vous
permettront dinteragir avec lenvironnement dexcution
sur lequel votre application sexcute. Plusieurs dentre
eux utilisent lobjet Java System, un objet Java central
destin interagir avec lenvironnement qui entoure
votre application Java. Il faut tre trs prudent lorsque
vous utilisez cet objet et plus gnralement lorsque vous
interagissez avec lenvironnement, car vous risquez par
inadvertance de crer du code dpendant de votre plate-
forme. Lobjet System interagit avec lenvironnement et
ce dernier est bien sr propre la plate-forme sur laquelle
vous travaillez. Les effets de lutilisation dune mthode
ou dune proprit de System sur une plate-forme peu-
vent ainsi ne pas tre les mmes sur lensemble des autres
plates-formes.
12 CHAPITRE 2 Interagir avec lenvironnement
Obtenir des variables
denvironnement
Cet exemple montre comment rcuprer une variable
denvironnement avec la mthode [Link]().
Cette mthode a t dconseille dans les versions du JDK
comprises entre la version 1.2 et la version 1.4. Avec le
JDK 1.5, Sun a pris une mesure exceptionnelle en reve-
nant sur sa dcision et en rhabilitant cette mthode. Si
vous utilisez une version du JDK pour laquelle cette
mthode est dconseille, vous verrez des avertissements
apparatre au moment de la compilation lorsque vous ten-
tez dutiliser cette mthode. Les mthodes dconseilles
ne doivent pas tre utilises dans les nouveaux projets de
dveloppement mais restent gnralement prises en
charge pour des raisons de compatibilit arrire. Il nexiste
pas de garantie que les mthodes dconseilles continuent
dtre prises en charge dans les versions futures du JDK,
mais dans le cas prcis de cette mthode, il se trouve que
la version la plus rcente du JDK la rhabilite : vous
pouvez donc raisonnablement supposer quelle conti-
nuera dtre prise en charge.
En gnral, on considre quil est de mauvais usage duti-
liser des variables denvironnement dans les applications
Java. Celles-ci dpendent en effet de la plate-forme, or
le Java a justement pour vocation dtre indpendant de
toute plate-forme. Certaines plates-formes Java (notam-
ment Macintosh) ne proposent dailleurs pas de variable
denvironnement. Votre code ne se comportera donc
pas comme prvu dans ces environnements.
String envPath = [Link]("PATH");
13 Dfinir et obtenir des proprits systme
Lexemple suivant montre comment obtenir et dfinir
des proprits systme. Cette approche est prfrable
celle qui consiste utiliser des variables denvironnement.
Dnir et obtenir
des proprits systme
Les proprits systme sont des paires cl/valeur externes
votre application Java. Lobjet Java System propose un
mcanisme permettant de lire les noms et les valeurs de
ces proprits systme externes depuis votre application
Java. Lexemple prcdent montre comment dfinir et lire
une proprit systme laide de lobjet Java System. Vous
pouvez aussi rcuprer toutes les proprits systme dans
un objet de proprits laide de linstruction suivante :
Properties systemProps = [Link]();
Une autre mthode permet galement de rcuprer les
noms des proprits systme. Le fragment de code suivant
indique comment rcuprer tous les noms des proprits
systme puis rcuprer chaque proprit avec son nom :
Properties props = [Link]();
Enumeration propertyNames = [Link]();
String key = "";
while ([Link]()) {
key = (String) [Link]();
[Link](key + "=" +
[Link](key));
}
[Link]("timezone", "EasternStandardTime");
String zone = [Link]("timezone");
14 CHAPITRE 2 Interagir avec lenvironnement
Parser des arguments en ligne
de commande
Dans cet exemple, nous stockons les valeurs de trois argu-
ments en ligne de commande dans trois variables String
spares, arg1, arg2 et arg3.
Toutes les classes Java peuvent inclure une mthode main()
excutable en ligne de commande. La mthode main()
accepte un tableau String darguments en ligne de com-
mande. Les arguments sont contenus dans le tableau dans
lordre o ils sont entrs dans la ligne de commande. Pour
les rcuprer, il vous suffit donc dextraire les lments du
tableau des arguments pass la mthode main().
Si votre application utilise un grand nombre darguments
en ligne de commande, il peut tre utile de passer du temps
concevoir un parseur darguments en ligne de com-
mande personnalis pour comprendre et grer les diffrents
types darguments en ligne de commande, comme les para-
mtres un caractre, les paramtres avec des tirets (-),
les paramtres immdiatement suivis par un autre param-
tre li, etc.
java my_program arg1 arg2 arg3
public static void main(String[] args) {
String arg1 = args[0];
String arg2 = args[1];
String arg3 = args[2];
}
15 Parser des arguments en ligne de commande
Info
De nombreux exemples de processeurs darguments en ligne de
commande peuvent tre trouvs sur Internet afin de gagner du
temps. Deux bonnes bibliothques peuvent tre utilises pour
dmarrer :
[Link]
[Link]
Ces deux bibliothques peuvent analyser les arguments dune
ligne de commande complexe laide dune interface relative-
ment simple.
3
Manipuler
des chanes
En programmation, quel que soit le langage utilis, une
grande partie des oprations ralises concerne la manipu-
lation des chanes. A lexception des donnes numri-
ques, presque toutes les donnes sont gres sous forme
de chanes. Les donnes numriques sont dailleurs parfois
elles-mmes manipules sous cette forme. On simagine
difficilement comment il serait possible dcrire un pro-
gramme complet sans utiliser la moindre chane.
Les exemples de ce chapitre prsentent des tches couran-
tes lies la manipulation des chanes. Le langage Java
propose une excellente prise en charge des chanes. A la
diffrence du langage C, les chanes sont des types prd-
finis dans le langage Java. Celui-ci contient une classe
String spcifiquement destine contenir les donnes de
chane. En Java, les chanes ne doivent pas tre consid-
res la manire de tableaux de caractres comme elles le
sont en C.
18 CHAPITRE 3 Manipuler des chanes
Chaque fois que vous souhaitez reprsenter une chane en
Java, vous devez utiliser la classe String et non un tableau.
La classe String possde une proprit importante : une
fois cre, la chane est immuable. Les objets Java String
ne peuvent donc plus tre changs aprs quils sont crs.
Vous pouvez attribuer le nom donn une chane un
autre objet String, mais vous ne pouvez pas changer le
contenu de la chane. Vous ne trouverez donc aucune
mthode set dans la classe String. Si vous souhaitez crer
une chane laquelle des donnes peuvent tre ajoutes
(par exemple, dans une routine qui construit progressive-
ment une chane), vous devez utiliser la classe String-
Builder dans le JDK 1.5 ou la classe StringBuffer dans les
versions antrieures du Java, et non la classe String. Les
classes StringBuilder et StringBuffer sont muables : leur
contenu peut tre modifi. Il est trs courant de construire
des chanes en utilisant la classe StringBuilder ou String-
Buffer et de passer ou stocker des chanes en utilisant la
classe String.
Comparer des chanes
La valeur de result et result2 doit tre true si les chanes
ont le mme contenu. Si leur contenu est diffrent,
result et result2 valent false. La premire mthode,
equals(), tient compte de la casse des caractres dans les
chanes. La seconde, equalsIgnoreCase(), ignore la casse
des caractres et retourne true si le contenu est identique
indpendamment de la casse.
boolean result = [Link](str2);
boolean result2 = [Link](str2);
19 Comparer des chanes
Les oprations de comparaison de chanes sont une source
courante de bogues pour les programmeurs dbutants en
Java. Ces derniers sefforcent souvent de comparer leurs
chanes avec loprateur de comparaison ==. Or ce dernier
compare les rfrences dobjet et non le contenu des
objets. Deux objets chane qui contiennent les mmes
donnes de chane mais correspondent des instances
dobjet physiquement distinctes ne sont ds lors pas consi-
drs comme gaux selon cet oprateur.
La mthode equals() de la classe String fait porter la
comparaison sur le contenu de la chane et non sur sa rf-
rence dobjet. En gnral, il sagit de la mthode de com-
paraison souhaite pour les comparaisons de chanes.
Voyez lexemple suivant :
String name1 = new String("Timmy");
String name2 = new String("Timmy");
if (name1 == name2) {
[Link]("The strings are equal.");
}
else {
[Link]("The strings are not equal.");
}
La sortie obtenue aprs lexcution de ces instructions est
la suivante :
The strings are not equal.
A prsent, utilisez la mthode equals() et observez le
rsultat :
String name1 = new String("Timmy");
String name2 = new String("Timmy");
if ([Link](name2)) {
[Link]("The strings are equal.");
20 CHAPITRE 3 Manipuler des chanes
}
else {
[Link]("The strings are not equal.");
}
La sortie obtenue aprs lexcution de ces instructions est
la suivante :
The strings are equal.
La mthode compareTo() est une autre mthode apparen-
te de la classe String. Elle compare alphabtiquement
deux chanes en retournant une valeur entire : positive,
ngative ou gale 0. La valeur 0 nest retourne que si
la mthode equals() est value true pour les deux
chanes. Une valeur ngative est retourne si la chane sur
laquelle la mthode est appele prcde dans lordre
alphabtique celle qui est passe en paramtre la
mthode. Une valeur positive est retourne si la chane
sur laquelle la mthode est appele suit dans lordre alpha-
btique celle qui est passe en paramtre. En fait, la
comparaison seffectue en fonction de la valeur Unicode
de chaque caractre dans les chanes compares. La
mthode compareTo() possde galement une mthode
compareToIgnoreCase() correspondante qui opre de la
mme manire mais en ignorant la casse des caractres.
Considrez lexemple suivant :
String name1="Camden";
String name2="Kerry";
int result = [Link](name2);
if (result == 0) {
[Link]("The names are equal.");
}
21 Rechercher et rcuprer des sous-chanes
else if (result > 0) {
[Link](
"name2 comes before name1 alphabetically.");
}
else if (result < 0) {
[Link](
"name1 comes before name2 alphabetically.");
}
La sortie de ce code est :
name1 comes before name2 alphabetically.
Rechercher et rcuprer
des sous-chanes
Dans la premire mthode, la valeur de result contient
lindex de la premire occurrence de string2 lintrieur
de string1. Si string2 nest pas contenu dans string1, la
valeur -1 est retourne.
Dans la seconde mthode, la valeur de result contient
lindex de la premire occurrence de string2 lintrieur
de string1 qui intervient aprs le cinquime caractre
dans string1. Le second paramtre peut tre nimporte
quel entier valide suprieur 0. Si la valeur est suprieure
la longueur de string1, la valeur -1 est retourne.
Outre rechercher une sous-chane dans une chane, il
peut arriver que vous sachiez o se trouve la sous-chane
et que vous souhaitiez simplement latteindre. La mthode
int result = [Link](string2);
int result = [Link](string2, 5);
22 CHAPITRE 3 Manipuler des chanes
substring() de la chane vous permet de latteindre. Cette
mthode est surcharge, ce qui signifie quil existe plu-
sieurs moyens de lappeler. Le premier consiste lui passer
simplement un index de dpart. Cette mthode retourne
une sous-chane qui commence lindex de dpart et
stend jusqu la fin de la chane. Lautre moyen dutiliser
substring() consiste lappeler avec deux paramtres
un index de dpart et un index de fin.
String string1 = "My address is 555 Big Tree Lane";
String address = [Link](14);
[Link](address);
Ce code produit la sortie suivante :
555 Big Tree Lane
Le premier caractre 5 se trouve la position 14 de la
chane. Il sagit donc du dbut de la sous-chane. Notez
que les chanes sont toujours indexes en commenant 0
et que le dernier caractre se trouve lemplacement
(longueur de la chane) - 1.
Traiter une chane caractre
par caractre
La mthode charAt()permet dobtenir un unique caractre
de la chane lindex spcifi. Les caractres sont indexs
en commenant 0, de 0 (longueur de la chane) - 1.
for (int index = 0; index < [Link]();
index++) {
char aChar = [Link](index);
}
23 Renverser une chane par caractre
Cet exemple parcourt en boucle chaque caractre contenu
dans string1. Il est aussi possible de procder en utilisant
la classe StringReader, comme ceci :
StringReader reader = new StringReader(string1);
int singleChar = [Link]();
Avec ce mcanisme, la mthode read() de la classe Strin-
gReader retourne un caractre la fois, sous forme
dentier. A chaque fois que la mthode read() est appele,
le caractre suivant de la chane est retourn.
Renverser une chane
par caractre
La classe StringBuffer contient une mthode reverse()
qui retourne un StringBuffer contenant les caractres du
StringBuffer original, mais inverss. Un objet StringBuf-
fer peut aisment tre converti en objet String laide de
la mthode toString() de lobjet StringBuffer. En utili-
sant temporairement un objet StringBuffer, vous pouvez
ainsi produire une seconde chane avec les caractres
dune chane dorigine, en ordre invers.
Si vous utilisez le JDK 1.5, vous pouvez utiliser la classe
StringBuilder au lieu de la classe [Link]-
Builder possde une API compatible avec la classe
StringBuffer. Elle propose de meilleures performances,
mais ses mthodes ne sont pas synchronises. Elle nest
donc pas thread-safe. En cas de multithreading, vous devez
continuer utiliser la classe StringBuffer.
String letters = "ABCDEF";
StringBuffer lettersBuff = new StringBuffer(letters);
String lettersRev = [Link]().toString();
24 CHAPITRE 3 Manipuler des chanes
Renverser une chane par mot
La sortie de ce fragment de code est la suivante :
Original string: Reverse this string
Reversed string: string this Reverse
Comme vous pouvez le voir, le renversement dune
chane par mot est plus complexe que le renversement
dune chane par caractre. Cest quil existe un support
intgr dans Java pour le renversement par caractre, et
non pour le renversement par mot. Pour raliser cette
dernire tche, nous utilisons les classes StringTokenizer
et Stack. Avec StringTokenizer, nous parsons chaque
mot de la chane et le poussons dans notre pile. Une fois
la chane entire traite, nous parcourons la pile en boucle
en dpilant chaque mot et en lajoutant un StringBuffer
qui stocke la chane inverse.
String test = "Reverse this string";
Stack stack = new Stack();
StringTokenizer strTok = new StringTokenizer(test);
while([Link]()) {
[Link]([Link]());
}
StringBuffer revStr = new StringBuffer();
while(![Link]()) {
[Link]([Link]());
[Link](" ");
}
[Link]("Original string: " + test);
[Link]("\nReversed string: " + revStr);
25 Convertir une chane en majuscules ou en minuscules
Dans la pile, le dernier lment entr est par principe le
premier sorti une proprit baptise LIFO (last in, first
out) que nous exploitons pour effectuer linversion.
Consultez l'exemple trait dans la section "Parser une
chane spare par des virgules" de ce chapitre pour
dautres utilisations de la classe StringTokenizer.
Info
Nous nen traiterons pas ici, mais un nouvel ajout du JDK 1.5
peut vous intresser : la classe Scanner. Cette classe est un
analyseur de texte lmentaire permettant de parser des types
primitifs et des chanes laide dexpressions rgulires.
Convertir une chane en
majuscules ou en minuscules
Ces deux mthodes transforment une chane en majuscu-
les ou en minuscules uniquement. Elles retournent toutes
deux le rsultat transform. Ces mthodes naffectent pas
la chane dorigine. Celle-ci reste intacte avec une casse
mixte.
Ces mthodes peuvent notamment tre utiles lors du
stockage dinformations dans une base de donnes, par
exemple si vous souhaitez stocker des valeurs de champ en
majuscules ou en minuscules uniquement. Grce ces
mthodes, lopration de conversion est un jeu denfant.
String string = "Contains some Upper and some Lower.";
String string2 = [Link]();
String string3 = [Link]();
26 CHAPITRE 3 Manipuler des chanes
La conversion de la casse est galement utile pour la ges-
tion des interfaces dauthentification des utilisateurs. Le
champ dID de lutilisateur est normalement considr
comme tant un champ qui ne doit pas tenir compte de la
casse, alors que le champ de mot de passe en tient compte.
Lors de la comparaison de lID utilisateur, vous pouvez
ainsi convertir lID en majuscules ou en minuscules puis
le comparer une valeur stocke dans la casse approprie.
Vous pouvez aussi utiliser la mthode equalsIgnoreCase()
de la classe String, qui ralise une comparaison sans tenir
compte de la casse.
Supprimer les espaces au dbut
et la n dune chane
La mthode trim() supprime les espaces de dbut et de fin
dune chane et retourne le rsultat. La chane originale
reste inchange. Sil ny a pas despace de dbut ou de fin
supprimer, la chane dorigine est retourne. Les espaces
et les caractres de tabulation sont supprims.
Cette mthode est trs utile lorsquil sagit de comparer
des entres saisies par lutilisateur avec des donnes exis-
tantes. Bien des programmeurs se sont creus la tte de
nombreuses heures en se demandant pourquoi les don-
nes saisies ntaient pas identiques la chane stocke et
se sont finalement aperu que la diffrence ne tenait qu
un simple espace blanc la fin de la chane. La suppression
des espaces avant les comparaisons limine entirement ce
problme.
String result = [Link]();
27 Parser une chane spare par des virgules
Parser une chane spare
par des virgules
La mthode split() de la classe String accepte une expres-
sion rgulire comme unique paramtre et retourne un
tableau dobjets String dcompos selon les rgles de
lexpression rgulire passe. Le parsing des chanes spa-
res par des virgules devient ainsi un jeu denfant. Dans
cet exemple, nous passons simplement une virgule la
mthode split() et obtenons un tableau de chanes con-
tenant les donnes spares par des virgules. Le tableau de
rsultat de notre exemple contient ainsi les donnes
suivantes :
results[0] = tim
results[1] = kerry
results[2] = timmy
results[3] = camden
La classe StringTokenizer est elle aussi utile pour
dcomposer des chanes. Lexemple prcdent peut tre
repris avec cette classe au lieu de la mthode split() :
String str = "tim,kerry,timmy,Camden";
StringTokenizer st = new StringTokenizer(str, ",");
while ([Link]()) {
[Link]([Link]());
}
String str = "tim,kerry,timmy,camden";
String[] results = [Link](",");
28 CHAPITRE 3 Manipuler des chanes
Cet exemple de code imprime chacun des noms contenus
dans la chane dorigine (str) sur une ligne spare,
comme ceci :
tim
kerry
timmy
camden
Notez que les virgules sont supprimes (elles ne sont pas
imprimes). La classe StringTokenizer peut tre construite
avec un, deux ou trois paramtres. Lorsquelle est appele
avec un seul paramtre, le paramtre correspond la
chane diviser. Dans ce cas, le dlimiteur utilis corres-
pond aux limites naturelles de mot par dfaut. Le tokenizer
utilise ainsi le jeu de dlimiteurs " \t\n\r\f" (le caractre
despace, le caractre de tabulation, le caractre de nou-
velle ligne, le caractre de retour chariot et le caractre
davancement de page).
Le deuxime moyen de construire un objet StringToke-
nizer consiste passer deux paramtres au constructeur.
Le premier paramtre correspond alors la chane
dcomposer et le second la chane contenant les dlimi-
teurs en fonction desquels la chane doit tre divise. Ce
paramtre vient remplacer les dlimiteurs par dfaut.
Pour finir, vous pouvez passer un troisime argument au
constructeur StringTokenizer qui indique si les dlimi-
teurs doivent tre retourns sous forme de jetons ou sup-
prims. Ce paramtre est boolen. Si vous passez la valeur
true, les dlimiteurs sont retourns sous forme de jetons.
Par dfaut, le paramtre vaut false. Il supprime les dli-
miteurs et ne les traite pas comme des jetons.
29 Parser une chane spare par des virgules
Examinez aussi les exemples du Chapitre 6. Avec lajout
du support des expressions rgulires en Java propos par
le JDK 1.4, il devient souvent possible dutiliser des
expressions rgulires au lieu de la classe StringTokenizer.
La documentation JavaDoc officielle stipule que la classe
StringTokenizer est une classe hrite dont lusage doit
tre dconseill dans le nouveau code. Dans la mesure du
possible, utilisez donc la mthode split() de la classe
String ou le paquetage Java pour les expressions rgulires.
4
Travailler avec des
structures de donnes
On appelle "structure de donnes" un dispositif servant
organiser les donnes utilises par un programme. Chaque
fois que vous travaillez avec des groupes dlments de
donnes similaires, il est judicieux dutiliser une structure
de donnes. Le Java offre une excellente gestion des diff-
rents types de structures de donnes, dont les tableaux, les
listes, les dictionnaires et les ensembles. La plupart des
classes Java servant travailler avec les structures de don-
nes sont livres dans le framework Collections, une archi-
tecture unifie pour la reprsentation et la manipulation
de collections ou de structures de donnes. Les classes de
structure de donnes les plus couramment utilises sont
ArrayList et HashMap. La plupart des exemples de ce cha-
pitre sy rfrent.
Lexpression "structure de donnes" peut sappliquer la
manire dont les donnes sont ordonnes dans un fichier
ou une base de donnes tout autant quen mmoire. Tous
les exemples de ce chapitre traitent des structures de don-
nes en mmoire.
32 CHAPITRE 4 Travailler avec des structures de donnes
Info
Sun met disposition un document (en anglais) qui offre une
bonne vue densemble du framework Collections et propose des
didacticiels sur lutilisation des diffrentes classes. Pour consul-
ter ce document, rendez-vous ladresse suivante : http://
[Link]/j2se/1.5.0/docs/guide/collections/[Link].
Redimensionner un tableau
En Java, les tableaux dobjets normaux ou de types primi-
tifs ne peuvent pas tre redimensionns de manire dyna-
mique. Si vous souhaitez quun tableau soit agrandi par
rapport sa dclaration dorigine, vous devez dclarer un
nouveau tableau plus grand, puis copier le contenu du
premier tableau dans le nouveau. La procdure peut pren-
dre la forme suivante :
int[] tmp = new int[[Link] + 10];
[Link](myArray, 0, tmp, 0, [Link]);
myArray = tmp;
Dans cet exemple, nous souhaitons agrandir la taille dun
tableau dentiers appel myArray afin de lui ajouter dix l-
ments. Nous crons donc un nouveau tableau appel tmp et
linitialisons en lui attribuant la longueur de myArray + 10.
Nous utilisons ensuite la mthode [Link]()
pour copier le contenu de myArray dans le tableau tmp.
Pour finir, nous positionnons myArray de manire ce
quil pointe sur le tableau tmp nouvellement cr.
En gnral, la meilleure solution pour ce type de pro-
blme consiste utiliser un objet ArrayList au lieu dun
tableau dobjets classique. Lobjet ArrayList peut contenir
// Utiliser un ArrayList
List myArray = new ArrayList();
33 Parcourir une collection en boucle
nimporte quel type dobjet. Son principal intrt tient
ce quil se redimensionne automatiquement selon les
besoins. Lorsque vous utilisez un ArrayList, vous navez
plus vous soucier de la taille de votre tableau en vous
demandant si vous risquez de manquer de place. Limpl-
mentation ArrayList est en outre bien plus efficace que
la mthode prcdente qui consiste copier le tableau
redimensionner dans un nouveau tableau. Lobjet Array-
List fait partie du paquetage [Link].
Parcourir une collection en boucle
// Pour un ensemble ou une liste
// collection est l'objet set ou list
for (Iterator it= [Link](); [Link](); )
{
Object element = [Link]();
}
// Pour les cls d'un dictionnaire
for (Iterator it = [Link]().iterator(); [Link]();
) {
Object key = [Link]();
}
// Pour les valeurs d'un dictionnaire
for (Iterator it = [Link]().iterator(); [Link]();
) {
Object value = [Link]();
}
// Pour les cls et les valeurs d'un dictionnaire
for (Iterator it = [Link]().iterator();
[Link](); ) {
[Link] entry = ([Link])[Link]();
Object key = [Link]();
Object value = [Link]();
}
34 CHAPITRE 4 Travailler avec des structures de donnes
Le paquetage [Link] contient une classe Iterator qui
facilite le parcours en boucle des collections. Pour par-
courir en boucle un objet collection, vous devez dabord
obtenir un objet Iterator en appelant la mthode itera-
tor() de lobjet collection. Lorsque vous avez lobjet
Iterator, il ne reste plus qu le parcourir pas pas avec la
mthode next(). Cette mthode retourne llment sui-
vant de la collection.
La mthode next() retourne un type Object gnrique.
Vous devez donc transtyper la valeur de retour afin de lui
attribuer le type attendu. La mthode hasNext() vous per-
met quant elle de vrifier sil existe dautres lments qui
nont pas encore t traits. En combinant ces deux
mthodes, vous pouvez ainsi aisment crer une boucle
for pour parcourir un un chacun des lments dune
collection, comme le montre lexemple prcdent.
Lexemple prcdent indique aussi comment parcourir en
boucle un ensemble ou une liste, les cls dun diction-
naire, les valeurs dun dictionnaire et les cls et les valeurs
dun dictionnaire.
Info
Les itrateurs peuvent tre utiles pour exposer des collections
via une API. Lavantage quapporte lexposition des donnes
laide dun itrateur tient ce que le code appelant na pas se
soucier de la manire dont les donnes sont stockes. Cette
implmentation permet de changer le type de collection sans
avoir modifier lAPI.
35 Crer une collection mappe
Crer une collection mappe
Cet exemple utilise un HashMap pour crer une collection
mappe dobjets. Le HashMap possde une mthode put()
qui prend deux paramtres. Le premier est une valeur de
cl et le second lobjet que vous souhaitez stocker dans le
dictionnaire. Dans cet exemple, nous stockons donc trois
objets (obj1, obj2 et obj3) en les indexant avec des cls
(respectivement key1, key2 et key3). La classe HashMap est
lune des classes Java les plus couramment utilises. Dans
un HashMap, les objets placs dans un dictionnaire doivent
tous tre du mme type de classe. Si obj1 est un objet
String, obj2 et obj3 doivent donc galement tre des
objets String.
Pour rcuprer les objets placs dans la collection, vous
utilisez la mthode get() du HashMap. Elle prend un unique
paramtre correspondant la cl de llment rcuprer.
Si llment est trouv, il est retourn sous forme dobjet
gnrique Object : il faut donc le transtyper pour lui attri-
buer le type dsir. Si llment que vous tentez de
rcuprer nexiste pas, la valeur null est retourne.
Info
Le JDK 1.5 introduit une nouvelle fonctionnalit du langage,
les gnriques, permettant de rcuprer des lments dun Has-
hMap sans avoir raliser de transtypage. Sun propose un
excellent article sur lutilisation des gnriques ladresse
suivante : [Link]
/generics/[Link].
HashMap map = new HashMap();
[Link](key1, obj1);
[Link](key2, obj2);
[Link](key3, obj3);
36 CHAPITRE 4 Travailler avec des structures de donnes
Les objets utiliss comme valeurs de cl dans un HashMap
doivent implmenter les mthodes equals() et hashCode().
Ces mthodes sont utilises par limplmentation HashMap
pour retrouver les lments dans le dictionnaire. Si elles
ne sont pas implmentes dans un objet utilis comme
valeur de cl, les objets cls sont retrouvs en fonction
de leur identit uniquement. Dans ce cas, pour trouver
une cl concordante, vous devrez passer linstance dobjet
elle-mme lorsque vous essayerez de rcuprer un objet :
a priori, ce nest pas le but recherch !
Stocker une collection
La classe Arrays est une classe du paquetage [Link]
contenant un grand nombre de mthodes statiques servant
manipuler des tableaux. La plus utile dentre elles est sans
doute la mthode sort(). Cette mthode prend un tableau
dobjets ou de types primitifs et des index de dbut et de
fin. Lindex de dbut spcifie lindex du premier lment
trier et lindex de fin celui du dernier lment trier.
Les primitifs sont tris par ordre croissant. Lorsque
cette mthode est utilise pour trier des objets, tous
les objets doivent implmenter linterface Comparable,
dfaut de quoi un objet Comparator peut tre pass.
// Trier un tableau
int[] myInts = {1,5,7,8,2,3};
[Link](myInts);
// Trier une liste
List myList = new ArrayList();
[Link](obj1);
[Link](obj2);
[Link](myList);
37 Stocker une collection
Dans lexemple prcdent, nous commenons avec un
tableau dentiers de type int. Nous passons ce tableau la
mthode [Link]() qui le trie. Notez bien que cest
le tableau lui-mme qui est pass : il est donc directement
tri et modifi. La mthode sort() ne retourne pas de
nouveau tableau tri : son type de retour est void.
La classe Collections, autre classe du paquetage [Link],
contient des mthodes statiques qui oprent sur dautres
objets de collection. La mthode sort() prend un objet
List en entre et trie les lments dans la liste par ordre
croissant, selon lordre naturel des lments. Comme avec
la mthode sort() de lobjet Arrays, tous les lments
dans lobjet List pass la mthode doivent implmenter
linterface Comparable dfaut de quoi un objet Compara-
tor peut tre pass avec lobjet List. La liste passe la
mthode sort() est elle-mme modifie.
Dans la seconde partie de notre exemple, nous crons un
objet ArrayList et utilisons la mthode Collec-
[Link]() pour le trier. Dans cet exemple, aucun objet
Comparator na t pass, aussi les objets obj1 et obj2 doi-
vent imprativement implmenter linterface Comparable.
Si lordre de tri par dfaut ne vous convient pas, vous
pouvez implmenter linterface Comparator pour dfinir
votre propre mcanisme de tri. Le comparateur que vous
dfinissez peut ensuite tre pass comme second argument
la mthode sort() de la classe Collections ou Arrays.
En plus des classes que nous venons de citer, le fra-
mework Collections contient des classes dont le tri est
inhrent, comme les objets TreeSet et TreeMap. Si vous
utilisez ces classes, les lments sont automatiquement
tris lorsquils sont placs dans la collection. Dans le cas
dun TreeSet, les lments sont tris par ordre croissant
38 CHAPITRE 4 Travailler avec des structures de donnes
daprs linterface Comparable ou daprs le Comparator
fourni au moment de la cration. Dans le cas dun TreeMap,
les lments sont tris par ordre croissant de cl daprs
linterface Comparable ou daprs le Comparator fourni au
moment de la cration.
Trouver un objet
dans une collection
Ces exemples montrent comment retrouver des objets
dans les collections les plus couramment utiliss : Array-
List et HashMap. La mthode indexOf() de lobjet Array-
List permet de retrouver la position dans le tableau
laquelle se trouve un objet particulier. Si lobjet pass la
mthode indexOf() nest pas retrouv, la mthode
retourne -1. Lobjet HashMap indexe les lments par
objets et non par valeurs entires comme le fait lobjet
ArrayList. Les mthodes containsValue() ou contains-
Key() peuvent tre utilises pour dterminer si le HashMap
contient lobjet pass comme valeur ou comme cl dans le
dictionnaire. Elles retournent une valeur boolenne.
Deux autres mthodes, binarySearch() et contains(),
permettent galement de retrouver des objets dans des
collections. La mthode binarySearch() est une mthode
// Trouver un objet dans un ArrayList
int index = [Link](myStringObj);
// Trouver un objet par valeur dans un HashMap
[Link](myStringObj);
// Trouver un objet par cl dans un HashMap
[Link](myStringObj);
39 Trouver un objet dans une collection
des classes utilitaires Arrays et Collections. Elle effectue
une recherche dans un tableau selon lalgorithme de
recherche binaire. Le tableau doit tre tri avant dappeler
la mthode binarySearch() de la classe Arrays. Sans cela,
les rsultats sont indfinis. Le tri du tableau peut tre ra-
lis avec la mthode [Link](). Si le tableau contient
plusieurs lments possdant la valeur spcifie comme
valeur de recherche, rien ne permet de dterminer celui
qui sera retrouv. Selon la mme logique, la mthode
binarySearch() de la classe Collections ne doit tre utili-
se que sur une collection dj trie par ordre croissant
selon lordre naturel de ses lments. Ce tri peut tre ra-
lis avec la mthode [Link](). Comme pour les
tableaux, lemploi de binarySearch() sur une collection
non trie produit des rsultats indfinis. Sil existe plusieurs
lments correspondant lobjet recherch, rien ne per-
met non plus de dterminer celui qui sera retrouv.
Lorsque la collection nest pas dj trie, il peut tre
prfrable dutiliser la mthode indexOf() plutt que de
raliser le tri (sort()) puis la recherche binaire (binary-
Search()). Lopration de tri (sort()) peut tre coteuse
dans le cas de certaines collections.
Lexemple suivant utilise la mthode binarySearch() pour
effectuer une recherche dans un tableau dentiers :
int[] myInts = new int[]{7, 5, 1, 3, 6, 8, 9, 2};
[Link](myInts);
int index = [Link](myInts, 6);
[Link]("Value 6 is at index: " + index);
Ce code produit la sortie suivante :
The value 6 is at index 4.
40 CHAPITRE 4 Travailler avec des structures de donnes
La classe ArrayList possde galement une mthode
contains() qui peut tre utilise pour vrifier si un objet
donn est membre dun ArrayList donn.
Convertir une collection
en un tableau
Comme le montre cet exemple, il est assez simple en Java
de convertir une collection telle quun ArrayList ou un
HashMap en un tableau dobjets standard.
Lobjet ArrayList possde une mthode toArray() qui
retourne un tableau dobjets. La conversion dun HashMap
en un tableau est lgrement diffrente. Il faut dabord
obtenir les valeurs stockes dans le HashMap sous forme de
tableau en utilisant la mthode entrySet().
La mthode entrySet() retourne les valeurs de donnes
sous forme de Set Java. Une fois que lobjet Set est
obtenu, nous pouvons appeler la mthode toArray() pour
rcuprer un tableau contenant les valeurs stockes dans le
HashMap.
// Convertir un ArrayList en un tableau dobjets
Object[] objects = [Link]();
// Convertir un HashMap en un tableau d'objets
Object[] mapObjects = [Link]().toArray();
5
Dates et heures
La plupart des programmes Java sont immanquablement
conduits devoir grer des dates et des heures un
moment ou un autre. Fort heureusement, la gestion des
dates et des heures est fort bien intgre Java. Trois clas-
ses principales sont utilises dans la plupart des program-
mes pour stocker et manipuler les heures et les dates :
[Link], [Link] et [Link].
Bon nombre des mthodes de la classe [Link]
sont maintenant dconseilles : vous devez donc viter de
les utiliser pour vos nouveaux projets de dveloppement.
Les mthodes dconseilles concernent pour la plupart la
cration et la manipulation des dates. Dans le cas de ces
oprations, il est prfrable dutiliser le mcanisme de la
classe [Link]. Les conversions entre les
objets Date et Calendar sont faciles. Si vous prfrez passer
vos dates sous forme dobjets Date, il est donc parfaite-
ment possible dviter les mthodes dconseilles. Vous
devez alors simplement convertir vos dates en objets
Calendar au moment de les manipuler. Lun des exemples
de ce chapitre montre comment effectuer la conversion
entre les objets Date et les objets Calendar.
42 CHAPITRE 5 Dates et heures
Retrouver la date daujourdhui
Il est impratif que vous soyez familiaris avec lobjet Date
du paquetage [Link] si vos programmes traitent avec
des dates et des heures, car cet objet est trs frquemment
utilis. Il permet notamment de rcuprer trs simple-
ment la date et lheure courantes. Lorsque vous crez une
instance de lobjet Date, celle-ci est initialise avec lheure
et la date courantes.
La classe Calendar propose une autre mthode pour
rcuprer la date et lheure courantes, comme ceci :
Calendar cal = [Link]();
Cette ligne produit un objet Calendar nomm cal et lini-
tialise avec la date et lheure courantes.
Conversion entre les objets
Date et Calendar
En travaillant avec des heures et des dates, vous constate-
rez souvent quil est ncessaire deffectuer une conversion
entre des objets Java Date et Calendar. Cette tche est
Date today = new [Link]();
[Link]("Todays Date is " + [Link]());
// Conversion de Date Calendar
Date myDate = new [Link]();
Calendar myCal = [Link]();
[Link](myDate);
// Conversion de Calendar Date
Calendar newCal = [Link]();
Date newDate = [Link]();
43 Conversion entre les objets Date et Calendar
heureusement trs simple, comme en atteste lexemple
prcdent. Lobjet Calendar possde une mthode set-
Time() qui prend un objet [Link] en entre et
positionne lobjet Calendar en lui attribuant la date et
lheure contenues dans lobjet Date pass. Pour la conver-
sion inverse, vous pouvez utiliser la mthode getTime()
de la classe Calendar qui retourne la date et lheure du
calendrier sous forme dobjet [Link].
La plupart des applications Java se servent des classes Date
et Calendar. De l limportance quil y a se familiariser
avec le processus de conversion dun type vers lautre. Il
est conseill de crer des mthodes utilitaires pour raliser
ces conversions afin de pouvoir les utiliser depuis
nimporte quel emplacement du code au moyen dun
simple appel de mthode. Voici des mthodes simples
pour la conversion des objets Calendar en objets Date et
des objets Date en objets Calendar :
public static Date calToDate(Calendar cal) {
return [Link]();
}
public static Calendar dateToCal(Date date) {
Calendar myCal = [Link]();
[Link](date);
return myCal;
}
44 CHAPITRE 5 Dates et heures
Imprimer une date/une heure
dans un format spci
Le Java contient des classes de formatage qui peuvent tre
utilises pour appliquer une date un format dsir. La
classe la plus couramment utilise pour le formatage des
dates est la classe SimpleDateFormat. Elle prend une chane
de format en entre de son constructeur et retourne un
objet de format qui peut tre utilis ensuite pour formater
des objets Date. La mthode format() de lobjet SimpleDa-
teFormat retourne une chane contenant la reprsentation
formate de la Date passe en paramtre.
Voici la sortie de lexemple prcdent :
Todays Date and Time is: jeu., 04 janv. 2007 16:48:38
La chane de format passe au constructeur SimpleDate-
Format peut paratre un peu obscure si vous ne connaissez
pas les codes de formatage utiliser. Le Tableau 5.1 pr-
sente les codes qui peuvent tre passs au constructeur de
SimpleDateFormat. Dans notre exemple, nous avons utilis
la chane de format suivante :
"EEE, dd MMM yyyy HH:mm:ss"
Dcomposons cette chane en nous rfrant au Tableau 5.1,
afin de comprendre le format demand :
b EEE : reprsentation sur trois caractres du jour de la
semaine (par exemple, Mar).
b , : place une virgule dans la sortie.
Date todaysDate = new [Link]();
SimpleDateFormat formatter =
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
String formattedDate = [Link](todaysDate);
[Link]("Todays Date and Time is: " +
formattedDate);
45 Imprimer une date/une heure dans un format spcifi
b dd : reprsentation sur deux caractres du jour du mois
(01 31).
b MMM : reprsentation sur trois caractres du mois de
lanne (par exemple, Jul).
b yyyy : reprsentation sur quatre caractres de lanne
(par exemple, 2006).
b HH:mm:ss : heure, minutes et secondes, spares par des
deux-points (par exemple, 11:18:33).
Ces lments combins produisent la chane de date
suivante :
jeu., 04 janv. 2007 16:48:38
Tableau 5.1 : Codes de format de date et dheure
Lettre
Composant de
date ou dheure
Prsentation Exemples
G Dsignateur dre Texte AD
y Anne Anne 1996 ; 96
M Mois de lanne Mois Juillet ; Jul ; 07
w Semaine de lanne Nombre 27
W Semaine du mois Nombre 2
D Jour de lanne Nombre 189
d Jour du mois Nombre 10
F Jour de la semaine
dans le mois
Nombre 2
E Jour de la semaine Texte Mardi ; Mar
a Marqueur
A.M./P.M.
Texte PM
46 CHAPITRE 5 Dates et heures
En plus de crer vos propres chanes de format, vous
pouvez utiliser lune des chanes de format prdfinies
avec les mthodes getTimeInstance(), getDateInstance()
ou getDateTimeInstance() de la classe DateFormat. Par
exemple, le code suivant retourne un objet formateur qui
utilisera un format de date pour vos paramtres rgionaux
par dfaut :
DateFormat df = [Link]();
H Heure du
jour (0 23)
Nombre 0
k Heure du
jour (1 24)
Nombre 24
K Heure au format
A.M./P.M. (0 11)
Nombre 0
h Heure au format
A.M./P.M. (1 12)
Nombre 12
m Minutes
dans lheure
Nombre 30
s Secondes
dans la minute
Nombre 55
S Millisecondes Nombre 978
z Fuseau horaire Fuseau horaire
gnral
Pacific
Standard Time ;
PST ; GMT-08:00
Z Fuseau horaire Fuseau horaire
RFC 822
-0800
Tableau 5.1 : Codes de format de date et dheure (suite)
Lettre
Composant de
date ou dheure
Prsentation Exemples
47 Parser des chanes en dates
Le formateur df peut ensuite tre utilis exactement
comme nous avons utilis lobjet SimpleDateFormat dans
notre exemple prcdent. Consultez la documentation
JavaDoc disponible pour la classe DateFormat pour obte-
nir des informations dtailles sur les objets de forma-
tage dheure et de date standard disponibles ladresse
[Link]
[Link].
Parser des chanes en dates
Lobjet DateFormat est utilis pour parser un objet String
et obtenir un objet [Link]. La mthode getDa-
teInstance() cre un objet DateFormat avec le format de
date standard de votre pays. Vous pouvez ensuite utiliser
la mthode parse() de lobjet DateFormat retourn pour
parser votre chane de date et obtenir un objet Date,
comme le montre cet exemple.
La mthode parse() accepte aussi un second paramtre
qui spcifie la position dans la chane partir de laquelle
lanalyse doit tre effectue.
Les classes [Link], [Link] et [Link]
.Timestamp contiennent une mthode statique appele
valueOf() qui peut galement tre utilise pour parser des
chanes de date simples au format aaaa-mm-jj. Elles sont
trs utiles pour convertir en objets Date des dates utilises
dans des chanes SQL avec des objets JDBC.
String dateString = "January 12, 1952 or 3:30:32pm";
DateFormat df = [Link]();
Date date = [Link](dateString);
48 CHAPITRE 5 Dates et heures
Ces techniques sont utiles pour convertir des donnes de
date entres par lutilisateur en objets Date Java pour un
traitement ultrieur dans votre application. Vous pou-
vez rcuprer les dates entres par lutilisateur sous forme
de chane et les convertir en objets Date laide de ces
techniques.
Additions et soustractions
avec des dates ou des calendriers
Si vous utilisez un objet Date, la technique dajout ou de
soustraction des dates consiste convertir dabord lobjet
en une valeur long en utilisant la mthode getTime() de
lobjet Date. La mthode getTime() retourne lheure
mesure en millisecondes depuis le dbut de "lre"
UNIX (1
er
janvier 1970, 00 h 00 s 00 ms GMT). Ensuite,
vous devez raliser lopration arithmtique avec des
valeurs long et reconvertir le rsultat en objet Date. Dans
lexemple prcdent, nous ajoutons 5 jours lobjet Date.
Nous convertissons les 5 jours en millisecondes en multi-
pliant 5 par le nombre dheures dans une journe (24), le
nombre de minutes dans une heure (60), le nombre de
secondes dans une minute (60) et finalement par 1 000
pour convertir les secondes en millisecondes.
// Arithmtique de dates utilisant des objets Date
Date date = new Date();
long time = [Link]();
time += 5*24*60*60*1000;
Date futureDate = new Date(time);
// Arithmtique de dates utilisant des objets Calendar
Calendar nowCal = [Link]();
[Link]([Link], 5);
49 Calculer la diffrence entre deux dates
Les oprations arithmtiques de date peuvent tre ra-
lises directement sur des objets Calendar en utilisant la
mthode add(). Cette mthode prend deux paramtres,
un champ et une quantit, tous deux de type int. La
quantit spcifie est ajoute au champ spcifi. Le champ
peut correspondre nimporte quel champ de date valide,
comme un jour, une semaine, un mois, une anne, etc.
Pour soustraire une heure, vous devez utiliser une valeur
ngative. En positionnant le paramtre de champ la
constante Calendar approprie, vous pouvez directement
ajouter ou soustraire des jours, des semaines, des mois, des
annes, etc. La seconde partie de lexemple prcdent
montre comment ajouter 5 jours un objet Calendar.
Calculer la diffrence
entre deux dates
Cet exemple convertit deux objets de date date1 et date2
en millisecondes chacun reprsent sous forme de long.
La diffrence est calcule en soustrayant time1 time2. La
diffrence calcule en jours est ensuite imprime en ra-
lisant lopration arithmtique ncessaire pour convertir la
diffrence en millisecondes en une diffrence en jours.
Il arrivera souvent que vous souhaitiez dterminer la
dure qui spare deux dates, par exemple en calculant le
nombre de jours restants avant lexpiration dun produit.
long time1 = [Link]();
long time2 = [Link]();
long diff = time2 time1;
[Link]("Difference in days = " +
diff/(1000*60*60*24));
50 CHAPITRE 5 Dates et heures
Si vous connaissez la date dexpiration dun produit, vous
pouvez calculer le nombre de jours avant expiration en
calculant la diffrence entre la date dexpiration et la date
courante.
Voici un exemple de mthode pour raliser ce calcul :
public static void daysTillExpired(Date expDate) {
Date currentDate = new Date();
long expTime = [Link]();
long currTime = [Link]();
long diff = expTime currTime;
return diff/(1000*60*60*24);
}
Cette mthode prend une date dexpiration en entre et
calcule le nombre de jours jusqu la date dexpiration.
Cette valeur en jours est retourne par la mthode. Elle
peut fournir un nombre ngatif si la date dexpiration est
dpasse.
Comparer des dates
if ([Link](date2)) {
[Link]("dates are the same.");
}
else {
if ([Link](date2)) {
[Link]("date1 before date2");
}
else {
[Link]("date1 after date2");
}
}
51 Retrouver le jour de la semaine/ du mois/de lanne ou le numro de la semaine
Cet exemple utilise les mthodes equals() et before() de
la classe Date. La mthode equals() retourne true si les
valeurs de donnes sont les mmes. Sinon, elle retourne
false. Les dates doivent tre les mmes la milliseconde
prs pour que la mthode equals() retourne true. La
mthode before() retourne true si la date sur laquelle elle
est appele intervient avant la date qui lui est passe en
paramtre.
La classe Date possde galement une mthode after qui
est utilise de manire analogue la mthode before()
pour dterminer si la date partir de laquelle elle est appe-
le intervient aprs la date passe en paramtre.
La mthode compareTo() de la classe Date est aussi utile
pour comparer deux dates. Elle prend un argument de det
retourne une valeur dentier. Elle retourne 0 si la date
partir de laquelle elle est appele quivaut celle passe en
argument, une valeur ngative si elle lui est antrieure et
une valeur positive si elle lui est ultrieure.
Retrouver le jour de la semaine/
du mois/de lanne ou le numro
de la semaine
Calendar cal = [Link]();
[Link]("Day of week: " +
[Link](Calendar.DAY_OF_WEEK));
[Link]("Month: " + [Link]([Link]));
[Link]("Year: " + [Link]([Link]));
[Link]("Week number: " +
[Link](Calendar.WEEK_OF_YEAR));
52 CHAPITRE 5 Dates et heures
Vous pouvez aisment dterminer des valeurs comme le
jour de la semaine, le mois, lanne ou le numro de
semaine avec la mthode get() de lobjet Calendar. Dans
lexemple prcdent, nous obtenons un objet Calendar
reprsentant la date et lheure courantes avec la mthode
getInstance(). Nous imprimons ensuite le jour de la
semaine, le mois, lanne puis la semaine de lanne en
utilisant la mthode get() et en passant la constante
Calendar approprie pour spcifier le champ rcuprer.
Pour obtenir ces valeurs avec un objet Date, vous devez
dabord convertir lobjet Date en un objet Calendar en
utilisant la mthode setTime() dune instance Calendar et
en passant lobjet Date convertir. La conversion entre les
objets Date et Calendar a t prsente prcdemment
dans ce chapitre.
Calculer une dure coule
En calculant une dure coule, vous pouvez dterminer
le temps requis pour raliser une action ou le temps de
progression dun processus. Pour cela, vous devez utiliser
la mthode [Link]() afin dobtenir
lheure courante en millisecondes. Cette mthode doit tre
utilise au dbut et la fin de la tche chronomtrer, afin
de calculer la diffrence entre les deux mesures. La valeur
retourne par la mthode [Link]()
correspond au temps coul depuis le 1
er
janvier 1970,
00 h 00 s 00 ms, en millisecondes.
long start = [Link]();
// Raliser une autre action
long end = [Link]();
long elapsedTime = end start;
53 Calculer une dure coule
Le JDK 1.5 introduit une mthode nanoTime() dans la
classe System, qui permet dobtenir une mesure plus pr-
cise encore, la nanoseconde. Toutes les plates-formes ne
prennent cependant pas en charge cette prcision : bien
que la mthode nanoTime() soit disponible, il nest donc
pas toujours possible de compter sur une mesure en nano-
secondes. Ce niveau de prcision est souvent utile pour
les tests, le profilage et lanalyse des performances.
6
Retrouver des motifs
avec des expressions
rgulires
Les expressions rgulires ont t introduites en Java la
sortie du JDK 1.4. Les expressions rgulires spcifient
des motifs pouvant tre retrouvs dans des squences de
caractres. Elles sont particulirement utiles pour lanalyse
des chanes et conomisent souvent au programmeur bien
du temps et des efforts par rapport aux solutions qui ny
font pas appel. Avant dtre ajoutes au Java, elles ont t
utilises pendant des annes par les programmeurs UNIX.
Les outils UNIX standard comme sed et awk les
emploient notamment. Les expressions rgulires sont
aussi couramment utilises dans le langage de programma-
tion Perl. Leur ajout au JDK reprsente un intressant
renforcement des capacits du Java.
Dans ce chapitre, vous allez apprendre utiliser les fonc-
tionnalits lies aux expressions rgulires du Java afin
de retrouver et remplacer des portions de texte ou den
dterminer la concordance au regard dun modle.
56 CHAPITRE 6 Retrouver des motifs avec des expressions rgulires
Grce ces acquis, vous pourrez dterminer les cas o
lusage dun traitement par les expressions rgulires peut
tre utile dans vos applications.
Les expressions rgulires
en Java
Les classes Java Matcher et Pattern que vous utiliserez
pour les oprations lies aux expressions rgulires sont
contenues dans le paquetage [Link]. Elles per-
mettent la fois de retrouver des squences de caractres
et den dterminer la concordance daprs des motifs
dexpression rgulire. Quelle diffrence faut-il faire entre
"retrouver" et "dterminer la concordance" ? Lopration
de recherche permet de retrouver des correspondances
dans une chane. Lopration de dtermination de la con-
cordance requiert que la chane entire soit une corres-
pondance prcise de lexpression rgulire.
Les tches pour lesquelles vous faisiez auparavant appel
la classe StringTokenizer sont en gnral toutes dsignes
pour tre simplifies laide dexpressions rgulires.
Info
Si vous ne pouvez pas utiliser une version de Java contenant
le paquetage des expressions rgulires (autrement dit, une
version 1.4 ou ultrieure), il existe une bonne solution de
remplacement avec le paquetage Jakarta RegExp dApache.
Ce livre ne couvre pas le paquetage Jakarta, mais vous trou-
verez des informations et une documentation complte le
concernant ladresse [Link]
57 Les expressions rgulires en Java
Le Tableau 6.1 prsente les caractres spciaux courants
utiliss dans les expressions rgulires. Vous pourrez vous
rfrer ce tableau en consultant les exemples du chapitre.
Tableau 6.1 : Tableau des expressions rgulires
caractres spciaux couramment utiliss
Caractre
spcifique
Description
^ Dbut de la chane
$ Fin de la chane
? 0 ou 1 fois (fait rfrence lexpression
rgulire prcdente)
* 0 ou plusieurs fois (fait rfrence
lexpression rgulire prcdente)
+ 1 ou plusieurs fois (fait rfrence
lexpression rgulire prcdente)
[] Classe de caractres
| Oprateur union
. Nimporte quel caractre
\d Un chiffre
\D Caractre autre quun chiffre
\s Caractre despace blanc (espace, tabulation,
nouvelle ligne, saut de page, retour chariot)
\S Caractre autre quespace blanc
\w Caractre de mot [a-zA-Z_0-9]
\W Caractre autre quun caractre de mot [^\w]
58 CHAPITRE 6 Retrouver des motifs avec des expressions rgulires
Dans le Tableau 6.1, les expressions rgulires chappes
sont prsentes en tant prcdes par une unique barre
oblique inverse. Notez cependant qu lintrieur des
chanes Java, il convient dutiliser deux barres obliques
inverses chaque fois. Le caractre de barre oblique
inverse possde en effet une signification spciale en
Java : la double barre oblique inverse chappe ds lors le
caractre de barre oblique inverse et quivaut un uni-
que caractre de barre oblique inverse.
La JavaDoc de la classe Pattern propose une liste plus
complte des caractres utiliss pour exprimer des expres-
sions rgulires. Elle est disponible ladresse suivante :
[Link]
regex/[Link].
Retrouver une portion de texte
laide dune expression rgulire
Cet exemple utilise les classes Pattern et Matcher. Pour
commencer, nous utilisons la mthode compile() de la
classe Pattern afin de compiler une chane de motif en un
objet Pattern. Une fois que nous avons lobjet Pattern
regPat, nous utilisons la mthode matcher() et passons la
chane de texte en fonction de laquelle la correspondance
String pattern = "[TJ]im";
Pattern regPat = [Link](pattern);
String text = "This is jim and Timothy.";
Matcher matcher = [Link](text);
if ([Link]()) {
String matchedText = [Link]();
}
59 Retrouver une portion de texte laide dune expression rgulire
doit tre tablie. La mthode matcher() retourne une ins-
tance de la classe Matcher. Pour finir, nous appelons la
mthode group() de la classe Matcher pour obtenir le texte
correspondant. Le texte correspondant dans cet exemple
est la chane "Tim". Notez que la chane "jim" nest pas
une occurrence correspondante, car par dfaut, les expres-
sions rgulires tiennent compte de la casse des caractres.
Pour oprer une recherche en ignorant la casse, ce code
doit tre lgrement modifi, comme ceci :
String patt = "[TJ]im";
Pattern regPat = [Link](patt,
Pattern.CASE_INSENSITIVE);
String text = "This is jim and Timothy.";
Matcher matcher = [Link](text);
if ([Link]()) {
String matchedText = [Link]();
}
Le texte retourn est maintenant la chane de caractres
"jim". La mise en correspondance ntant cette fois pas
sensible la casse, la premire correspondance "jim"
intervient avant la correspondance portant sur "Tim".
Notez que la seule diffrence par rapport au prcdent
exemple tient ce que nous avons ajout un paramtre
supplmentaire la mthode compile() en crant notre
objet Pattern. Cette fois-ci, nous passons le drapeau
CASE_INSENSITIVE afin dindiquer que nous souhaitons
que la correspondance soit tablie sans tenir compte de la
casse. Lorsque ce drapeau nest pas inclus, la correspon-
dance stablit par dfaut en tenant compte de la casse.
60 CHAPITRE 6 Retrouver des motifs avec des expressions rgulires
Si votre code doit sexcuter sous diffrents paramtres
rgionaux, vous pouvez galement passer le drapeau de
casse Unicode. La ligne de compilation ressemblera alors
ceci :
Pattern regPat = [Link](pattern,
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
Comme vous le voyez, les diffrents drapeaux passs la
mthode compile() sont spars les uns des autres par un
signe OU logique. Les drapeaux Pattern doivent tre
passs au moment o le Pattern est cr en utilisant la
mthode compile(). Une fois que lobjet Pattern est
cr, il est immuable, ce qui signifie quil ne peut plus
tre chang.
Dans les prcdents exemples, nous avons utilis la mthode
find() de la classe Matcher pour retrouver la premire
correspondance dans notre chane dentre. La mthode
find() peut cependant tre appele de manire rptitive
afin de retourner toutes les correspondances successives
dans la chane dentre. La mthode find() retourne true
chaque fois quune correspondance est trouve. Elle
retourne false lorsquil ny a plus de correspondance. Si
vous appelez find() de nouveau aprs quelle a retourn
false, elle se rinitialise et retrouve la premire occurrence
de nouveau. Il existe une autre mthode find() qui prend
un paramtre int spcifiant un index partir duquel la
recherche doit dmarrer. Pour le reste, cette mthode
find() se comporte exactement comme la mthode find()
sans paramtre.
Dautres solutions sont possibles pour obtenir le rsultat
de la correspondance. Nous avons utilis la mthode
group() de la classe Matcher, mais il existe aussi des
mthodes pratiques start() et end(). La mthode start()
61 Remplacer du texte mis en correspondance
retourne lindex au dbut de la prcdente correspon-
dance. La mthode end() retourne lindex aprs le dernier
caractre mis en correspondance.
Remplacer du texte
mis en correspondance
Cet exemple montre comment remplacer le texte
retrouv avec notre chane de motif par un texte de rem-
placement. La valeur de string2 la fin de cet exemple est
la suivante :
This is jim and John.
Loccurrence de "jim" nest pas remplace, car la mise en
correspondance des expressions rgulires tient par dfaut
compte de la casse. Pour tablir une correspondance en
ignorant la casse, rfrez-vous lexercice prcdent.
Nous utilisons les classes Pattern et Matcher comme nous
lavons fait lors de la mise en correspondance lmentaire
de lexercice prcdent. Ltape nouvelle concerne ici
notre appel la mthode replaceAll() de Matcher. Nous
passons en paramtre le texte utiliser comme texte de
remplacement. Celui-ci vient remplacer toutes les occur-
rences retrouves du motif. Cette technique est trs effi-
cace pour remplacer des portions dune chane par une
chane de remplacement.
String pattern = "[TJ]im";
Pattern regPat = [Link](pattern);
String text = "This is jim and Tim.";
Matcher matcher = [Link](text);
String string2 = [Link]("John");
62 CHAPITRE 6 Retrouver des motifs avec des expressions rgulires
Lautre technique utile pour le remplacement du texte
consiste utiliser les mthodes appendReplacement() et
appendTail() de la classe Matcher. Lusage combin de ces
mthodes permet de remplacer des occurrences dune
sous-chane lintrieur dune chane. Le code suivant
prsente un exemple de cette technique :
Pattern p = [Link]("My");
Matcher m = [Link]("My dad and My mom");
StringBuffer sb = new StringBuffer();
boolean found = [Link]();
while(found) {
[Link](sb, "Our");
found = [Link]();
}
[Link](sb);
[Link](sb);
La sortie de ce code produit limpression de la ligne sui-
vante avec la mthode [Link]() :
Our dad and Our mom
Dans cet exemple, nous crons un objet Pattern afin
de retrouver les occurrences du texte "My". La mthode
appendReplacement() crit les caractres de la squence
dentre ("My dad and my mom") dans le tampon
StringBuffer sb, jusquau dernier caractre avant la prc-
dente correspondance. Elle ajoute ensuite au StringBuffer
la chane de remplacement passe en second paramtre.
Pour finir, elle fixe la position de la chane courante au
niveau de la fin de la dernire correspondance. Ce pro-
cessus se rpte jusqu ce quil ny ait plus de corres-
pondance. A ce moment-l, nous appelons la mthode
appendTail() pour ajouter la portion restante de la squence
dentre au StringBuffer.
63 Retrouver toutes les occurrences dun motif
Retrouver toutes les occurrences
dun motif
Dans les prcdents exemples du chapitre, nous navons
trouv quune unique correspondance dun motif. Dans
cet exemple, nous retrouvons toutes les occurrences dun
motif de correspondance donn dans une chane. Le motif
utilis est "\\st(\\w)*o(\\w)*". Cette expression rgulire
retrouve tous les mots qui commencent par t et contien-
nent la lettre o. La sortie imprime par notre instruction
[Link]() est la suivante :
town
tom
ton
toon
Dcomposons cette expression rgulire et voyons ce que
chaque lment nous apporte :
b \\s : caractre spcial dexpression rgulire corres-
pondant un caractre despace blanc.
b t : correspond la lettre t.
b \\w* : caractre spcial dexpression rgulire corres-
pondant zro, un ou plusieurs caractres de mot (qui
ne sont pas des espaces blancs).
String pattern = "\\st(\\w)*o(\\w)*";
Pattern regPat = [Link](pattern);
String text = "The words are town tom ton toon house.";
Matcher matcher = [Link](text);
while ([Link]()) {
String matchedText = [Link]();
[Link]("match - " + matchedText);
}
64 CHAPITRE 6 Retrouver des motifs avec des expressions rgulires
b o : correspond la lettre o.
b \\w* : caractre spcial dexpression rgulire corres-
pondant zro, un ou plusieurs caractres de mot (qui
ne sont pas des espaces blancs).
Cette expression rgulire ne correspond pas au premier
mot de la chane, quand bien mme celui-ci commence-
rait par un t et contiendrait un o, car le premier lment
de lexpression rgulire correspond un caractre
despace blanc or gnralement, les chanes ne commen-
cent pas par un espace blanc.
Imprimer des lignes
contenant un motif
Cet exemple montre comment effectuer une recherche
dans un fichier afin de trouver toutes les lignes contenant
un motif donn. Ici, nous utilisons la classe BufferedRea-
der pour lire des lignes depuis un fichier texte. Nous ten-
tons de mettre en correspondance chaque ligne avec notre
motif en utilisant la mthode find() de la classe Matcher.
String pattern = "^a";
Pattern regPat = [Link](pattern);
Matcher matcher = [Link]("");
BufferedReader reader =
new BufferedReader(new FileReader("[Link]"));
String line;
while ((line = [Link]()) != null) {
[Link](line);
if ([Link]()) {
[Link](line);
}
}
65 Retrouver des caractres de nouvelle ligne dans du texte
Cette mthode retourne true si le motif est trouv dans la
ligne passe en paramtre. Nous imprimons toutes les
lignes qui correspondent au motif donn. Notez que ce
fragment de code peut lever des exceptions FileNotFoun-
dException et IOException, quil convient de grer dans
votre code. Dans cet exemple, lexpression rgulire cor-
respond nimporte quelle ligne contenue dans notre
fichier dentre qui commence par la lettre a minuscule.
Le motif dexpression rgulire que nous utilisons se
dcompose de la manire suivante :
b ^ : caractre spcial dexpression rgulire correspon-
dant au dbut dune chane.
b a : correspond la lettre a.
Retrouver des caractres
de nouvelle ligne dans du texte
Dans cet exemple, nous utilisons le drapeau [Link]-
TILINE pour retrouver des caractres de nouvelle ligne
dans une chane de texte. Par dfaut, les caractres
dexpression rgulire ^ et $ ne correspondent quau
dbut et la fin dune chane entire. Si une chane con-
String pattern = "\\d$";
String text =
"This is line 1\nHere is line 2\nThis is line 3\n";
Pattern regPat =
[Link](pattern, [Link]);
Matcher matcher = [Link](text);
while ([Link]()) {
[Link]([Link]());
}
66 CHAPITRE 6 Retrouver des motifs avec des expressions rgulires
tenait plusieurs lignes distingues par des caractres de
nouvelle ligne, lexpression rgulire ^ ne correspondrait
toujours quau dbut de la chane par dfaut. Si nous pas-
sons le drapeau [Link] la mthode Pat-
[Link]() comme nous le faisons dans cet exemple,
le caractre ^ correspond maintenant au premier caractre
suivant un terminateur de ligne et le caractre $ au carac-
tre prcdent un terminateur de ligne. Avec le drapeau
[Link], le ^ correspond maintenant au dbut
de chaque ligne dans une chane contenant plusieurs
lignes spares par des caractres de nouvelle ligne.
La sortie de cet exemple est la suivante :
1
2
3
Nous utilisons le motif "\\d$". Dans cette expression
rgulire, le \\d correspond nimporte quel chiffre uni-
que. En mode MULTILINE, le $ correspond au caractre
intervenant juste avant un terminateur de ligne. Leffet
intressant est que notre expression rgulire correspond
tout caractre chiffre unique prsent la fin dune ligne.
Nous obtenons donc la sortie prcdente.
7
Nombres
Le travail avec des nombres en Java est un domaine dans
lequel tout bon programmeur se doit dtre aguerri, car
presque tous les programmes ont affaire des nombres
sous une forme ou une autre. Dans ce chapitre, nous
utiliserons principalement les types numriques de base
du Java, leurs objets encapsuleurs (wrappers) et la classe
[Link].
Le Tableau 7.1 prsente les types prdfinis du Java et liste
leurs objets encapsuleurs disponibles. Notez que le type
boolen ne possde pas de taille en bits parce quil ne peut
contenir que deux valeurs discrtes, true ou false.
Tableau 7.1 : Types prdnis du Java
Type Taille en bits Objet encapsuleur
byte 8 Byte
short 16 Short
int 32 Integer
long 64 Long
68 CHAPITRE 7 Nombres
Les classes dobjet encapsuleur sont utiles lorsque vous
souhaitez traiter un type de base comme un objet. Cette
approche peut notamment tre utile si vous souhaitez
dfinir une API manipulant uniquement des objets. En
encapsulant vos nombres sous forme dobjets, vous pou-
vez aussi srialiser les types de base.
Vrier si une chane
est un nombre valide
Dans cet exemple, nous utilisons la mthode statique
parseInt() de la classe Integer pour tenter de convertir
le paramtre chane en un entier. Si le paramtre chane
ne peut pas tre converti en un entier valide, lexception
float 32 Float
double 64 Double
char 16 Character
boolean -- Boolean
Tableau 7.1 : Types prdnis du Java (suite)
Type Taille en bits Objet encapsuleur
try {
int result = [Link](aString);
}
catch (NumberFormatException ex) {
[Link]("The string does not contain a valid
number.");
}
69 Comparer des nombres virgule flottante
NumberFormatException est leve. Si lexception Number-
FormatException nest pas leve, on peut donc en conclure
a contrario que la mthode parseInt() est parvenue par-
ser la chane en une valeur dentier.
Il est aussi possible de dclarer la variable int en dehors du
bloc try afin de pouvoir attribuer une valeur par dfaut
la variable dans le bloc catch si lexception NumberFormat-
Exception est leve. Le code devient alors le suivant :
int result = 0;
try {
result = [Link](aString);
}
catch (NumberFormatException ex) {
result = DEFAULT_VALUE;
}
Comparer des nombres
virgule ottante
Une prudence toute particulire est recommande lors de
la comparaison des nombres virgule flottante en raison
des erreurs darrondi. Au lieu de comparer les types Java
de base virgule flottante float et double avec loprateur
==, il est prfrable de comparer leurs quivalents objet. La
mthode equals() de Float et Double retourne true si et
Float a = new Float(3.0f);
Float b = new Float(3.0f);
if ([Link](b)) {
// Ils sont gaux
}
70 CHAPITRE 7 Nombres
seulement si les deux valeurs sont exactement identiques
au bit prs ou si elles correspondent toutes deux la valeur
NaN. Cette valeur dsigne une valeur autre quun nombre
(NaN pour not a number) qui nest pas un nombre valide.
En pratique, lors de la comparaison des nombres virgule
flottante, il nest pas toujours souhaitable deffectuer une
comparaison exacte. Il est parfois plus judicieux de la fixer
une plage diffrentielle acceptable, aussi appele tol-
rance. Les classes et les types Java ne possdent malheureu-
sement pas de fonctionnalit prdfinie de ce type, mais
vous pouvez assez aisment crer votre propre mthode
equals() pour cela. Voici un fragment de code qui peut
tre utilis pour crer une mthode de ce type :
float f1 = 2.99f;
float f2 = 3.00f;
float tolerance = 0.05f;
if (f1 == f2) [Link]("they are equal");
else {
if ([Link](f1-f2) < tolerance) {
[Link]("within tolerance");
}
}
Nous comparons dabord les nombres virgule flottante
en utilisant loprateur ==. Sils sont gaux, nous impri-
mons un message correspondant. Sils ne le sont pas, nous
vrifions si la valeur absolue de leur diffrence est inf-
rieure la valeur de tolrance dsire. Cette technique
permet de crer une mthode utile prenant en paramtre
deux valeurs virgule flottante et une tolrance, et
retournant un rsultat indiquant si les valeurs sont gales,
la plage de tolrance prs.
71 Arrondir des nombres virgule flottante
Arrondir des nombres
virgule ottante
Il convient dtre prudent si vous souhaitez convertir un
nombre virgule flottante en un entier. Si vous vous
contentez de transtyper le nombre virgule flottante en
un int ou un long, la conversion en un int ou un long
sopre en tronquant simplement la portion dcimale.
Avec une valeur dcimale comme 20.99999, vous obtien-
drez donc 20 aprs le transtypage en une valeur int ou
long. La mthode approprie pour raliser une conver-
sion de nombre virgule flottante en entier consiste
utiliser la mthode [Link](). Lexemple prcdent
montre comment arrondir une valeur double et une
valeur float. Si vous passez une valeur double la
mthode [Link](), le rsultat retourn est un long.
Si vous passez une valeur float la mthode Math
.round(), le rsultat retourn est un int. La mthode
[Link]() arrondit la valeur vers le haut si la partie
dcimale du nombre virgule flottante est 0,5 ou plus et
vers le bas pour les nombres dont la partie dcimale est
infrieure 0,5.
// Arrondir une valeur double
long longResult = [Link](doubleValue);
// Arrondir une valeur float
int intResult = [Link](floatValue);
72 CHAPITRE 7 Nombres
Formater des nombres
Dans la plupart des applications, il est ncessaire dafficher
des nombres. Le Java permet par chance le formatage des
nombres, afin de leur donner lapparence dsire lorsque
vous souhaitez les afficher dans votre application.
Cet exemple gnre le nombre format suivant en sortie :
1 623 542,765
Dans cet exemple, nous utilisons la classe NumberFormat
pour formater une valeur double en une reprsentation
sous forme de chane spare par des espaces. La classe
NumberFormat se trouve dans le paquetage [Link]. Elle
est aussi trs utile pour le code que vous devez diffuser
dans plusieurs pays. La classe NumberFormat supporte le
formatage de nombres et de devises et sait galement
reprsenter des nombres et des devises laide de diff-
rents paramtres rgionaux.
La classe NumberFormat peut aussi tre utilise pour forma-
ter des valeurs de pourcentage afficher. Voici un exem-
ple utilisant la classe NumberFormat pour formater un
pourcentage afficher :
double percent = 0.80;
NumberFormat percentFormatter;
String formattedPercent;
percentFormatter = [Link]();
double value = 1623542.765;
NumberFormat numberFormatter;
String formattedValue;
numberFormatter = [Link]();
formattedValue = [Link](value);
[Link]("%s%n", formattedValue);
73 Formater des nombres
formattedPercent = [Link](percent);
[Link]("%s%n", formattedPercent);
La sortie de ce code est la suivante :
80%
La classe NumberFormat possde galement une mthode
parse() qui peut tre utilise pour parser des chanes con-
tenant des nombres en un objet Number, partir duquel
peut sobtenir un type numrique.
Le JDK 1.5 a introduit la classe [Link], un
objet de formatage de porte gnrale permettant de for-
mater un grand nombre de types. En plus des nombres,
cette classe peut galement formater des dates et des heu-
res. Elle est trs bien documente dans la documentation
du JDK 1.5 ladresse suivante : [Link]
j2se/1.5.0/docs/api/java/util/[Link].
Le JDK 1.5 ajoute aussi deux mthodes utilitaires la
classe [Link] pour un formatage ais des
objets OutputStream : format() et printf(). Toutes deux
prennent une chane de format et un nombre variable
darguments Object en entre. Ces mthodes sont trs
proches des mthodes de formatage des chanes classiques
printf et scanf du C. Pour plus dinformations sur ces
mthodes, rfrez-vous la documentation du JDK 1.5
ladresse [Link]
java/io/[Link].
Dans lexemple suivant, nous allons voir comment for-
mater des valeurs de devise afficher avec la classe
NumberFormat.
74 CHAPITRE 7 Nombres
Formater des devises
Comme pour lexemple prcdent concernant le forma-
tage des nombres, nous utilisons ici la classe NumberFormat,
mais afin de formater cette fois une valeur de devise. Nous
utilisons la mthode getCurrencyInstance() de la classe
NumberFormat pour obtenir une instance de formatage de
devise de la classe. Avec cette instance, nous pouvons pas-
ser une valeur virgule flottante et rcuprer en retour
une valeur de devise formate. La sortie de cet exemple
produit la chane suivante :
567 123 678,99
En plus de placer des virgules aux emplacements appro-
pris, le formateur de devises ajoute automatiquement le
signe dollar aprs la chane (ou avant, selon les paramtres
rgionaux).
Convertir un entier en nombre
binaire, octal et hexadcimal
double currency = 567123678.99;
NumberFormat currencyFormatter;
String formattedCurrency;
currencyFormatter = [Link]();
formattedCurrency = [Link](currency);
[Link]("%s%n", formattedCurrency);
int intValue = 24;
String binaryStr = [Link](intValue);
String octalStr = [Link](intValue);
String hexStr = [Link](intValue);
75 Gnrer des nombres alatoires
La classe Integer permet aisment de convertir une valeur
dentier en un nombre binaire, octal ou hexadcimal.
Les mthodes statiques concernes de la classe Integer
sont les mthodes toBinaryString(), toOctalString() et
toHexString(). Dans cet exemple, nous les utilisons cha-
cune en passant dans chaque cas une valeur dentier et
en obtenant en retour un objet String contenant respec-
tivement lentier au format binaire, octal et hexadcimal.
Gnrer des nombres alatoires
La classe Random du paquetage [Link] peut tre utilise
pour gnrer des nombres alatoires. Par dfaut, elle uti-
lise lheure courante du jour comme valeur de graine
pour son gnrateur de nombres alatoires. Vous pouvez
aussi dfinir vous-mme une valeur de graine en la passant
comme paramtre au constructeur de Random. La mthode
nextInt() produit un nombre alatoire entier 32 bits.
Lautre moyen de gnrer des nombres alatoires consiste
utiliser la mthode random() de la classe Math dans le
paquetage [Link].
double value = [Link]();
Cette mthode retourne une valeur double avec un
signe positif, suprieure ou gale 0,0 et infrieure 1,0.
Pour gnrer une valeur comprise dans un intervalle
spcifique, vous pouvez ajouter la limite infrieure au
rsultat de [Link]() et multiplier par lintervalle.
Random rn = new Random();
int value = [Link]();
double dvalue = [Link]();
76 CHAPITRE 7 Nombres
Le code suivant produit ainsi un nombre alatoire com-
pris entre 5 et 20 :
double value = (5+[Link]())*15;
La classe Random et la mthode random() de la classe Math
fournissent en fait un nombre pseudo-alatoire et non un
vritable nombre alatoire, car ce nombre est gnr en
utilisant une formule mathmatique et une valeur de graine
dentre. Si lon connat la valeur de graine et le mca-
nisme interne de la classe Random, il est possible de prdire
la valeur obtenue. Ces classes ne constituent donc gnra-
lement pas une bonne solution pour les gnrateurs de
nombres alatoires utiliser dans les applications forte-
ment scurises. Dans la plupart des cas cependant, il sagit
de gnrateurs de nombres alatoires parfaitement accep-
tables.
Calculer des fonctions
trigonomtriques
La classe Math du paquetage [Link] contient des
mthodes permettant de calculer aisment toutes les fonc-
tions trigonomtriques. Cet exemple montre comment il
est possible de rcuprer le cosinus, le sinus et la tangente
dun angle donn. La classe Math possde galement des
// Calcul du cosinus
double cosine = [Link](45);
// Calcul du sinus
double sine = [Link](45);
// Calcul de la tangente
double tangent = [Link](45);
77 Calculer un logarithme
mthodes pour calculer larc cosinus, larc sinus et larc
tangente ainsi que le sinus, le cosinus et la tangente hyper-
boliques. Chacune de ces mthodes prend un unique
paramtre de type double en entre et retourne un rsultat
de type double.
Calculer un logarithme
Cet exemple utilise la mthode log() de la classe
[Link] pour calculer le logarithme du paramtre
pass. Nous passons une valeur de type double et la valeur
de retour est galement un double. La mthode log() cal-
cule le logarithme naturel de base e, o e correspond la
valeur standard de 2,71828.
Le JDK 1.5 a ajout une nouvelle mthode la classe Math
afin de calculer directement un algorithme de base 10 :
log10(). Cette mthode, analogue log(), prend en
entre un paramtre double et retourne un double. Elle
peut aisment tre utilise pour calculer un logarithme de
base 10, comme ceci :
double logBase10 = Math.log10(200);
double logValue = [Link](125.5);
8
Entre et sortie
Dans la plupart des cas, lentre et la sortie constituent le
but ultime des applications. Les programmes seraient par-
faitement inutiles sils ne pouvaient produire en sortie des
rsultats ni rcuprer en entre des donnes traiter four-
nies par lutilisateur ou lordinateur. Dans ce chapitre,
nous prsenterons quelques exemples de base pour les
oprations dentre et de sortie.
Les paquetages [Link] et [Link] abritent la plupart
des classes utilises dans ce chapitre pour les tches
dentre et de sortie. Nous verrons comment lire et crire
des fichiers, travailler avec des archives ZIP, formater la
sortie et travailler avec les flux de systme dexploitation
standard.
A mesure que vous lisez les exemples de ce chapitre, gar-
dez lesprit que bon nombre des exercices peuvent lever
des exceptions dans nimporte quel programme rel, telle
lexception [Link]. Dans les exemples,
nous ninclurons pas le code de gestion des exceptions.
Dans une application relle, il est cependant impratif
quil soit prsent.
80 CHAPITRE 8 Entre et sortie
Lire du texte partir
dune entre standard
Dans un programme de console, il est courant de lire
lentre standard qui provient le plus souvent de la ligne
de commande. Cet exemple montre comment lire
lentre dans une variable String Java. Le Java contient
trois flux connects aux flux du systme dexploitation. Il
sagit des flux standard dentre, de sortie et derreur. Ils
sont respectivement dfinis en Java par [Link], Sys-
[Link] et [Link]. Ils peuvent tre utiliss pour lire
ou crire vers et depuis lentre et la sortie standard du
systme dexploitation.
Dans cet exemple, nous crons un BufferedReader afin de
lire le flux [Link]. Nous lisons avec ce lecteur les lignes
de lentre standard en poursuivant jusqu ce que lutili-
sateur tape le mot "quit".
Ecrire vers une sortie standard
[Link] est un PrintStream qui crit sa sortie vers la
sortie standard (en gnral, la console). [Link] est lun
des trois flux dfini par le Java pour se connecter aux flux
BufferedReader inStream =
new BufferedReader (new InputStreamReader([Link]));
String inLine = "";
while ( !([Link]("quit"))) {
[Link]("prompt> ");
inLine = [Link]();
}
[Link]("Hello, World!");
81 Formater la sortie
de systme dexploitation standard. Les autres flux sont
[Link] et [Link], permettant de lire lentre stan-
dard et dcrire dans le flux derreur standard.
Le flux [Link] est probablement le flux de systme
dexploitation standard le plus frquemment utilis. Il est
mis contribution par la quasi-totalit des programmeurs
pour le dbogage de leurs applications. Ce flux crit dans
la console : il sagit ainsi dun outil pratique pour voir ce
qui se passe un point particulier de lapplication.
En gnral, les instructions [Link] ne doivent cepen-
dant pas tre conserves dans les programmes aprs le
dbogage initial, car elles peuvent en affecter les perfor-
mances. A long terme, il est prfrable de rcolter les
informations de dbogage dans votre application laide
dun dispositif de journalisation comme celui que propo-
sent [Link] ou le paquetage populaire Log4J
dApache.
Formater la sortie
Cet exemple utilise la mthode format() pour formater
une chane de sortie qui imprime une moyenne la batte
en baseball sous sa forme classique trois chiffres aprs la
virgule. La moyenne est dfinie en divisant le nombre de
coups russis par le nombre de "prsences la batte"
(at-bats). Le spcificateur de format %.3f demande au for-
mateur dimprimer la moyenne sous forme de nombre
virgule flottante avec trois chiffres aprs la virgule.
float hits=3;
float ab=10;
String formattedTxt =
[Link]("Batting average: %.3f", hits/ab);
82 CHAPITRE 8 Entre et sortie
Le JDK 1.5 a introduit la classe [Link] qui
peut tre utilise pour simplifier le formatage du texte. La
classe Formatter opre la manire de la fonction printf
du langage C et offre une prise en charge de la justifica-
tion et de lalignement pour la mise en page, des formats
courants pour les donnes numriques, les chanes et les
dates et heures, ainsi quune sortie spcifique en fonction
des paramtres rgionaux.
Voici un exemple dutilisation directe de la classe Formatter :
StringBuffer buffer = new StringBuffer();
Formatter formatter = new Formatter(buffer, [Link]);
[Link]("Value of PI: %6.4f", [Link]);
[Link]([Link]());
Ce code produit la sortie suivante :
Value of PI: 3,1416
Dans cet exemple, nous crons une instance Formatter et
lutilisons pour formater la valeur mathmatique standard
du nombre pi. Celle-ci contient un nombre infini de chif-
fres aprs la virgule, mais il est gnralement prfrable
den restreindre le nombre au moment de limprimer.
Dans cet exemple, nous avons utilis le spcificateur de
format %6.4f. La valeur 6 indique que la sortie pour ce
nombre ne doit pas dpasser 6 caractres de longueur en
comptant la virgule. La valeur 4 indique que la prcision
de la valeur dcimale doit tre de 4 chiffres aprs la
virgule. La valeur imprime atteint donc 6 caractres de
longueur et possde 4 chiffres aprs la virgule : 3,1416.
En plus dutiliser directement la classe Formatter, vous
pouvez utiliser les mthodes format() et printf() des flux
[Link] et [Link]. Voici par exemple comment
83 Formater la sortie
imprimer lheure locale en utilisant la mthode format()
du flux [Link] :
[Link]("Local time: %tT",
[Link]());
Cette mthode imprime lheure locale, comme ceci :
Local time: 16:25:14
La classe String contient galement une mthode statique
format() qui peut tre utilise pour formater directement
des chanes. Nous pouvons par exemple utiliser cette
mthode statique pour formater aisment une chane de
date comme ceci :
Calendar c = new GregorianCalendar(1999,
[Link], 6);
String s = [Link]("Timmys Birthday: %1$tB %1$te,
%1$tY", c);
Ce code cre la valeur String formate suivante :
Timmys Birthday: Janvier 6, 1999
Toutes les mthodes qui produisent une sortie formate
dont nous avons trait prennent une chane de format et
une liste darguments en paramtres. La chane de format
est un objet String qui peut contenir du texte et un ou
plusieurs spcificateurs de format.
Pour notre exemple de formatage prcdent, la chane de
format serait "Timmy's Birthday: %1$tm %1$te,%1$tY", les
lments %1$tm, %1$te et $1$tY tant les spcificateurs
de format.
Le reste de la chane correspond du texte statique. Ces
spcificateurs de format indiquent comment les argu-
ments doivent tre traits et lendroit de la chane o ils
doivent tre placs.
84 CHAPITRE 8 Entre et sortie
Pour faire rfrence notre exemple de nouveau, la liste
darguments correspond simplement lobjet Calendar c.
Dans cet exemple, nous navons quun seul argument,
mais la liste peut en contenir plusieurs. Tous les param-
tres passs aux mthodes de formatage aprs la chane de
format sont considrs comme des arguments.
Les spcificateurs de format possdent le format suivant :
%[index_argument$][drapeaux][largeur][.prcision]
conversion
index_argument fait rfrence un argument dans la liste
des arguments passe la mthode de formatage. La liste
est indexe en commenant 1. Pour faire rfrence au
premier argument, vous devez donc utiliser 1$.
Llment drapeaux dsigne un ensemble de caractres qui
modifient le format de sortie. Lensemble de drapeaux
valides dpend du type de conversion.
Llment largeur est un entier dcimal positif indiquant
le nombre minimal de caractres crire dans la sortie.
Llment prcision est un entier dcimal positif norma-
lement utilis pour restreindre le nombre de caractres. Le
comportement spcifique dpend du type de conversion.
Llment conversion est un caractre indiquant comment
largument doit tre format. Lensemble des conversions
valides pour un argument donn dpend du type de don-
nes de largument.
Tous les lments spcificateurs sont facultatifs lexcep-
tion du caractre de conversion.
Le Tableau 8.1 prsente une liste des caractres de conver-
sion valides. Pour plus dinformations sur les conversions
de date et dheure, rfrez-vous au JavaDoc de la classe
Formatter ladresse suivante : [Link]
j2se/1.5.0/docs/api/.
85 Formater la sortie
Tableau 8.1 : Codes de format de Formatter
Code Description
b Si largument arg est null, le rsultat est false.
Si arg est un boolean ou un Boolean, le rsultat
est la chane retourne par [Link]().
Sans cela, le rsultat est true.
h Si largument arg est null, le rsultat est "null".
Sans cela, le rsultat est obtenu en invoquant
[Link]([Link]()).
s Si largument arg est null, le rsultat est "null".
Si arg implmente Formattable, [Link]
est invoque. Sans cela, le rsultat est obtenu
en invoquant [Link]().
c Le rsultat est un caractre Unicode.
d Le rsultat est format sous forme dentier dcimal.
o Le rsultat est format sous forme dentier octal.
x Le rsultat est format sous forme dentier
hexadcimal.
f Le rsultat est format comme un nombre dcimal.
e Le rsultat est format sous forme de nombre
dcimal en notation scientifique informatise.
g Le rsultat est format en utilisant une notation
scientifique informatise ou le format dcimal,
selon la prcision et la valeur aprs larrondi.
a Le rsultat est format sous forme de nombre
hexadcimal virgule flottante avec une mantisse
et un exposant.
t Prfixe pour les caractres de conversion
de date et dheure.
n Le rsultat est le sparateur de ligne spcifique
la plate-forme.
% Le rsultat est un % littral.
86 CHAPITRE 8 Entre et sortie
Pour obtenir une liste complte des codes de format
disponibles, rfrez-vous la documentation JavaDoc de
la classe Formatter qui peut tre consulte ladresse
[Link]
[Link].
Ouvrir un chier par son nom
Cet exemple montre comment crer un BufferedReader
pour lire lentre dun fichier spcifi par un nom de
fichier (ici, [Link]) et comment crer un BufferedWri-
ter pour crire du texte vers un fichier de sortie spcifi
par son nom ([Link]).
Il est trs facile douvrir un fichier dsign par son nom en
Java. La plupart des classes de flux dentre et de sortie ou
de lecteur possdent une option permettant de spcifier le
fichier par nom dans le flux ou le constructeur du lecteur.
// Ouvrir un fichier en lecture
BufferedReader is =
new BufferedReader(new FileReader("[Link]"));
// Ouvrir un fichier en criture
BufferedWriter out =
new BufferedWriter(new FileWriter("[Link]"));
87 Lire un fichier dans un tableau doctets
Lire un chier dans
un tableau doctets
Cet exemple lit le fichier spcifi par fileName dans le
tableau doctets bytes. Notez que la mthode [Link]()
retourne la longueur du fichier en octets sous forme de
valeur long, mais nous devons utiliser une valeur int pour
initialiser le tableau doctets. Nous transtypons donc
dabord la valeur long en une valeur int. Dans un vrita-
ble programme, il conviendrait pralablement de sassurer
que la valeur de longueur tient effectivement dans un type
int avant de la transtyper laveuglette. Avec la mthode
read() du InputStream, nous continuons lire les octets
du fichier jusqu ce que le tableau doctets soit rempli ou
quil ny ait plus doctets lire dans le fichier.
File file = new File(fileName);
InputStream is = new FileInputStream(file);
long length = [Link]();
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while ((offset < [Link])
&& ((numRead=[Link](bytes, offset,
[Link]-offset))>= 0)) {
offset += numRead;
}
[Link]();
88 CHAPITRE 8 Entre et sortie
Lire des donnes binaires
La mthode read() permet de lire des donnes binaires
depuis un fichier dans un tableau doctets. Dans cet exem-
ple, nous lisons le flux dentre is dans le tableau doctets
bytes. Le tableau bytes est ici suppos avoir t prc-
demment initialis sous forme de tableau doctets et la
variable fileName correspondre au nom dun fichier
valide. La variable offset pointe lemplacement du
tableau doctets partir duquel lcriture des donnes doit
tre commence. Elle est utile lorsque vous vous trouvez
dans une boucle, que vous lisez les donnes dun fichier
et que vous ne souhaitez pas craser les donnes pr-
cdemment stockes dans le tableau doctets. A chaque
passage dans la boucle, vous pouvez mettre jour ce
dcalage, comme nous lavons vu dans lexemple prc-
dent, "Lire un fichier dans un tableau doctets". Voici la
portion de code concerne :
while ( (offset < [Link])
&& ( (numRead=[Link](bytes, offset,
[Link]-offset)) >= 0) ) {
offset += numRead;
}
Dans cet exemple de code, nous crivons des donnes
depuis le flux dente is dans le tableau bytes. Nous
poursuivons la lecture depuis le fichier jusqu ce que
nous ayons rempli le tableau bytes ou quil ny ait plus de
donnes lire dans le fichier.
InputStream is = new FileInputStream(fileName);
int offset = 0;
int bytesRead = [Link](bytes, offset, [Link]-offset);
89 Atteindre une position dans un fichier
Atteindre une position
dans un chier
La mthode seek() de la classe RandomAccessFile permet
datteindre nimporte quelle position dsire dans un
fichier. Dans cet exemple, nous crons dabord un objet
File, qui est ensuite utilis pour crer une instance Rando-
mAccessFile. Avec linstance RandomAccessFile (raf),
nous recherchons la fin du fichier en passant la valeur
[Link]() en paramtre la mthode seek().
Aprs avoir utilis la mthode seek() pour trouver la
position dsire dans le fichier, nous pouvons ensuite uti-
liser les mthodes read() ou write() de la classe RandomAc-
cessFile pour lire ou crire des donnes partir de cette
position exacte.
Lire une archive JAR ou ZIP
File file = new File("[Link]");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
[Link]([Link]());
// Lire un fichier ZIP
ZipFile file = new ZipFile(filename);
Enumeration entries = [Link]();
while ([Link]()) {
ZipEntry entry = (ZipEntry)[Link]();
if ([Link]()) {
// Traiter le rpertoire
}
else {
// Traiter le fichier
}
}
[Link]();
90 CHAPITRE 8 Entre et sortie
Le Java offre un support intgr pour la lecture et lcri-
ture de fichiers darchive ZIP. Les fichiers ZAR ntant
autres que des fichiers ZIP possdant un contenu prcis,
les classes et les mthodes des fichiers ZIP peuvent ga-
lement tre utilises pour les lire. Les classes ZIP sont
contenues dans le paquetage [Link] qui fait partie
du JDK standard.
Dans cet exemple, nous crons dabord un objet ZipFile
en passant le nom de fichier dun fichier ZIP existant au
constructeur de la classe ZipFile. Nous obtenons ensuite
lensemble des entres du fichier ZIP dans un type dnu-
mration en appelant la mthode entries() de lobjet
ZipFile. Une fois en possession des entres de fichier ZIP
sous forme dnumration, nous pouvons parcourir au
pas pas les entres et instancier un objet ZipEntry pour
chaque entre. Avec lobjet ZipEntry, nous pouvons
dterminer si lentre particulire qui est traite est un
rpertoire ou un fichier et la traiter en fonction.
Crer une archive ZIP
// Ecrire un fichier ZIP
ZipOutputStream out =
new ZipOutputStream(new FileoutputStream(zipFileName));
FileInputStream in = new FileInputStream(fileToZip1);
[Link](new ZipEntry(fileToZip1));
int len;
byte[] buf = new byte[1024];
while ((len = [Link](buf)) > 0) {
[Link](buf,0,len);
}
[Link]();
[Link]();
[Link]();
91 Crer une archive ZIP
Dans lexemple prcdent, nous avons vu comment lire
dans un fichier ZIP. Cette fois, nous crons un fichier
ZIP. Pour cela, nous commenons par construire un
ZipOutputStream en passant son constructeur un objet
FileOutputStream pointant vers le fichier que nous sou-
haitons compresser sous forme de fichier ZIP. Ensuite,
nous crons un FileInputStream pour le fichier que nous
souhaitons ajouter notre archive ZIP. Nous utilisons la
mthode putNextEntry() du ZipOutputStream pour ajou-
ter le fichier larchive.
La mthode putNextEntry() prend un objet ZipEntry en
entre : nous devons donc construire le ZipEntry partir
du nom du fichier que nous ajoutons notre archive.
Dans une boucle while, nous lisons ensuite notre fichier
en utilisant le FileInputStream et lcrivons dans le
ZipOutputStream. Une fois cela fait, nous fermons lentre
en utilisant la mthode closeEntry() du ZipOutputStream,
puis fermons chacun de nos flux ouverts.
Dans cet exemple, nous navons ajout quun seul fichier
notre archive ZIP, mais ce code peut aisment tre
tendu afin dajouter autant de fichiers que ncessaire
larchive. La classe ZipOutputStream accepte aussi bien les
entres compresses que les entres non compresses.
9
Travailler avec
des rpertoires
et des chiers
Lune des tches courantes dans la plupart des applications
Java consiste travailler avec le systme de fichiers et
notamment ses rpertoires et ses fichiers. Ce chapitre pr-
sente un certain nombre dexemples destins vous aider
travailler avec des fichiers et des rpertoires en Java.
La principale classe que nous utiliserons pour ces exem-
ples est la classe [Link]. Elle permet de lister, crer,
renommer et supprimer des fichiers, mais encore de tra-
vailler avec des rpertoires.
Bon nombre des exemples de ce chapitre peuvent lever
une exception SecurityException. En Java, le systme de
fichiers est protg par le gestionnaire de scurit. Pour
certaines applications, il peut falloir en utiliser une impl-
mentation personnalise. Parmi les applications Java, les
applets sont les plus restreintes en ce qui concerne laccs
94 CHAPITRE 9 Travailler avec des rpertoires et des fichiers
aux fichiers et aux rpertoires sur lordinateur local de
lutilisateur. En tirant parti du gestionnaire de scurit et
du framework de stratgie de scurit li vous pouvez
contrler prcisment laccs aux fichiers et aux rpertoi-
res. Pour plus dinformations sur les options de scurit
disponibles en Java, consultez la documentation de scu-
rit disponible (en anglais) sur le site Web Java officiel
ladresse [Link]
[Link].
Pour plus dinformations sur le gestionnaire de scurit,
consultez le didacticiel suivant (en anglais) propos par Sun :
[Link]
system/[Link].
Crer un chier
Cet exemple utilise la mthode createNewFile() pour
crer un nouveau fichier portant le nom spcifi en para-
mtre (ici, [Link]) en construisant lobjet File. La
mthode createNewFile() retourne la valeur boolenne
true si le fichier a bien t cr et false si le nom de
fichier spcifi existe dj.
La classe File propose une autre mthode statique pour
crer un fichier temporaire : createTempFile(). Lexem-
ple suivant montre comment lutiliser pour crer un
fichier temporaire :
File tmp = [Link]("temp", "txt", "/temp");
File f = new File("[Link]");
boolean result = [Link]();
95 Renommer un fichier ou un rpertoire
Les paramtres que nous passons la mthode createTemp-
File() sont le prfixe du fichier temporaire, son suffixe et
son rpertoire. Il existe aussi une autre version de cette
mthode qui ne prend que deux paramtres et utilise le
rpertoire temporaire par dfaut. Le fichier spcifi doit
dj exister pour que lune ou lautre forme des mthodes
createTempFile() puisse fonctionner.
Si vous utilisez des fichiers temporaires, la mthode delete-
OnExit() de la classe File peut aussi vous intresser. Elle
doit tre appele sur un objet File qui reprsente un
fichier temporaire. Lappel de la mthode deleteOnExit()
requiert que le fichier soit automatiquement supprim
lorsque la machine virtuelle Java se ferme.
Renommer un chier
ou un rpertoire
Dans cet exemple, nous renommons le fichier [Link]
en lappelant [Link]. Pour cela, nous devons crer
deux objets File. Le premier est construit avec le nom
courant du fichier. Ensuite, nous crons un nouvel objet
File en utilisant le nom de remplacement que nous sou-
haitons donner au fichier. Nous appelons la mthode
renameTo() de lobjet File dorigine et lui passons lobjet
File spcifiant le nouveau nom de fichier. La mthode
renameTo() retourne la valeur boolenne true si lopra-
tion de modification du nom russit et false sinon, quelle
que soit la raison.
File f = new File("[Link]");
File newFile = new File("[Link]");
boolean result = [Link](newFile);
96 CHAPITRE 9 Travailler avec des rpertoires et des fichiers
Cette technique peut galement tre utilise pour renom-
mer un rpertoire. Le code est alors exactement le mme,
la diffrence que nous passons cette fois les noms de
rpertoire aux constructeurs de lobjet File au lieu des
noms de fichier. Voici comment procder :
File f = new File("directoryA");
File newDirectory = new File("newDirectory");
boolean result = [Link](newDirectory);
Rappelez-vous que le nouveau nom de fichier ou de
rpertoire doit tre spcifi dans un objet File pass la
mthode renameTo(). Lune des erreurs courantes consiste
tenter de passer un objet String contenant le nouveau
nom de fichier ou de rpertoire la mthode renameTo().
Une erreur de compilation est gnre si un objet String
est pass la mthode renameTo().
Supprimer un chier
ou un rpertoire
La classe File permet aisment de supprimer un fichier.
Dans cet exemple, nous crons dabord un objet File en
spcifiant le nom du fichier supprimer. Ensuite, nous
appelons la mthode delete() de lobjet File. Elle
retourne la valeur boolenne true si le fichier a bien t
supprim et false sinon.
La mthode delete() peut aussi tre utilise pour suppri-
mer un rpertoire. Dans ce cas, vous devez crer lobjet
File f = new File("[Link]");
boolean result = [Link]();
97 Modifier des attributs de fichier
File en spcifiant le nom du rpertoire au lieu dun nom
de fichier, comme ceci :
File directory = new File("files/images");
[Link]();
Le rpertoire nest supprim que sil est vide. Sil ne lest
pas, la mthode delete() retourne la valeur boolenne
false. Si le fichier ou le rpertoire que vous essayez de
supprimer nexiste pas, delete() retourne aussi false, sans
lever dexception.
La classe File propose une autre mthode utile lie la
suppression des fichiers et des rpertoires : deleteOnExit().
Lorsquelle est appele, le fichier ou le rpertoire repr-
sent par lobjet File sont automatiquement supprims
lorsque la machine virtuelle Java se ferme.
Modier des attributs de chier
Lobjet File permet aisment de modifier lhorodatage de
dernire modification et ltat de lecture/criture dun
fichier. Pour raliser ces tches, vous devez utiliser les
mthodes setReadOnly() et setLastModified() de la classe
File. La mthode setReadOnly() positionne en lecture
seule le fichier sur lequel elle est appele. La mthode set-
LastModified() prend un unique paramtre en entre
spcifiant une date en millisecondes et positionne lhoro-
datage de dernire modification du fichier cette date.
File f = new File("[Link]");
boolean result = [Link]();
long time = (new Date()).getTime();
result = [Link](time);
98 CHAPITRE 9 Travailler avec des rpertoires et des fichiers
La valeur temporelle passe est mesure en millisecon-
des coules depuis lpoque UNIX (1
er
janvier 1970,
00 h 00 m 00 s, GMT). Ces deux mthodes retournent la
valeur boolenne true uniquement si lopration russit.
Si lopration choue, elles retournent false.
Obtenir la taille dun chier
Dans cet exemple, nous retrouvons la taille dun fichier
en utilisant la mthode length() de lobjet File. Cette
mthode retourne la taille du fichier en octets. Si le fichier
nexiste pas, elle retourne 0.
Cette mthode est souvent utile avant de lire un fichier
sous forme de tableau doctets. Grce la mthode
length(), vous pouvez dterminer la longueur du fichier
afin de connatre la taille requise pour que le tableau
doctets contienne la totalit du fichier. Le code suivant
est ainsi souvent utilis pour lire un fichier dans un tableau
doctets :
File myFile = new File("[Link]");
InputStream is = new FileInputStream(myFile);
// Obtenir la taille du fichier
long length = [Link]();
if (length > Integer.MAX_VALUE) {
// Le fichier est trop grand
}
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
File file = new File("infilename");
long length = [Link]();
99 Dterminer si un fichier ou un rpertoire existe
while (offset < [Link]
&& (numRead=[Link](bytes, offset,
[Link])) >= 0) {
offset += numRead;
}
[Link]();
Dterminer si un chier
ou un rpertoire existe
Cet exemple utilise la mthode exists() de lobjet File
pour dterminer si le fichier ou le rpertoire reprsent
par cet objet existe. Elle retourne true si le fichier ou le
rpertoire existe et false sinon.
Dplacer un chier
ou un rpertoire
boolean exists = (new File("filename")).exists();
if (exists) {
// Le fichier ou le rpertoire existe
}
else {
// Le fichier ou le rpertoire nexiste pas
}
File file = new File( "filename ");
File dir = new File( "directoryname ");
boolean success =
[Link](new File(dir, [Link]()));
if (!success) {
// Le fichier na pas pu tre dplac
}
100 CHAPITRE 9 Travailler avec des rpertoires et des fichiers
La mthode renameTo() de la classe File permet de
dplacer un fichier ou un rpertoire dans un autre rper-
toire. Dans cet exemple, nous crons un objet File afin de
reprsenter le fichier ou le rpertoire dplacer. Nous
crons un autre objet File reprsentant le rpertoire de
destination dans lequel nous souhaitons dplacer le fichier
ou le rpertoire, puis appelons la mthode renameTo() du
fichier dplac en lui passant un unique paramtre dobjet
File. Lobjet File pass en paramtre est construit en uti-
lisant le rpertoire de destination et le nom de fichier
dorigine. Si lopration de dplacement russit, la
mthode renameTo() retourne la valeur boolenne true.
En cas dchec, elle retourne false.
Lorsque vous utilisez la mthode renameTo(), gardez
lesprit que bien des aspects de ce comportement
dpendent de la plate-forme dexcution. Certains sont
signals dans le JavaDoc pour cette mthode, et notam-
ment les suivants :
b Lopration renameTo peut ne pas tre capable de
dplacer un fichier dun systme de fichiers un autre.
b Lopration renameTo peut ne pas tre atomique.
Autrement dit, limplmentation de lopration rena-
meTo peut se dcomposer en plusieurs tapes au niveau
du systme dexploitation : cette particularit peut
poser problme en cas dincident, comme lors dune
coupure de courant survenant entre les tapes.
b Lopration renameTo peut chouer si un fichier poss-
dant le nom du chemin abstrait de destination existe
dj.
Lorsque vous utilisez cette mthode, vrifiez toujours la
valeur de retour afin de vous assurer que lopration a
russi.
101 Obtenir un chemin de nom de fichier absolu partir dun chemin relatif
Obtenir un chemin de nom
de chier absolu partir
dun chemin relatif
Cet exemple retrouve le chemin absolu dun fichier dont
le chemin relatif est spcifi. Le chemin absolu dfinit le
chemin complet du fichier en commenant partir du
rpertoire racine du systme de fichiers, comme ceci :
c:\project\book\[Link].
Le nom de fichier relatif spcifie le nom et le chemin du
fichier par rapport au rpertoire courant, comme some-
[Link] si le rpertoire courant est c:\project\book.
Dans bien des cas, le nom de chemin relatif nest constitu
que du nom de fichier. La mthode getAbsoluteFile() de
la classe File retourne une objet File reprsentant le nom
de fichier absolu pour le fichier reprsent par lobjet File
sur lequel elle est appele.
Une autre mthode similaire, getAbsolutePath(), retourne
le chemin absolu sous forme de String et non dobjet File.
Le code suivant prsente cette mthode :
File file = new File( "[Link] ");
String absPath = [Link]();
Dans cet exemple, absPath contient la chane "c:\project\
book\[Link]".
File file = new File( "[Link] ");
File absPath = [Link]();
102 CHAPITRE 9 Travailler avec des rpertoires et des fichiers
Dterminer si un chemin de nom
de chier correspond un chier
ou un rpertoire
Cet exemple dtermine si lobjet File dsign reprsente
un fichier ou un rpertoire. La mthode isDirectory()
de la classe File retourne true si lobjet File sur lequel
elle est appele reprsente un rpertoire et false sil
reprsente un fichier. Elle est utile lorsque vous souhai-
tez parcourir lensemble des fichiers et sous-rpertoires
dun rpertoire donn. Par exemple, vous pourriez sou-
haiter crire une mthode qui liste tous les fichiers dun
rpertoire et parcoure de manire rcurrente chacun de
ses sous-rpertoires.
La mthode isDirectory() peut tre utilise lorsque vous
parcourez la liste des lments contenus dans chaque
rpertoire afin de dterminer sil sagit dun fichier ou
dun rpertoire.
Voici un exemple de ce type de mthode qui utilise la
mthode isDirectory() :
static void listAllFiles(File dir) {
String[] files = [Link]();
for (int i = 0; i < [Link]; i++) {
File f = new File(dir, files[i]);
File testPath = new File( "directoryName ");
boolean isDir = [Link]();
if (isDir) {
// testPath est un rpertoire
}
else {
// testPath est un fichier
}
103 Lister un rpertoire
if ([Link]()) {
listAllFiles(f);
}
else {
[Link]([Link]());
}
}
}
Si vous appelez cette mthode et lui passez un objet File
reprsentant un rpertoire, elle imprime les chemins com-
plets de tous les fichiers contenus dans le rpertoire et dans
lensemble de ses sous-rpertoires.
La classe File contient aussi une mthode isFile() qui
retourne true si lobjet File sur lequel elle est appele
reprsente un fichier et false sinon.
Lister un rpertoire
La classe File peut aussi tre utilise pour lister le contenu
dun rpertoire. Cet exemple utilise la mthode list() de
la classe File pour obtenir un tableau dobjets String
contenant tous les fichiers et sous-rpertoires contenus
dans le rpertoire spcifi par lobjet File. Si le rpertoire
nexiste pas, la mthode retourne null. Les chanes
retournes sont des noms de fichiers et des noms de rper-
toire simples et non des chemins complets. Lordre des
rsultats nest pas garanti.
File directory = new File("users/tim");
String[] result = [Link]();
104 CHAPITRE 9 Travailler avec des rpertoires et des fichiers
La mthode list() possde une autre implmentation qui
prend un paramtre [Link] et permet de
filtrer les fichiers et rpertoires retourns dans les rsultats
de la mthode. En voici un exemple :
File directory = new File("users/tim");
FilenameFilter fileFilter = new HTMLFileFilter();
String[] result = [Link](fileFilter);
Voici maintenant limplmentation correspondante de la
classe HTMLFileFilter :
class HTMLFileFilter extends FilenameFilter {
public boolean accept(File f) {
return [Link]() || [Link]()
.toLowerCase() .endsWith(".html"));
}
public String getDescription() }
return "/html files";
}
FilenameFilter est une interface dfinissant une mthode
nomme accept(). Celle-ci prend deux paramtres : un
objet File et un objet String. Lobjet File spcifie le
rpertoire dans lequel le fichier a t trouv et lobjet
String spcifie le nom du fichier. La mthode accept()
retourne true si le fichier doit tre inclus dans la liste et
false sinon. Dans cet exemple, nous avons cr un filtre
qui amne la mthode list() ninclure que les fichiers
qui se terminent par lextension .html.
Si le filtre pass est null, la mthode se comporte comme
la prcdente mthode list() sans paramtre.
En plus des mthodes list(), la classe File propose
deux versions dune mthode appele listFiles().
105 Lister un rpertoire
listFiles() retourne un tableau dobjets File au lieu
dun tableau de chanes. Lexemple utilise sa variante sans
paramtre :
File directory = new File("users/tim");
File[] result = [Link]();
Les objets File rsultants contiennent des chemins relatifs
ou absolus selon lobjet File depuis lequel la mthode
listFiles() a t appele. Si lobjet File de rpertoire
dans cet exemple contient un chemin absolu, le rsultat
contient des chemins absolus. Si lobjet File de rpertoire
contient un chemin relatif, les rsultats sont des chemins
relatifs.
Lautre version de listFiles() prend un paramtre File-
Filter, de manire analogue lexemple prsent pour la
mthode list(). En voici un exemple :
File directory = new File("users/tim");
FileFilter fileFilter = new HTMLFileFilter();
String[] result = [Link](fileFilter);
Voici maintenant limplmentation correspondante de la
classe HTMLFileFilter :
class HTMLFileFilter extends FileFilter {
public boolean accept(File f) {
return [Link]() ||
[Link]().toLowerCase().endsWith(".html");
}
public String getDescription() {
return ".html files";
}
}
106 CHAPITRE 9 Travailler avec des rpertoires et des fichiers
FileFilter est une interface dfinissant deux mthodes,
accept() et getDescription(). A la diffrence de la
mthode accept() de FilenameFilter, la mthode
accept() de FileFilter ne prend quun paramtre, un
objet File. Lobjet File spcifie un fichier ou un rper-
toire. La mthode accept() retourne true si le fichier
ou le rpertoire doivent tre inclus dans la liste et false
sinon. Dans cet exemple, nous avons cr un filtre qui
amne la mthode list() ninclure que les rpertoires
ou les fichiers qui se terminent par lextension .html.
Crer un nouveau rpertoire
Cet exemple utilise la mthode mkdir() de la classe File
pour crer un nouveau rpertoire. mkdir() retourne true
si le rpertoire a pu tre cr et false sinon. Elle ne cre
de rpertoire que si tous les rpertoires parents spcifis
existent dj. Ici, il est donc ncessaire que le rpertoire
users existe dj pour que mkdir() parvienne crer le
rpertoire users/tim.
La mthode mkdirs() de la classe File est une mthode
similaire qui permet de crer un arbre de rpertoires com-
plet en gnrant tous les rpertoires parents sils nexistent
pas. En voici un exemple :
boolean success = (new File("/users/tim/Web")).mkdirs( );
A lexcution de cette instruction, la mthode mkdirs()
crera tous les rpertoires (users, tim, Web) qui nexistent
pas.
boolean success = (new File("users/tim")).mkdir();
10
Clients rseau
La plupart des applications crites aujourdhui requirent
diffrents types de fonctionnalits rseau. Les applications
Java entirement autonomes se font de plus en plus rares.
Ce chapitre sur les clients rseau a donc toutes les chances
dtre utile la plupart des dveloppeurs Java qui conoi-
vent des applications aujourdhui.
Les programmes rseau impliquent une communication
entre un client et un serveur. En gnral, le client est
lapplication qui transmet une demande de contenu ou de
services et le serveur une application rseau qui sert ce
contenu et ces services de nombreux clients. Dans ce
chapitre, nous nous concentrerons spcifiquement sur le
client. Le Chapitre 11, "Serveurs rseau" traite des exem-
ples lis au serveur.
A lexception dun exemple concernant la lecture dune
page Web via HTTP, les exemples de ce chapitre oprent
tous au niveau de la programmation avec les sockets. Les
sockets sont une implmentation rseau de bas niveau.
Dans la plupart des cas, vous chercherez utiliser un pro-
tocole situ au niveau juste suprieur celui de la couche
des sockets, comme le HTTP, le SMTP ou le POP.
108 CHAPITRE 10 Clients rseau
Dautres API Java ou tierces permettent de travailler avec
ces protocoles rseau de plus haut niveau. Le paquetage
[Link] fournit les fonctionnalits de communication
rseau ct client que nous utiliserons dans ce chapitre.
La plate-forme J2EE (que nous nabordons pas dans ce
livre) propose de nombreux services rseau supplmen-
taires dont un support complet du dveloppement Web
Java ct serveur. Parmi les technologies rseau incluses
dans la plate-forme J2EE, on peut citer les servlets, les EJB
et le JMS.
Contacter un serveur
Dans cet exemple, nous nous connectons un serveur
via TCP/IP laide de la classe Java Socket. Lors de la
construction de linstance sock, une connexion de socket
est opre au serveur spcifi par serverName ici,
[Link], sur le port 80.
A chaque fois quun Socket est cr, vous devez veiller
fermer le socket lorsque vous avez termin en appelant la
mthode close() sur linstance Socket avec laquelle vous
travaillez.
Le Java prend en charge dautres mthodes de connexion
au serveur dont nous ne traiterons pas en dtail ici. Par
exemple, vous pouvez utiliser la classe URL pour ouvrir
une URL et la lire. Pour plus de dtails sur lutilisation de
la classe URL, consultez lexemple "Lire une page Web via
HTTP" de ce chapitre.
String serverName = "[Link]";
Socket sock = new Socket(serverName, 80);
109 Retrouver des adresses IP et des noms de domaine
Retrouver des adresses IP
et des noms de domaine
Dans cet exemple, nous rcuprons le nom dhte corres-
pondant une adresse IP connue, puis nous rcuprons
ladresse IP correspondant un nom dhte distant. Pour
ces deux tches, nous faisons appel la classe InetAddress.
Nous utilisons la mthode statique getByName() de la
classe InetAddress pour crer une instance InetAddress.
Nous pouvons passer une adresse IP ou un nom dhte
la mthode getByName() pour crer linstance InetAddress.
Une fois linstance InetAddress cre, nous pouvons
appeler la mthode getHostAddress() pour retourner
ladresse IP sous forme de String. Si nous connaissons
dj ladresse IP, nous pouvons appeler la mthode
getHostName() pour retourner le nom dhte sous forme de
String. Si le nom dhte ne peut pas tre rsolu, la
mthode getHostName() retourne ladresse IP.
// Trouver ladresse IP dun domaine
String hostName = [Link]";
String ip =
[Link](hostName).getHostAddress();
// Trouver le nom de domaine de ladresse IP
String ipAddress = "[Link]";
String hostName =
[Link](ipAddress).getHostName();
110 CHAPITRE 10 Clients rseau
Grer les erreurs rseau
Cet exemple prsente les exceptions que vous devez ten-
ter de capturer lorsque vous ralisez des oprations rseau.
La premire exception que nous essayons de capturer est
lexception UnknownHostException. Il sagit dune sous-classe
dIOException. Elle est leve afin dindiquer que ladresse
IP dun hte ne peut tre dtermine.
NoRouteToHostException et ConnectException sont des
sous-classes de SocketException. NoRouteToHostException
signale quune erreur sest produite lors de la tentative de
connexion un socket une adresse et un port distants.
En gnral, lhte distant ne peut pas tre atteint en raison
dun problme li un pare-feu ou un routeur interpos.
Lexception ConnectException est leve si une connexion
lhte distant est refuse. IOException est une exception
de porte plus gnrale qui peut galement tre leve
partir dappels rseau.
try {
// Connexion lhte rseau
// Ralisation des E/S rseau
}
catch (UnknownHostException ex) {
[Link]("Unknown host.");
}
catch (NoRouteToHostException ex) {
[Link]("Unreachable host.");
}
catch (ConnectException ex) {
[Link]("Connect refused.");
}
catch (IOException ex) {
[Link]([Link]());
}
111 Lire du texte
Les exemples de ce chapitre et du suivant nincluent pas
de mcanisme de gestion des erreurs. Il convient cepen-
dant de capturer ces exceptions dans vos applications Java
qui utilisent des fonctionnalits rseau.
Lire du texte
Cet exemple suppose que vous avez prcdemment cr
un socket au serveur partir duquel vous souhaitez lire du
texte. Pour plus dinformations sur la cration dune ins-
tance de socket, consultez lexemple "Contacter un ser-
veur" de ce chapitre. Une fois linstance socket obtenue,
nous appelons la mthode getInputStream() pour obtenir
une rfrence au flux dentre du socket. Avec cette rf-
rence, nous crons un InputStreamReader et lutilisons pour
instancier un BufferedReader. Nous lisons enfin le texte sur
le rseau avec la mthode readLine() du BufferedReader.
Cet usage du BufferedReader permet deffectuer une lec-
ture efficace des caractres, des tableaux et des lignes. Si vous
cherchez simplement lire une trs petite quantit de don-
nes, vous pouvez cependant aussi procder directement
depuis InputStreamReader, sans utiliser de BufferedReader.
Voici comment lire des donnes dans un tableau de carac-
tres en nutilisant quun InputStreamReader :
InputStreamReader in =
new InputStreamReader([Link]()));
String text = [Link](charArray, offset, length);
BufferedReader in = new BufferedReader
(new InputStreamReader([Link]()));
String text = [Link]();
112 CHAPITRE 10 Clients rseau
Dans cet exemple, les donnes sont lues depuis le flux
dentre dans le tableau de caractres spcifi par charArray.
Les caractres sont placs dans le tableau en commenant
une position spcifie par le paramtre de dcalage offset,
et le nombre maximal de caractres lus est spcifi par le
paramtre length.
Ecrire du texte
Cet exemple requiert que vous ayez prcdemment cr
un socket au serveur destination duquel vous souhaitez
crire du texte. Pour plus de dtails sur la cration de
linstance de socket, consultez lexemple "Contacter un
serveur" de ce chapitre. Une fois linstance de socket
obtenue, nous appelons la mthode getOutputStream()
pour obtenir une rfrence au flux de sortie du socket.
Lorsque la rfrence est acquise, nous instancions un
PrintWriter afin dcrire du texte sur le rseau vers le ser-
veur avec lequel nous sommes connects. Le second para-
mtre que nous passons au constructeur PrintWriter dans
cet exemple dfinit loption de purge automatique. La
valeur true amne les mthodes println(), printf() et
format() vider automatiquement le tampon de sortie.
Dans notre exemple, nous utilisons la mthode print().
Nous devons donc la faire suivre par un appel la
mthode flush() pour forcer lenvoi des donnes sur le
rseau.
PrintWriter out =
new PrintWriter([Link](), true);
[Link](msg);
[Link]();
113 Lire des donnes binaires
Lire des donnes binaires
Cet exemple montre comment lire des donnes binaires
sur un rseau. Il requiert que vous ayez prcdemment
cr un socket au serveur partir duquel vous souhaitez
lire du texte. Pour plus de dtails sur la cration de lins-
tance de socket, consultez lexemple "Contacter un ser-
veur" de ce chapitre.
Dans cet exemple, nous appelons la mthode getInput-
Stream() de linstance de socket afin dobtenir une rfrence
au flux dentre du socket. En passant le flux dentre en
paramtre, nous instancions un DataInputStream, que
nous pouvons utiliser pour lire des donnes binaires sur le
rseau. Nous utilisons la mthode readUnsignedByte()
pour lire un unique octet non sign sur le rseau.
Si le volume de donnes que vous lisez est important, il
est prfrable dencapsuler le flux dentre du socket dans
une instance BufferedInputStream, comme ceci :
DataInputStream in = new DataInputStream(new
BufferedInputStream([Link]()));
Ici, au lieu de passer directement le flux dentre du socket
au constructeur DataInputStream, nous crons dabord
une instance BufferedInputStream et la passons au cons-
tructeur DataInputStream.
Dans cet exemple, nous avons utilis la mthode read-
UnsignedByte(), mais DataInputStream possde bien dautres
mthodes pour lire des donnes dans nimporte quel
type de donnes Java primitif, dont les suivantes : read(),
DataInputStream in =
new DataInputStream([Link]());
[Link]();
114 CHAPITRE 10 Clients rseau
readBoolean(), readByte(), readChar(), readDouble(), read-
Float(), readInt(), readLong(), readShort(), readUnsigned-
Byte() et readUnsignedShort(). Consultez le JavaDoc pour
plus de dtails sur lutilisation de ces mthodes et dautres
mthodes de la classe DataInputStream : [Link]
.com/j2se/1.5.0/docs/api/java/io/DataInputStream
.html.
Ecrire des donnes binaires
Dans lexemple "Ecrire du texte" vu prcdemment, nous
avons montr comment crire des donnes texte sur un
rseau. Cet exemple montre comment crire des donnes
binaires sur le rseau. Il requiert que vous ayez prcdem-
ment cr un socket au serveur destination duquel vous
souhaitez crire du texte. Pour plus de dtails sur la cra-
tion de linstance de socket, consultez lexemple "Contac-
ter un serveur" de ce chapitre.
Dans cet exemple, nous appelons la mthode getOutput-
Stream() de linstance de socket pour obtenir une rf-
rence au flux de sortie du socket. Nous instancions
ensuite un DataOutputStream, que nous pouvons utiliser
pour crire des donnes binaires sur le rseau. Nous utili-
sons la mthode write() pour crire un tableau doctets
sur le rseau. La mthode write() prend trois paramtres.
Le premier est un byte[] servant rcuprer les octets
partir desquels crire. Le second dfinit un dcalage dans
le tableau doctets servant dterminer la position partir
de laquelle lcriture doit tre effectue. Le troisime
DataOutputStream out =
new DataOutputStream([Link]());
[Link](byteArray, 0, 10);
115 Lire des donnes srialises
spcifie le nombre doctets crire. Dans cet exemple,
nous crivons des octets du tableau byteArray en com-
menant la position 0 et en crivant 10 octets.
Si le volume des donnes que vous crivez est important, il
devient plus efficace dencapsuler le flux de sortie du socket
dans une instance BufferedOutputStream, comme ceci :
DataOutputStream out = new DataOutputStream(new
BufferedOutputStream([Link]()));
Au lieu de passer directement le flux de sortie de socket au
constructeur DataOutputStream, nous crons dabord une
instance BufferedOutputStream et la passons au construc-
teur DataOutputStream.
Dans cet exemple, nous avons utilis la mthode write(),
mais DataOutputStream possde bien dautres mthodes
pour crire des donnes depuis nimporte quel type de don-
nes Java primitif, dont les suivantes : write(), writeBoo-
lean(), writeByte(), writeBytes(), writeChar(), writeChars(),
writeDouble(), writeFloat(), writeInt(), writeLong() et write-
Short(). Pour plus de dtails sur lutilisation de ces mtho-
des de la classe DataOutputStream, consultez le JavaDoc
ladresse [Link]
java/io/[Link].
Lire des donnes srialises
Le Java permet de srialiser les instances dobjet et de les
crire dans un fichier ou sur un rseau. Cet exemple mon-
tre comment lire un objet srialis depuis un socket rseau.
ObjectInputStream in =
new ObjectInputStream([Link]());
Object o = [Link]();
116 CHAPITRE 10 Clients rseau
Il requiert que vous ayez prcdemment cr un socket
au serveur avec lequel vous souhaitez communiquer.
Pour plus de dtails sur la cration de linstance de socket,
consultez lexemple "Contacter un serveur" de ce chapitre.
Dans cet exemple, nous appelons la mthode getInput-
Stream() de linstance de socket afin dobtenir une rf-
rence au flux dentre du socket. Avec cette rfrence,
nous pouvons instancier un ObjectInputStream. La classe
ObjectInputStream est utilise pour dsrialiser des don-
nes et des objets primitifs prcdemment crits en utili-
sant un ObjectOutputStream. Nous utilisons la mthode
readObject() de lobjet ObjectInputStream pour lire un
objet depuis le flux. Lobjet peut ensuite tre transtyp en
son type attendu. Par exemple, pour lire un objet Date
depuis le flux, nous utiliserions la ligne suivante :
Date aDate = (Date)[Link]();
Tous les champs de donnes qui ne sont pas transitoires et
statiques retrouvent la valeur qui tait la leur lorsque
lobjet a t srialis.
Seuls les objets qui supportent linterface [Link]-
lizable ou [Link] peuvent tre lus
depuis des flux. Lors de limplmentation dune classe
srialisable, il est vivement recommand de dclarer un
membre de donnes serialVersionUID. Ce champ fournit
un numro de version qui est utilis lors de la dsrialisa-
tion pour vrifier que lmetteur et le rcepteur dun
objet srialis ont charg pour cet objet des classes compa-
tibles en termes de srialisation. Si vous ne dclarez pas
explicitement ce champ, un serialVersionUID par dfaut
est automatiquement calcul. Ce serialVersionUID par
dfaut tient finement compte des particularits de dtail
de la classe. Si vous apportez des modifications mineures
une classe et que vous souhaitiez conserver le mme
117 Ecrire des donnes srialises
numro de version en considrant que cette implmenta-
tion reste compatible avec la version courante, vous devez
dclarer votre propre serialVersionUID.
Ecrire des donnes srialises
Le Java permet de srialiser les instances dobjet et de les
crire dans un fichier ou sur un rseau. Cet exemple mon-
tre comment lire un objet srialis depuis un socket
rseau. Il requiert que vous ayez prcdemment cr un
socket au serveur avec lequel vous souhaitez communi-
quer. Pour plus de dtails sur la cration de linstance de
socket, consultez lexemple "Contacter un serveur" de ce
chapitre.
Dans cet exemple, nous appelons la mthode getOutput-
Stream() de linstance de socket pour obtenir une rf-
rence au flux de sortie du socket. Avec cette rfrence,
nous instancions un ObjectOutputStream. La classe Object-
OutputStream est utilise pour srialiser des donnes et des
objets primitifs. Nous utilisons la mthode writeObject()
de ObjectOutputStream pour crire un objet dans le flux.
Tous les champs de donnes qui ne sont pas transitoires et
statiques sont prservs dans la srialisation et restaurs
lorsque lobjet est dsrialis. Seuls les objets qui suppor-
tent linterface [Link] peuvent tre crits
dans des flux.
ObjectOutputStream out =
new ObjectOutputStream([Link]());
[Link](myObject);
118 CHAPITRE 10 Clients rseau
Lire une page Web via HTTP
Cet exemple prsente un autre moyen de lire des don-
nes depuis le rseau avec une programmation de plus
haut niveau que le niveau socket auquel se cantonnaient
les prcdents exemples. Le Java peut communiquer
avec une URL sur le protocole HTTP grce la classe
HttpURLConnection. Ici, nous instancions un objet URL en
passant une chane dURL valide au constructeur URL.
Ensuite, nous instancions un HttpURLConnection en passant
linstance url au constructeur HttpURLConnection. La
mthode getInputStream() est appele pour obtenir un
flux dentre afin de lire les donnes depuis la connexion
dURL. A laide du flux dentre, nous pouvons ensuite
lire le contenu de la page Web.
Il est aussi possible de lire le contenu dune URL en uti-
lisant directement la classe URL, comme ceci :
URL url = new URL("[Link]
[Link]();
La mthode getContent() retourne un Object. Celui-ci
peut tre un InputStream ou un objet contenant les don-
nes. Par exemple, la mthode getContent() peut retour-
ner un objet String stockant le contenu dune URL. La
mthode getContent() que nous venons dutiliser est en
fait un raccourci du code suivant :
[Link]();
URL url = new URL("[Link]
HttpURLConnection http = new HttpURLConnection(url);
InputStream in = [Link]();
119 Lire une page Web via HTTP
La mthode openConnection() de la classe URL retourne un
objet URLConnection. Il sagit de lobjet dans lequel la
mthode getContent() se trouve en fait implmente.
HttpURLConnection fournit des mthodes spcifiques au
HTTP qui ne sont pas disponibles dans les classes plus
gnrales URL ou URLConnection. Par exemple, on peut
utiliser la mthode getResponseCode() pour obtenir le
code dtat dun message de rponse HTTP. Le HTTP
dfinit galement un protocole pour rediriger les requtes
vers un autre serveur. La classe HttpURLConnection con-
tient des mthodes qui comprennent cette fonctionnalit
galement. Par exemple, si vous souhaitez oprer une
requte un serveur et suivre toutes les redirections quil
retourne, vous pouvez utiliser le code suivant pour dfinir
cette option :
URL url = new URL("[Link]
HttpURLConnection http = new HttpURLConnection(url);
[Link](true);
Loption est en fait positionne true par dfaut. Le cas
pratique le plus utile consistera donc au contraire posi-
tionner loption de suivi des redirections false lorsque
vous ne souhaitiez pas automatiquement tre redirig vers
un autre serveur que celui sur lequel votre requte portait
initialement. Cette mesure restrictive pourrait notamment
tre envisage avec certaines applications de scurit, lors-
que vous ne faites confiance qu certains serveurs spcifis.
Les pages Web qui contiennent des donnes sensibles
sont gnralement protges par un protocole de scu-
rit appel SSL (Secure Sockets Layer). Les pages prot-
ges par SSL sont dsignes par le prfixe "https" dans
la chane dURL, au lieu du prfixe "http" habituel.
120 CHAPITRE 10 Clients rseau
Le JDK standard inclut une implmentation du SSL
dans le cadre de JSSE (Java Secure Socket Extension). Pour
rcuprer une page protge par SSL, vous devez utiliser la
classe HttpsURLConnection au lieu de HttpURLConnection.
HttpsURLConnection gre tous les dtails du protocole
SSL, en toute transparence. Pour plus dinformations sur
lutilisation du SSL et les autres fonctionnalits de scurit
fournies par JSSE, consultez le guide de rfrence JSSE
propos par Sun ladresse : [Link]
1.5.0/docs/guide/security/jsse/[Link].
11
Serveurs rseau
En pratique, il y a bien plus de chances que vous criviez
du code de client rseau que du code de serveur rseau.
Toutefois, bon nombre dapplications intgrent la fois
des fonctionnalits client et des fonctionnalits serveur. Le
Java propose par chance un excellent support pour les
deux.
Le paquetage [Link] fournit les fonctionnalits de com-
munication rseau ct serveur que nous utiliserons dans
ce chapitre. La plate-forme J2EE (que nous nabordons
pas dans ce livre) propose de nombreux services rseau
supplmentaires dont un support complet du dveloppe-
ment Web Java ct serveur. Parmi les technologies
rseau incluses dans la plate-forme J2EE, on peut citer les
servlets, les EJB et le JMS.
122 CHAPITRE 11 Serveurs rseau
Crer un serveur et accepter
une requte
Cet exemple utilise une instance ServerSocket pour
crer un serveur coutant sur le port 9988. Nous passons
le port sur lequel nous souhaitons que le serveur coute
au constructeur du ServerSocket. Une fois le socket ser-
veur cr, nous appelons la mthode accept() pour atten-
dre une connexion client.
La mthode accept() bloque lexcution jusqu ce
quune connexion avec un client soit opre. Lorsquune
connexion est tablie, une nouvelle instance Socket est
retourne.
Si un gestionnaire de scurit est utilis, sa mthode check-
Accept() est appele avec [Link]().get-
HostAddress() et [Link]() en arguments, afin
de sassurer que lopration est autorise. Cette vrifica-
tion peut lever une exception SecurityException.
Les exemples de ce chapitre utilisent tous la classe Server-
Socket. Elle est utilise par le serveur pour attendre et ta-
blir les connexions client.
Lexemple prcdent la montr : lorsque vous commencez
par crer une classe ServerSocket, vous devez spcifier un
port couter pour les requtes entrantes. La classe Server-
Socket elle-mme nest pas utilise pour la communication
avec le client, mais uniquement pour tablir une connexion
public static final short PORT = 9988;
ServerSocket server = new ServerSocket(PORT);
while ((clientSock = [Link]( )) != null) {
// Traiter la demande du client
}
123 Retourner une rponse
avec lui. Lorsque ServerSocket accepte une connexion client,
une instance Socket standard est retourne. Cest cette ins-
tance qui est utilise pour communiquer avec le client.
Pour plus dinformations sur la manire dcrire votre
code lorsque vous vous attendrez devoir grer de nom-
breuses requtes clientes simultanes, consultez lexemple
"Grer plusieurs clients" de ce chapitre.
Retourner une rponse
Cet exemple montre comment retourner une rponse du
serveur au client. La mthode accept() de linstance Ser-
verSocket retourne une instance Socket lorsquune con-
nexion est tablie avec un client. Nous obtenons ensuite
le flux de sortie de ce socket en appelant la mthode
getOutputStream() de cet objet. Nous utilisons le flux de
sortie pour instancier un DataOutputStream et appelons la
mthode writeInt() de ce dernier pour crire une valeur
entire envoye sous forme de donnes binaires au client.
Pour finir, nous fermons le socket en utilisant la mthode
close() du Socket.
Cet exemple utilise la mthode write(), mais DataOutput-
Stream possde bien dautres mthodes pour crire des don-
nes depuis nimporte quel type de donnes Java primitif, et
notamment les suivantes : write(), writeBoolean(), write-
Byte(), writeBytes(), writeChar(), writeChars(), writeDou-
ble(), writeFloat(), writeInt(), writeLong() et writeShort().
Socket clientSock = [Link]();
DataOutputStream out =
new DataOutputStream([Link]());
[Link](someValue);
[Link]();
124 CHAPITRE 11 Serveurs rseau
Pour plus dinformations sur lutilisation de ces mthodes
et des autres mthodes de la classe DataOutputStream,
consultez la JavaDoc ladresse [Link]
1.5.0/docs/api/java/io/[Link].
Si vous souhaitez crire des donnes texte au client, utili-
sez le code suivant :
Socket clientSock = [Link]();
PrintWriter out = new PrintWriter(new
OutputStreamWriter([Link]()), true);
[Link]("Hello World");
[Link]();
Au lieu de crer un DataOutputStream, nous crons cette
fois un OutputStreamWriter et un PrintWriter. La mthode
print() du PrintWriter permet dcrire une chane de
texte destination du client. Le second paramtre pass au
constructeur PrintWriter dfinit loption de purge auto-
matique. La valeur true amne les mthodes println(),
printf() et format() vider automatiquement le tampon
de sortie. Comme notre exemple utilise la mthode
println(), il nest pas ncessaire dappeler explicitement
la mthode flush(). Enfin comme toujours, lorsque nous
avons fini dutiliser le PrintWriter, nous appelons la
mthode close() pour fermer le flux.
Retourner un objet
Socket clientSock = [Link]();
ObjectOutputStream os =
new ObjectOutputStream([Link]( ));
// Retourner un objet
[Link](new Date());
[Link]();
125 Retourner un objet
Cet exemple retourne un objet srialis au client. Nous
obtenons une instance Socket que retourne la mthode
accept() du ServerSocket une fois quune connexion
un client est tablie. Nous crons alors une instance
ObjectOutputStream et passons le flux de sortie obtenu
depuis le socket client. ObjectOutputStream est utilise
pour crire des types de donnes primitifs et des graphes
dobjets Java vers un OutputStream. Dans cet exemple,
nous crivons un objet Date dans le flux de sortie puis fer-
mons ce flux.
La mthode writeObject() srialise lobjet pass en para-
mtre. Dans cet exemple, il sagit dun objet Date. Tous
les champs de donnes qui ne sont pas transitoires et dyna-
miques sont prservs dans la srialisation et restaurs lors-
que lobjet est dsrialis. Seuls les objets qui supportent
linterface [Link] peuvent tre srialiss.
Le projet open source XStream de [Link] propose
une alternative intressante aux classes ObjectOutput-
Stream et ObjectInputStream. XStream fournit des impl-
mentations de ObjectInputStream et ObjectOutputStream
qui permettent aux flux dobjets dtre srialiss ou dsria-
liss en XML. La classe ObjectInputStream standard utilise
un format binaire pour les donnes srialises. La sortie
srialise des classes XStream fournit pour sa part les clas-
ses srialises dans un format XML facile lire. Pour plus
dinformations sur XStream et pour tlcharger ce projet,
rendez-vous ladresse [Link]
[Link].
126 CHAPITRE 11 Serveurs rseau
Grer plusieurs clients
Pour grer plusieurs clients, il suffit de crer un thread
pour chaque requte entrante traiter. Dans cet exemple,
nous crons un nouveau thread pour grer la connexion
cliente entrante immdiatement aprs avoir accept la
connexion. Ce procd permet de librer notre thread
dcouteur de serveur qui peut retourner couter les
connexions clientes suivantes.
Dans cet exemple, nous nous trouvons lintrieur dune
boucle while infinie : ds quun thread est engendr pour
grer une requte entrante, le serveur retourne immdia-
tement attendre la requte suivante. La classe Handler que
nous utilisons pour dmarrer le thread doit tre une sous-
classe de la classe Thread ou doit implmenter linterface
Runnable. Le code utilis dans lexemple est correct si
la classe Handler est une sous-classe de la classe Thread. Si la
classe Handler implmente au contraire linterface Runnable,
le code de dmarrage du thread devient alors le suivant :
Thread thd = new Thread(new Handler(clientSock));
[Link]();
Voici lexemple dune classe Handler simple qui tend la
classe Thread :
class Handler extends Thread {
Socket sock;
Handler(Socket socket) {
[Link] = socket;
}
while (true) {
Socket clientSock = [Link]();
new Handler(clientSock).start();
}
127 Grer plusieurs clients
public void run() {
DataInputStream in =
new DataInputStream([Link]());
PrintStream out =
new PrintStream([Link](), true);
// Gestion de la requte cliente
[Link]();
}
}
Cette classe peut tre utilise pour grer des requtes
clientes entrantes. Limplmentation concrte de la ges-
tion des requtes spcifiques dans le code est volontaire-
ment masque ici, aux fins de lillustration. Lorsque la
mthode start() de cette classe est appele, comme cest
le cas dans notre exemple prcdent, la mthode run()
dfinie ici est excute. start() est implmente dans la
classe de base Thread : nous navons pas la redfinir dans
notre implmentation de Handler.
Lors de la cration dune solution multithreade de ce type,
il peut aussi tre intressant de crer un systme de pooling
des threads. Dans ce cas, vous crerez un pool de threads
au dmarrage de lapplication au lieu dengendrer un nou-
veau thread pour chaque requte entrante.
Le pool de threads contient un nombre fixe de threads
pouvant excuter des tches. Ce systme vite que lappli-
cation ne cre un nombre excessif de threads qui pour-
raient grever les performances systme. Un trs bon article
(en anglais) concernant le pooling des threads peut tre
consult ladresse [Link]
cles/[Link]?p=30483&seqNum=3&rl=1. Pour plus
dinformations sur lutilisation des threads, consultez le
Chapitre 15, "Utiliser des threads".
128 CHAPITRE 11 Serveurs rseau
Servir du contenu HTTP
Cet exemple montre comment servir du contenu HTML
trs simple via HTTP. Pour commencer, nous acceptons
une connexion avec un client, crons un BufferedReader
pour lire la requte cliente et crons un PrintWriter que
nous utilisons pour retransmettre le HTML via HTTP au
client. Les donnes que nous crivons vers le PrintWriter
constituent le minimum ncessaire pour crer un message
de rponse HTTP valide. Notre rponse est compose de
trois champs den-tte HTTP et de nos donnes HTML.
Nous commenons notre rponse en spcifiant la version
HTTP et un code de rponse dans la ligne suivante :
[Link]("HTTP/1.1 200");
Nous indiquons le HTTP version 1.1 et le code de
rponse 200. Ce code signale que la requte a russi. A la
ligne suivante, nous signalons que le type de contenu
retourn est du HTML. Dautres types de contenu peuvent
tre retourns pour un message de rponse HTTP valide.
Socket client = [Link]();
BufferedReader in = new BufferedReader
(new InputStreamReader([Link]()));
// Avant de servir une rponse, on lit habituellement
// lentre cliente et on traite la requte.
PrintWriter out =
new PrintWriter([Link]());
[Link]("HTTP/1.1 200");
[Link]("Content-Type: text/html");
String html = "<html><head><title>Test Response" +
"</title></head><body>Just a test</body></html>";
[Link]("Content-length: " + [Link]());
[Link](html);
[Link]();
[Link]();
129 Servir du contenu HTTP
Par exemple, la ligne suivante spcifie que la rponse cor-
respond du texte brut et non du code HTML :
[Link]("Content-Type: text/plain");
Ensuite, nous crivons len-tte Content-length. Celui-ci
spcifie la longueur du contenu retourn, sans tenir
compte des champs den-tte. Aprs cela, nous crivons le
message HTML retourner. Pour finir, nous purgeons le
flux BufferedReader et le fermons avec les mthodes
flush() et close().
Info
Cette technique est utile pour les besoins simples en matire
de service HTTP, mais il nest pas recommand dcrire de tou-
tes pices un serveur HTTP complet en Java. Un excellent ser-
veur HTTP, gratuit et open source, est disponible dans le cadre
du projet Jakarta dApache : le serveur Tomcat. Pour plus
dinformations sur Tomcat et pour en tlcharger les fichiers,
accdez [Link] Tomcat sert du
contenu sur HTTP mais fournit galement un conteneur de ser-
vlets pour grer les servlets Java et les JSP.
12
Envoyer et recevoir
des e-mails
Le-mail est utilis dans de nombreuses applications. Il
est fort probable qu un stade ou un autre de vos projets
de dveloppement, vous soyez conduit prendre en
charge des courriers lectroniques dans lune de vos
applications Java.
Le Java facilite lintgration des fonctionnalits de messa-
gerie lectronique vos applications Java grce lAPI
JavaMail. Cette API est une extension du Java que vous
devez tlcharger sparment. Elle ne fait pas partie du
paquetage JDK standard propos en tlchargement. Les
classes utiles qui constituent lAPI JavaMail se trouvent
dans le paquetage [Link]. LAPI JavaMail actuelle
requiert le JDK 1.4 ou une version ultrieure. Les versions
antrieures du JDK ncessitent des versions galement
antrieures de lAPI JavaMail.
132 CHAPITRE 12 Envoyer et recevoir des e-mails
Ce chapitre traite de lenvoi et de la rception de-mails
partir dune application Java. Lintgration des capacits
de messagerie lectronique votre application Java consti-
tue un excellent ajout dans de nombreuses applications.
En pratique, ces fonctionnalits peuvent tre utiles pour
envoyer des alertes par e-mail, transmettre automatique-
ment des journaux et des rapports et plus gnralement,
communiquer avec les utilisateurs.
Vue densemble de lAPI JavaMail
JavaMail fournit des fonctionnalits pour envoyer et rece-
voir des e-mails. Des fournisseurs de service sajoutent
comme composants additionnels lAPI JavaMail pour
offrir des implmentations de diffrents protocoles de
messagerie. Limplmentation Sun inclut des fournisseurs
de services pour IMAP, POP3 et SMTP. JavaMail fait
galement partie de Java Enterprise dans J2EE.
Pour tlcharger lextension JavaMail, rendez-vous ladresse
[Link]
[Link].
Pour utiliser lAPI JavaMail, vous devez galement tlchar-
ger et installer lextension JAF (JavaBeans Activation Frame-
work) depuis [Link]
jaf/downloads/[Link].
En plus des exemples traits dans ce chapitre, vous pouvez
trouver des informations dtailles compltes sur lutilisa-
tion de lAPI JavaMail grce au lien JavaMail de rseau des
dveloppeurs Sun (en anglais) : [Link]
products/javamail/[Link].
133 Envoyer des e-mails
Envoyer des e-mails
Cet exemple envoie un message lectronique en texte
brut laide dun serveur SMTP. Six tapes de base doi-
vent tre imprativement suivies lorsque vous souhaitez
envoyer un e-mail avec lAPI JavaMail :
1. Vous devez crer un objet [Link], que
vous utiliserez pour passer des informations concernant
le serveur de messagerie.
2. Vous devez placer le nom dhte du serveur de messa-
gerie SMTP dans lobjet Properties, ainsi que toutes
les autres proprits dfinir.
3. Vous devez crer des objets Session et Message.
4. Vous devez dfinir les adresses e-mail du destinataire et
de lexpditeur du message ainsi que son sujet dans
lobjet Message.
5. Vous devez dfinir le texte du message dans lobjet
Message.
6. Vous devez appeler la mthode [Link]() pour
envoyer le message.
Lexemple prcdent suit chacune de ces tapes pour
crer et envoyer un message lectronique. Notez que les
adresses de provenance (From) et de destination (To) sont
cres sous forme dobjets InternetAddress. Lobjet
InternetAddress reprsente une adresse e-mail valide.
Properties props = new Properties( );
[Link]("[Link]", "[Link]");
Session session = [Link](props, null);
Message msg = new MimeMessage(session);
[Link](new InternetAddress("tim@[Link]"));
InternetAddress toAddress =
new InternetAddress("kerry@[Link]");
134 CHAPITRE 12 Envoyer et recevoir des e-mails
Une exception est leve si vous tentez de crer un objet
InternetAddress en utilisant un format dadresse e-mail
invalide. Lorsque vous spcifiez les destinataires To, vous
devez aussi spcifier leur type. Les types valides sont TO, CC
et BCC. Ils sont reprsents par les constantes suivantes :
[Link]
[Link]
[Link]
[Link]([Link], toAddress);
[Link]("Test Message");
[Link]("This is the body of my message.");
[Link](msg);
La classe Message est une classe abstraite dfinie dans le
paquetage [Link]. Une sous-classe qui limplmente
fait partie de limplmentation standard de JavaMail : la
classe MimeMessage. Cest cette implmentation que nous
utilisons dans lexemple au dbut de la section. La classe
MimeMessage reprsente un message lectronique de style
MIME. Elle devrait vous suffire pour la plupart de vos
besoins en matire de messagerie lectronique.
Dans cet exemple, nous utiliserons lobjet Properties pour
ne passer que lhte de messagerie SMTP. Il sagit de
lunique proprit qu'il est obligatoire de dfinir, mais
dautres proprits supplmentaires peuvent aussi tre sp-
cifies.
Info
Consultez le sommaire concernant le paquetage [Link]
dans la JavaDoc pour plus de dtails sur dautres proprits
de messagerie lies qui peuvent tre passes dans lobjet
Properties : [Link]
[Link].
135 Envoyer des e-mails MIME
Envoyer des e-mails MIME
MIME est lacronyme de Multimedia Internet Mail Exten-
sions. Ce standard est support par tous les principaux
clients de messagerie. Il constitue le moyen standard
dassocier des pices jointes aux messages. Il permet de
joindre aux e-mails une varit de types de contenu dont
des images, des vidos et des fichiers PDF. LAPI JavaMail
supporte galement les messages MIME. Il est mme
presque aussi facile de crer un message MIME avec des
pices jointes quun message standard en texte brut.
Dans cet exemple, nous crons et envoyons un message
MIME contenant un corps en texte brut et une pice
jointe HTML.
Pour crer un message multipartie, nous utilisons la classe
MultiPart du paquetage [Link]. La classe MimeMulti-
Part du paquetage [Link] fournit une impl-
mentation concrte de la classe abstraite MultiPart et utilise
des conventions MIME pour les donnes multiparties. La
classe MimeMultiPart permet dajouter plusieurs parties de
corps de message reprsentes sous forme dobjets MimeBo-
dyPart. Le contenu des parties de corps est dfini en utili-
sant la mthode setText() pour les parties de corps en
texte brut et setContent() pour les autres types de parties.
String html = "<html><head><title>Java Mail</title></head>"
+ "<body>Some HTML content.</body></html>";
Multipart mp = new MimeMultipart();
BodyPart textPart = new MimeBodyPart( );
[Link]("This is the message body.");
BodyPart htmlPart = new MimeBodyPart( );
[Link](html, "text/html");
[Link](textPart);
[Link](htmlPart);
[Link](mp);
[Link](msg);
136 CHAPITRE 12 Envoyer et recevoir des e-mails
Ensuite, nous utilisons la mthode setContent() en pas-
sant un objet contenant la partie de corps avec une chane
spcifiant le type MIME que nous ajoutons. Ici, nous
ajoutons une partie de corps HTML et spcifions donc le
type MIME text/html.
Le code prsent dans lexemple se concentre spcifique-
ment sur les tapes denvoi du message relatives au stan-
dard MIME. Voici un exemple plus complet qui inclut
toutes les tapes ncessaires la ralisation de cette tche :
Properties props = new Properties( );
[Link]("[Link]", "[Link]");
Session session = [Link](props, null);
Message msg = new MimeMessage(session);
[Link](new InternetAddress("tim@[Link]"));
InternetAddress toAddress =
new InternetAddress("kerry@[Link]");
[Link]([Link], toAddress);
[Link]("Test Message");
String html = "<html><head><title>Java Mail</title>
</head>" + "<body>Some HTML content.</body></html>";
Multipart mp = new MimeMultipart();
BodyPart textPart = new MimeBodyPart( );
[Link]("This is the message body.");
BodyPart htmlPart = new MimeBodyPart( );
[Link](html, "text/html");
[Link](textPart);
[Link](htmlPart);
[Link](mp);
[Link](msg);
137 Lire un e-mail
Info
LIANA (Internet Assigned Numbers Authority) propose une
rfrence prcise de tous les types de contenu MIME standard
sur son site Web. Le site propose galement une application
permettant denregistrer de nouveaux types MIME. Si vous
avez le sentiment quaucun type MIME existant ne correspond
votre contenu, vous pouvez utiliser cette application pour
demander la cration dun nouveau type de contenu MIME
correspondant votre type de contenu. Pour accder au site
Web de lIANA, rendez-vous ladresse [Link]
Les types de contenu MIME peuvent tre trouvs ladresse
[Link]
Lire un e-mail
Dans cet exemple, nous nous connectons un serveur de
messagerie POP3 et rcuprons tous les messages dans le
dossier INBOX (bote de rception). LAPI JavaMail facilite
considrablement cette tche.
Properties props = new Properties();
Session session = [Link](props, null);
Store store = [Link]("pop3");
[Link](host, username, password);
Folder folder = [Link]("INBOX");
[Link](Folder.READ_ONLY);
Message message[] = [Link]();
for (int i=0, n=[Link]; i<n; i++) {
[Link](i + ": " + message[i].getFrom()[0] +
"\t" + message[i].getSubject());
String content = message[i].getContent().toString();
[Link]([Link](0,100));
}
[Link](false);
[Link]();
138 CHAPITRE 12 Envoyer et recevoir des e-mails
Voici les tapes gnrales suivre lorsque vous utilisez
lAPI JavaMail pour lire des messages depuis un serveur de
messagerie POP :
1. Vous devez obtenir un objet Session.
2. Vous devez obtenir un objet Store partir de lobjet
Session.
3. Vous devez crer un objet Folder pour le dossier que
vous souhaitez ouvrir.
4. Vous devez ouvrir le dossier et rcuprer les messages.
Un dossier peut contenir des sous-dossiers : il convient
donc de rcuprer galement les messages de ces dos-
siers en procdant de manire rcursive.
Dans cet exemple, nous obtenons une instance par
dfaut de lobjet Session en utilisant la mthode statique
getDefaultInstance(). Lobjet Session reprsente une
session de messagerie. A partir de cet objet, nous obte-
nons ensuite un objet Store qui implmente le protocole
POP3. Lobjet Store reprsente un entrept de messages
et son protocole daccs. Si par exemple, nous souhai-
tions nous connecter un serveur de messagerie IMAP
au lieu dun serveur POP3, nous pourrions modifier
cette ligne de code afin dobtenir un entrept IMAP au
lieu dun entrept POP3. Nous devrions galement
inclure un fichier JAR supplmentaire qui supporte le
protocole IMAP. Sun fournit le fichier [Link] dans le
cadre de la distribution JavaMail. Nous nous connectons
un entrept POP3 en appelant la mthode connect() de
lobjet Store et en passant un hte, un nom dutilisateur
et un mot de passe.
139 Lire un e-mail
Dans le reste de lexemple, nous rcuprons le dossier
INBOX et tous les messages quil contient. Nous imprimons
lexpditeur (From), lobjet du message et les cent premiers
caractres du corps de chaque message dans le dossier
INBOX.
La classe Folder contient galement une mthode list()
qui nest pas utilise dans cet exemple mais permet de
rcuprer un tableau dobjets Folder reprsentant tous les
sous-dossiers du dossier sur lequel elle est appele. Si le
dossier INBOX contient de nombreux sous-dossiers, il est
ainsi possible dobtenir une rfrence chacun dentre
eux laide du code suivant :
Folder folder = [Link]("INBOX");
[Link](Folder.READ_ONLY);
Folder[] subfolders = [Link]();
Le tableau subfolders de cet exemple contiendra un objet
Folder pour chaque sous-dossier du dossier INBOX. Il sera
alors possible de traiter les messages dans chacun dentre
eux, comme nous lavons fait pour ceux du dossier INBOX.
La classe Folder propose aussi une mthode getFolder()
qui prend un unique paramtre de chane et retourne un
dossier dont le nom correspond la chane passe.
Grce la classe Folder, vous pouvez crire une mthode
qui parcourt lensemble dun compte de messagerie et lit
les messages des diffrents dossiers de lutilisateur.
13
Accs aux bases
de donnes
Les bases de donnes fournissent un mcanisme de stoc-
kage persistant pour les donnes dapplication et dans bien
des cas de figure, elles sont essentielles au fonctionnement
des applications. Le Java propose un excellent support
pour laccs aux bases de donnes relationnelles avec
lAPI JDBC (Java Database Connectivity).
Si votre application ne dfinit quun modle de donnes
trs simple et ne requiert quun accs trs limit une
base de donnes, lAPI JDBC convient bien. Au-del
de ce cas de figure, il peut cependant tre judicieux de
considrer lemploi dun framework de base de donnes
plutt que de programmer directement lAPI JDBC. Le
framework de persistance standard pour les applications
dentreprise est le framework EJB (Enterprise Java Beans).
EJB fait partie de Java Enterprise Edition. Il est considr
comme tant excessivement complexe par bon nombre
de dveloppeurs Java. Ce dfaut a dailleurs fait le succs
142 CHAPITRE 13 Accs aux bases de donnes
de certaines solutions open source qui deviennent de plus
en plus populaires. La complexit dEJB et les problmes
qui lui taient associs ont heureusement t partiellement
rsolus dans EJB 3.0. EJB 3.0 constitue une avance
majeure dans la bonne direction et devrait faire dEJB une
technologie plus conviviale pour les dveloppeurs.
Lexcellent framework de persistance de donnes open
source Hibernate gagne sans cesse en popularit. Il cre
une couche de mapping objet de vos donnes relationnel-
les. La couche de mapping objet permet de traiter les don-
nes persistantes avec une approche oriente objet par
opposition linterface SQL procdurale. Pour plus
dinformations sur le framework Hibernate, rendez-vous
ladresse [Link]
Ce chapitre se concentre purement sur laccs aux bases
de donnes via JDBC. Si vous utilisez un framework de
persistance de plus haut niveau, il reste important de bien
comprendre lAPI JDBC, car elle dfinit les fondations sur
lesquelles sappuient la plupart des frameworks de plus
haut niveau.
Se connecter une base
de donnes via JDBC
[Link]("[Link]");
Connection conn =
[Link](url, user, password);
Pour crer une connexion de base de donnes avec
JDBC, vous devez dabord charger un pilote. Dans cet
exemple, nous chargeons le JdbcOdbcDriver. Ce pilote
fournit une connectivit une source de donnes ODBC.
143 Se connecter une base de donnes via JDBC
Nous le chargeons avec la mthode [Link]().
Les pilotes de base de donnes JDBC sont gnralement
fournis par les diteurs de bases de donnes, bien que Sun
propose plusieurs pilotes gnriques dont le pilote ODBC
utilis dans cet exemple. Une fois le pilote charg, nous
obtenons une connexion la base de donnes avec la
mthode [Link](). La syntaxe uti-
lise pour spcifier la base de donnes laquelle nous
souhaitons nous connecter prend la forme dune URL.
Nous passons galement un nom dutilisateur et un mot
de passe valides pour la connexion la base de donnes.
LURL doit commencer par le prfixe jdbc:. Le reste du
format de spcification dURL (aprs le prfixe) est spci-
fique lditeur. Voici la syntaxe dURL pour se connec-
ter une base de donnes ODBC :
jdbc:odbc:nomdebasededonnes
La plupart des pilotes requirent que la chane dURL
inclue un nom dhte, un port et un nom de base de
donnes. Voici par exemple une URL valide pour la
connexion une base de donnes MySQL :
jdbc:mysql://[Link]/mydatabase
Cette URL spcifie une base de donnes MySQL sur lhte
[Link] pour une connexion sur le port 3306 avec
le nom de base de donnes mydatabase. Le format gnral
dune URL de base de donnes MySQL est le suivant :
jdbc:mysql://hte:port/base de donnes
Lun des autres moyens dobtenir une connexion de base
de donnes consiste utiliser JNDI. Cest en gnral
lapproche que vous adopterez si vous utilisez un serveur
dapplications comme WebLogic de BEA ou WebSphere
dIBM.
144 CHAPITRE 13 Accs aux bases de donnes
Hashtable ht = new Hashtable();
[Link](Context.INITIAL_CONTEXT_FACTORY,
"[Link]");
[Link](Context.PROVIDER_URL, "t3://hostname:port");
Context ctx = new InitialContext(ht);
[Link] ds =
([Link]) [Link]("myDataSource");
Connection conn = [Link]();
Avec JNDI, nous crons une instance InitialContext et
lutilisons pour rechercher un DataSource. Ensuite, nous
obtenons la connexion depuis lobjet de source de don-
nes. Une autre version de la mthode getConnection()
permet aussi de passer un nom dutilisateur et un mot de
passe pour la connexion aux bases de donnes requrant
une authentification.
Il est important de toujours veiller fermer la connexion
en utilisant la mthode close() de la classe Connection
lorsque vous avez termin dutiliser linstance Connection.
Envoyer une requte via JDBC
Dans cet exemple, nous crons une instruction JDBC avec
la mthode createStatement() de lobjet Connection et luti-
lisons pour excuter une requte qui retourne un ResultSet
Java. Pour la cration de la connexion, rfrez-vous au pr-
cdent exemple, "Se connecter une base de donnes via
JDBC". Pour raliser la requte SELECT, nous utilisons la
mthode executeQuery() de lobjet Statement.
Statement stmt = [Link]( );
ResultSet rs =
[Link]("SELECT * from users where name=tim");
145 Envoyer une requte via JDBC
Si vous souhaitez effectuer une opration UPDATE au lieu
dune requte SELECT, vous devez utiliser la mthode exe-
cuteUpdate() de lobjet Statement au lieu de sa mthode
executeQuery(). La mthode executeUpdate() est utilise
avec des instructions SQL INSERT, UPDATE et DELETE. Elle
retourne le compte des lignes pour les instructions INSERT,
UPDATE ou DELETE ou 0 si linstruction SQL ne retourne rien.
Voici un exemple dexcution dune instruction UPDATE :
Statement stmt = [Link]( );
int result = [Link]("UPDATE users SET name=
tim where id=1234");
Il est important de se souvenir quil nest possible douvrir
quun seul objet ResultSet la fois par objet Statement.
Toutes les mthodes dexcution dans linterface Statement
ferment lobjet ResultSet courant sil en existe dj un
douvert. Ce point est important retenir si vous imbri-
quez des connexions et des requtes de base de donnes.
JDBC 3.0 a introduit une fonctionnalit de conservation
du jeu de rsultats. Elle permet de conserver plusieurs jeux
de rsultats ouverts si vous spcifiez cette option lorsque
lobjet dinstruction est cr. Pour en apprendre plus sur les
nouvelles fonctionnalits de JDBC 3.0, consultez larticle
suivant (en anglais) sur le site Web DeveloperWorks dIBM :
[Link]
library/j-jdbcnew/.
Lorsque vous travaillez avec des instructions et des rsul-
tats, veillez toujours bien fermer les objets Connection,
Statement et ResultSet lorsque vous en avez termin.
Chacun de ces objets possde une mthode close() per-
mettant de le fermer afin de librer la mmoire et les
ressources. Si vous omettez de les fermer, vous risquez
de crer des fuites mmoire dans vos applications Java.
146 CHAPITRE 13 Accs aux bases de donnes
Le fait de ne pas fermer une connexion peut galement
provoquer des cas dinterblocage dans les applications
multithreades.
Si lune de vos instructions SQL doit tre excute de nom-
breuses fois, il est plus efficace dutiliser une requte Prepa-
redStatement. Pour plus dinformations ce sujet, consultez
lexemple suivant, "Utiliser une instruction prpare".
Utiliser une instruction prpare
Pour crer une instruction prpare dans JDBC, vous
devez utiliser un objet PreparedStatement au lieu dun
objet Statement. Dans cet exemple, nous passons le code
SQL la mthode prepareStatement() de lobjet Connec-
tion. Cette opration cre un objet PreparedStatement.
Avec une instruction prpare, les valeurs de donnes
dans linstruction SQL sont spcifies laide de points
dinterrogation. Les vritables valeurs pour ces jokers
reprsents par des points dinterrogation sont dfinies
plus tard en utilisant les mthodes set de PreparedState-
ment. Les mthodes set disponibles sont setArray(),
setAsciiStream(), setBigDecimal(), setBinaryStream(),
setBlob(), setBoolean(), setByte(), setBytes(), setCha-
racterStream(), setClob(), setDate(), setDouble(), set-
Float(), setInt(), setLong(), setNull(), setObject(),
PreparedStatement stmnt = [Link]("INSERT
into users values (?,?,?,?)");
[Link](1, name);
[Link](2, password);
[Link](3, email);
[Link](4, employeeId);
[Link]( );
147 Utiliser une instruction prpare
setRef(), setShort(), setString(), setTime(), setTimes-
tamp() et setURL(). Chacune de ces mthodes set est uti-
lise pour dfinir un type de donnes spcifique sous
forme de paramtre dans linstruction SQL. Par exemple,
la mthode setInt() est utilise pour dfinir des param-
tres entiers, la mthode setString() pour dfinir des para-
mtres String, etc.
Dans cet exemple, nous positionnons trois valeurs de
chane et une valeur entire avec les mthodes setS-
tring() et setInt().
Chaque point dinterrogation qui apparat dans linstruc-
tion de requte doit avoir une instruction set corres-
pondante qui dfinisse sa valeur. Le premier paramtre
des instructions set spcifie la position du paramtre cor-
respondant dans linstruction de requte. Si la valeur 1 est
passe comme premier paramtre une instruction set, cest
ainsi la valeur correspondant au premier point dinterro-
gation qui est positionne dans linstruction de requte.
Le second paramtre des instructions set spcifie la valeur
elle-mme du paramtre. Dans notre exemple, les varia-
bles name, password et email sont toutes censes tre de
type String. La variable employeeId est de type int.
Lorsque vous crez une instruction SQL que vous allez
rutiliser plusieurs fois, il est plus efficace dutiliser un
objet PreparedStatement au lieu dun objet Statement
standard. Linstruction prpare est une instruction SQL
prcompile qui offre une excution plus rapide une fois
cre.
148 CHAPITRE 13 Accs aux bases de donnes
Rcuprer les rsultats
dune requte
Les requtes JDBC retournent un objet ResultSet. Ce
dernier reprsente une table de donnes contenant les
rsultats dune requte de base de donnes. Le contenu du
ResultSet peut tre parcouru afin dobtenir les rsultats de
la requte excute. Le ResultSet conserve un curseur
qui pointe sur la ligne de donnes courante. Lobjet
ResultSet possde une mthode next() qui dplace le
curseur la ligne suivante. La mthode next() retourne
false lorsquil ny a plus de ligne dans lobjet ResultSet.
Il est ainsi possible dutiliser une boucle while pour par-
courir toutes les lignes contenues dans le ResultSet.
Le ResultSet possde des mthodes getter permettant de
rcuprer les valeurs de colonne de la ligne courante. Les
valeurs de donnes peuvent tre rcupres laide du
numro dindex ou du nom de la colonne. La numrota-
tion des colonnes commence 1. La casse nest pas prise
en compte pour les noms de colonne fournis en entre
aux mthodes getter.
Dans cet exemple, nous obtenons un ResultSet suite
lexcution dune requte SELECT. Nous parcourons en
boucle les lignes contenues dans le ResultSet en utilisant
la mthode next() et une boucle while. Nous obtenons
les valeurs de donnes name et password avec la mthode
getString().
ResultSet rs = [Link]("SELECT name, password
FROM users where name=tim");
while ([Link]( )) {
String name = [Link](1);
String password = [Link](2);
}
149 Utiliser une procdure stocke
Rappelez-vous quil est conseill de fermer vos instances
de ResultSet lorsque vous avez fini de les utiliser. Les
objets ResultSet sont automatiquement ferms lorsque
lobjet Statement qui les a gnrs est ferm, rexcut ou
utilis pour rcuprer le rsultat suivant dune squence
de rsultats multiples.
Utiliser une procdure stocke
Les procdures stockes sont des programmes de base de
donnes stocks et conservs dans la base de donnes
elle-mme. Elles peuvent tre appeles depuis le code Java
en utilisant linterface CallableStatement et la mthode
prepareCall() de lobjet Connection. CallableStatement
retourne un objet ResultSet comme le fait Statement ou
PreparedStatement. Dans cet exemple, nous appelons la
procdure stocke ListAllUsers sans paramtre.
Lobjet CallableStatement peut prendre des paramtres
dentre galement. Ceux-ci sont grs exactement
comme ils le sont avec un PreparedStatement. Par exem-
ple, le code suivant montre comment appeler une proc-
dure stocke qui utilise des paramtres dentre :
CallableStatment cs = [Link]("{ call
AddInts(?,?) }");
[Link](1,10);
[Link](2,50);
ResultSet rs = [Link]( );
CallableStatment cs =
[Link]("{ call ListAllUsers }");
ResultSet rs = [Link]( );
150 CHAPITRE 13 Accs aux bases de donnes
A la diffrence des autres types dinstructions JDBC,
CallableStatement peut galement retourner des param-
tres, appels paramtres OUT. Le type JDBC de chaque
paramtre OUT doit tre enregistr avant que lobjet
CallableStatement puisse tre excut. Cette inscription
sopre avec la mthode registerOutParameter(). Une
fois que linstruction a t excute, les paramtres OUT
peuvent tre rcuprs en utilisant les mthodes getter de
CallableStatement.
CallableStatement cs = [Link]("{call
getData(?, ?)}");
[Link](1, [Link]);
[Link](2, [Link]);
ResultSet rs = [Link]();
int intVal = [Link](1);
String strVal = [Link](2);
Dans cet exemple, nous appelons une procdure stocke
nomme getData() qui possde deux paramtres OUT.
Lun de ces paramtres OUT est une valeur int et lautre
une valeur String. Une fois ces deux paramtres enregis-
trs, nous excutons la requte et obtenons leurs valeurs
avec les mthodes getInt() et getString().
Lune des autres diffrences remarquer tient ce que
les procdures stockes peuvent retourner plusieurs jeux
de rsultats. Si une procdure stocke retourne plus dun
jeu de rsultats, on peut utiliser la mthode getMore-
Results() de la classe CallableStatement pour fermer
le jeu de rsultats courant et pointer sur le suivant.
La mthode getResultSet() peut tre appele ensuite
pour rcuprer le jeu de rsultats nouvellement dsign.
151 Utiliser une procdure stocke
Voici un exemple qui retourne plusieurs jeux de rsultats
et utilise ces mthodes pour rcuprer chacun dentre eux :
int i;
String s;
[Link]();
rs = [Link]();
while ([Link]()) {
i = [Link](1);
}
[Link]();
rs = [Link]();
while ([Link]()) {
s = [Link](1);
}
[Link]();
[Link]();
Ici, nous positionnons la valeur int i avec les rsultats du
premier jeu de rsultats et la variable String s avec ceux
du second.
14
XML
Le XML (eXtensible Markup Language) est driv du SGML
(Standard Generalized Markup Language), tout comme le
HTML (Hypertext Markup Language). En fait, le XML est
mme analogue en bien des points au HTML, ceci prs
quen XML, il vous revient de dfinir vos propres balises.
Vous ntes pas cantonn un jeu prdfini de balises
comme vous ltes en HTML. Le XHTML, pour sa part,
est une version du HTML compatible avec le standard
XML.
Le XML est couramment utilis comme format gnrique
pour lchange de donnes entre serveurs et applications,
dans les processus de communication entre couches appli-
catives ou pour le stockage de donnes complexes comme
les documents de traitement de texte voir les fichiers gra-
phiques.
Le XML a t largement adopt dans tous les secteurs
dindustrie et par la majorit des langages de programma-
tion. La plupart dentre eux proposent maintenant un
support pour le traitement des donnes XML. Le Java ny
fait pas exception et fournit dexcellents outils pour le
traitement des documents XML, que ce soit pour crer
ou pour lire des donnes XML.
154 CHAPITRE 14 XML
Ce chapitre requiert des connaissances en XML. Si vous
souhaitez apprendre ce langage ou parfaire vos connaissan-
ces dans ce domaine, consultez XML de Michael Morrison
(CampusPress, 2006).
Deux API de parsing XML courantes indpendantes du
langage sont dfinies par le W3C (World Wide Web
Consortium) : les API DOM et SAX. Le DOM (Document
Object Model) est un parseur qui lit un document XML
entier et construit un arbre dobjets Node, que lon appelle
le DOM ou le modle objet du document. Le DOM livre
une reprsentation parse complte du document XML
dont vous pouvez extraire des lments tout moment.
SAX (Simple API for XML) nest pas un vritable parseur en
soi, mais plus exactement une API qui dfinit un mca-
nisme de gestion des vnements pouvant servir parser
des documents XML. Vous pouvez crer des mthodes de
rappel qui sont appeles par lAPI SAX au moment o des
lments spcifiques du document XML sont atteints.
Limplmentation SAX scanne le document XML en
appelant les mthodes de rappel ds quelle rencontre le
dbut et la fin dlments particuliers du document XML.
Avec SAX, le document XML nest jamais compltement
stock ou reprsent en mmoire.
Limplmentation Java du traitement XML est appele
JAXP (Java API for XML Processing). JAXP permet aux
applications de parser et de transformer des documents
XML sans laide dune implmentation de traitement
XML. JAXP contient un parseur DOM et un parseur
SAX ainsi quune API XSLT pour la transformation des
documents XML. XSLT est lacronyme de eXtensible Sty-
lesheet Language Transformations. La technologie XSLT
permet de transformer les documents XML en les faisant
passer dun format un autre. JAXP fait partie intgrante
du JDK 1.4 et de ses versions ultrieures.
155 Parser du XML avec SAX
Parser du XML avec SAX
LAPI SAX opre en scannant le document XML de bout
en bout et en fournissant des rappels pour les vnements
qui se produisent. Ces vnements peuvent correspondre
la rencontre du dbut dun lment, de sa fin, du dbut
dun attribut, de sa fin, etc. Ici, nous crons une instance
XMLReader en utilisant le SAXParser. Une fois linstance de
parseur cre, nous dfinissons un gestionnaire de con-
tenu avec la mthode setContentHandler(). Le gestion-
naire de contenu est une classe qui dfinit les diffrentes
mthodes de rappel appeles par le parseur SAX lorsque le
document XML est pars. Ici, nous crons une instance
de MyXMLHandler, une classe que nous allons devoir ensuite
implmenter, en guise de gestionnaire. Ensuite, nous
appelons la mthode parse() et lui passons le nom dun
document XML. Ds lors, le traitement SAX dmarre.
Le code suivant prsente une implmentation dexemple
de la classe MyXMLHandler. La classe DefaultHandler que
nous tendons est une classe de base par dfaut pour les
gestionnaires dvnements SAX.
class MyXMLHandler extends DefaultHandler {
public void startElement(String uri, String
localName, String qname, Attributes attributes) {
// Traiter le dbut de llment
}
public void endElement(String uri, String localName,
String qname) {
XMLReader parser = [Link]
("[Link]");
[Link](new MyXMLHandler( ));
[Link]("[Link]");
156 CHAPITRE 14 XML
// Traiter la fin de llment
}
public void characters(char[] ch, int start, int length) {
// Traiter les caractres
}
public MyXMLHandler( )
throws [Link] {
super( );
}
}
Cette implmentation dexemple nimplmente que trois
mthodes : startElement(), endElement() et characters().
La mthode startElement() est appele par le parseur SAX
lorsquil rencontre le dbut dun lment dans le document
XML. De la mme manire, la mthode endElement() est
appele lorsquil rencontre la fin dun lment. La
mthode characters() est appele pour signaler la prsence
de donnes de caractre dans un lment. Pour obtenir une
description complte de toutes les mthodes qui peuvent
tre redfinies dans le gestionnaire SAX, consultez la Java-
Doc DefaultHandler : [Link]
docs/api/org/xml/sax/helpers/[Link].
Dans cet exemple, le parseur SAX sous-jacent est Xerces.
Nous le dfinissons dans lappel de mthode suivant :
XMLReader parser = [Link]
("[Link]");
JAXP est conu pour permettre des implmentations
de parseur externes : si vous prfrez un autre parseur
Xerces, rien ne vous empche de lutiliser avec le code
157 Parser du XML avec DOM
de cet exemple. Veillez cependant bien inclure limpl-
mentation du parseur dans votre chemin de classe.
SAX est gnralement plus efficace au niveau de la
mmoire que le parseur DOM car le document XML
nest pas tout entier stock en mmoire. LAPI DOM lit
le document entier en mmoire pour le traiter.
Parser du XML avec DOM
Dans cet exemple, nous utilisons les trois classes Docu-
mentBuilderFactory, DocumentBuilder et Document pour
dmarrer le parsing dun document XML avec un parseur
DOM. Le parsing sopre avec la classe DocumentBuilder.
Cette dernire dfinit lAPI permettant dobtenir des ins-
tances de Document DOM partir dun document XML.
La classe DocumentBuilder peut parser du XML depuis une
varit de sources dentre, dont des InputStream, des
File, des URL et des SAXInputSources. Ici, nous parsons le
XML partir dune source dentre File. La mthode
parse() de la classe DocumentBuilder parse le document
XML et retourne un objet Document.
Lobjet Document reprsente le DOM du document XML.
Cette instance Document peut ensuite tre utilise pour
accder aux composants du document XML, comme ses
entits, ses lments, ses attributs, etc.
File file = new File("[Link]");
DocumentBuilderFactory f =
[Link]();
DocumentBuilder p = [Link]();
Document doc = [Link](file);
158 CHAPITRE 14 XML
Lobjet Document est un conteneur pour une collection
hirarchique dobjets Node qui reprsente la structure du
document XML. Les nuds ont un parent, des enfants
ou des attributs associs. Le type Node contient trois sous-
classes qui reprsentent les principaux composants du
document XML : Element, Text et Attr. Considrons
maintenant un exemple de parsing dun DOM avec la
classe Document. Voici le document XML dexemple que
nous allons utiliser :
<Location>
<Address>
<City>Flat Rock</City>
<State>Michigan</State>
</Address>
</Location>
En supposant que nous avons dj obtenu une instance
Document avec la technique de parsing prsente dans
lexemple de dpart, il suffira dutiliser le code Java suivant
pour extraire les valeurs de texte de villes (city) et dtats
(state) :
NodeList list = [Link]("City");
Element cityEl = (Element)[Link](0);
String city = ((Text)[Link]()).getData();
NodeList list = [Link]("State");
Element stateEl = (Element)[Link](0);
String state = ((Text)[Link]()).getData();
La mthode getElementsByTagName() retourne un NodeList
contenant tous les lments qui correspondent au nom
pass. Notre document dexemple ne contient quun seul
lment City et un seul lment State : nous rcuprons
159 Utiliser une DTD pour vrifier un document XML
donc simplement le premier lment (index zro) de la
liste de nuds et le transtypons en un Element. Les l-
ments City et State possdent chacun un enfant, de type
Text. Nous utilisons la mthode getData() du type Text
pour rcuprer la valeur de ville (city) et dtat (state).
A la diffrence du parseur SAX, le parseur DOM lit le
document XML entier en mmoire, le parse et le traite
cet endroit. Ce procd est moins efficace en termes de
consommation de mmoire que celui du parseur SAX qui
ne stocke pas le document XML entier en mmoire mais
le scanne progressivement la manire dun flux.
Utiliser une DTD pour vrier
un document XML
Les DTD (Document Type Definition) sont des fichiers qui
dfinissent la manire dont un document XML particulier
doit tre structur. Une DTD peut ainsi spcifier quels
lments et quels attributs sont autoriss dans un docu-
ment. Les documents XML qui se conforment une
DTD sont considrs tre valides. Les documents XML
syntaxiquement corrects mais qui ne se conforment pas
une DTD sont simplement dits bien forms.
Pour valider un document avec une DTD, vous devez
appeler la mthode setValidating() de linstance Docu-
mentBuilderFactory et lui passer la valeur true. Tous les
documents XML parss sont ensuite valids par rapport
DocumentBuilderFactory factory =
[Link]();
[Link](true);
DocumentBuilder builder = [Link]();
160 CHAPITRE 14 XML
aux DTD spcifies dans leur en-tte. Voici une dcla-
ration de DTD classique en haut dun document XML :
<!DOCTYPE people SYSTEM "file:[Link]">
Cette dclaration attache le fichier [Link] stock
dans le systme de fichiers local sous forme de DTD au
document XML dans lequel elle est dclare.
Lorsque vous spcifiez la validation DTD, une exception
est lance depuis la mthode parse() de la classe Document-
Builder si le document XML que vous parsez ne se con-
forme pas la DTD.
Le standard XML Schema est une technologie plus
rcente qui offre les mmes avantages que les DTD. Les
schmas XML dfinissent le balisage attendu des docu-
ments XML, comme le font les DTD. Lavantage des
documents de schma tient cependant ce quils sont
eux-mmes des documents XML et que vous navez donc
pas besoin dun autre parseur pour les lire, alors que les
DTD ne sont pas des documents XML valides. Les DTD
respectent la syntaxe XBNF (eXtended Backus-Naur Form).
Pour utiliser un schma, vous devez utiliser la mthode
setSchema() du DocumentBuilderFactory au lieu de la
mthode setValidating(), comme ceci :
DocumentBuilderFactory factory =
[Link]();
[Link](schema);
DocumentBuilder builder = [Link]();
La mthode setSchema() prend une instance dun objet
Schema. Nous nentrerons pas ici dans les considrations
de dtail concernant lutilisation des schmas, mais vous
pouvez consulter la JavaDoc de DocumentBuilderFactory
pour plus dinformations sur limplmentation des schmas
161 Crer un document XML avec DOM
en Java, ladresse suivante : [Link]
1.5.0/docs/api/javax/xml/parsers/DocumentBuil-
[Link].
Pour plus dinformations sur les schmas en gnral, con-
sultez la documentation XML Schema ladresse :
[Link]
Crer un document XML avec DOM
Cet exemple utilise lAPI DOM et JAXP pour crer un
document XML. Le segment XML cr est le suivant :
<Location>
<Address>
<City>Flat Rock</City>
<State>Michigan</State>
</Address>
</Location>
DocumentBuilderFactory fact =
[Link]( );
DocumentBuilder builder = [Link]( );
Document doc = [Link]( );
Element location = [Link]("Location");
[Link](location);
Element address = [Link]("Address");
[Link](address);
Element city = [Link]("City");
[Link](city);
[Link]([Link]("Flat Rock"));
Element state = [Link]("State");
[Link](state);
[Link]([Link]("Michigan"));
(([Link])doc)
.write([Link]);
162 CHAPITRE 14 XML
La principale classe utilise ici est la classe [Link]
.Document. Elle reprsente le DOM dun document
XML. Nous crons une instance de la classe Document en
utilisant un DocumentBuilder obtenu partir dun Docu-
mentBuilderFactory. Chaque lment du document XML
est reprsent dans le DOM sous forme dinstance Element.
Dans le document XML que nous crons, nous avons
construit des objets Element appels Location, Address,
City et State. Nous ajoutons llment de niveau racine
(Location) lobjet de document avec la mthode append-
Child() de lobjet Document. La classe Element contient
elle aussi une mthode appendChild() que nous utilisons
pour construire la hirarchie du document sous llment
racine.
LAPI DOM permet tout aussi facilement de crer un
Element avec des attributs. Le code suivant peut tre uti-
lis pour ajouter un attribut "id" possdant la valeur
"home" llment Location :
[Link]("id","home");
Dans cet exemple, le parseur DOM sous-jacent est Crim-
son. Cette implmentation apparat dans la dernire ligne,
reproduite ici :
(([Link])doc)
.write([Link]);
JAXP est conu pour supporter les implmentations de
parseur externes : si vous prfrez un autre parseur
Crimson, rien ne vous empche de lutiliser avec le code
de cet exemple. Veillez cependant bien inclure limpl-
mentation du parseur dans votre chemin de classe.
LAPI JDOM est une alternative lAPI JAXP pour le
travail avec les documents XML. Il sagit dun projet open
source standardis par le biais du JCP (Java Community
163 Transformer du XML avec des XSLT
Process), sous la rfrence JSR 102. Pour plus dinforma-
tions sur lAPI JDOM, consultez le site [Link].
JDOM propose une API Java native en remplacement de
lAPI DOM standard pour lire et crer des documents
XML. De nombreux dveloppeurs trouvent lAPI JDOM
plus facile utiliser que lAPI DOM lors de la cration de
documents XML.
Transformer du XML avec des XSLT
Le XSLT est un standard pour la transformation des docu-
ments XML qui permet den modifier la structure laide
de feuilles de style XSL. Le paquetage [Link]-
form contient lAPI permettant dutiliser des transforma-
tions XSLT standard en Java. XSL est lacronyme de
eXtensible Stylesheet Language. XSLT est lacronyme de XSL
Transformation (transformation XSL), un langage qui per-
met de restructurer compltement les documents XML.
Lorsque vous utiliserez des XSLT, vous aurez en gnral
un document XML dentre et une feuille de style XSL
dentre et produirez en les combinant un document
XML de sortie. Le type du document de sortie ne se
limite cependant pas au XML. Bien dautres sortes de
documents de sortie peuvent tre cres laide de trans-
formations XSL.
StreamSource input =
new StreamSource(new File("[Link]"));
StreamSource stylesheet =
new StreamSource(new File("[Link]"));
StreamResult output = new StreamResult(new File("[Link]"));
TransformerFactory tf = [Link]();
Transformer tx = [Link](stylesheet);
[Link](input, output);
164 CHAPITRE 14 XML
Dans cet exemple, nous crons des instances StreamSource
pour les documents utiliss en entre du processus de
transformation : le document XML transformer et la
feuille de style XSL contenant les instructions de transfor-
mation. Nous crons aussi un objet StreamResult qui ser-
vira recueillir le rsultat de lcriture du document de
sortie. Nous obtenons ensuite une instance Transformer
gnre partir dune instance TranformerFactory.
Le flux de feuille de style est ensuite pass la mthode
newTranformer() de lobjet TransformerFactory pour crer
un objet Transformer. Pour finir, nous appelons la mthode
transform() du Transformer afin de transformer notre
document XML dentre en un document de sortie mis
en forme avec la feuille de style slectionne.
Le XSL peut tre une technologie trs efficace pour les
dveloppeurs. Si votre application Web doit tre accessi-
ble partir dune varit de priphriques diffrents,
comme des assistants personnels, des navigateurs Web et
des tlphones cellulaires, vous pourrez ainsi utiliser des
XSLT pour transformer votre sortie afin den adapter le
format chacun des priphriques concerns, sans pro-
grammer chaque fois une sortie spare. Les XSLT sont
aussi trs utiles pour crer des sites multilingues. La sortie
XML peut en effet tre transforme en plusieurs langages
grce des transformations XSLT.
15
Utiliser des threads
Le threading dsigne la mthode utilise par une applica-
tion logicielle pour accomplir plusieurs processus la fois.
En Java, un thread est une unit dexcution programme
qui sexcute simultanment dautres threads.
Les threads sont frquemment utiliss dans les applications
dinterface utilisateur graphique (GUI). Dans une applica-
tion de ce type, un thread peut couter lentre du clavier
ou dautres priphriques de saisie pendant quun autre
traite la commande prcdente.
La communication rseau implique aussi souvent lusage
du multithreading. En programmation rseau, un thread
peut couter les requtes de connexion, pendant quun
autre traite une requte prcdente. Les minuteurs utili-
sent aussi couramment les threads. Ils peuvent tre
dmarrs sous forme de thread sexcutant indpendam-
ment du reste de lapplication. Dans tous ces exemples, le
multithreading permet une application de poursuivre le
traitement tout en excutant une autre tche qui peut
prendre plus de temps et provoquerait de longs dlais en
labsence de multithreading.
166 CHAPITRE 15 Utiliser des threads
Le Java facilite grandement lcriture dapplications multi-
threades. La conception dapplications multithreades tait
trs complexe en C, mais en Java, tout est bien plus simple.
Lancer un thread
Il existe deux techniques principales pour crire du code
qui sexcute dans un thread spar. Vous pouvez impl-
menter linterface [Link] ou tendre la classe
[Link]. Dans lun ou lautre cas, vous devez
implmenter une mthode run() qui contient le code
excuter dans le thread.
Dans cet exemple, nous avons tendu la classe [Link]
.Thread. A lemplacement o nous souhaitons dmarrer le
thread, nous instancions notre classe MyThread et appelons
la mthode start() hrite de la classe Thread.
Voici maintenant le code permettant dexcuter un
thread avec lautre technique, en implmentant linter-
face Runnable :
public class MyThread2 implements Runnable {
public void run() {
// Excuter des tches
}
}
// Code pour utiliser MyThread2
Thread t = new Thread(MyThread2);
[Link]();
public class MyThread extends Thread {
public void run() {
// Excuter des tches
}
}
// Code pour utiliser MyThread
new MyThread().start();
167 Lancer un thread
Linterface Runnable est en gnral implmente lorsquune
classe tend une autre classe et ne peut donc tendre la
classe Thread galement. Le Java ne supporte que lhritage
unique : une classe ne peut tendre deux classes diffrentes.
La mthode lintrieur de laquelle nous dmarrons le
thread est ici lgrement diffrente. Au lieu dinstancier
la classe prcdemment dfinie, comme nous lavons fait
en tendant linterface Thread, nous instancions un objet
Thread et passons la classe implmentant Runnable en
paramtre au constructeur Thread. Ensuite, nous appelons
la mthode start() de Thread, qui dmarre le thread et
planifie son excution.
Lun des autres moyens pratiques de crer un thread con-
siste implmenter linterface Runnable en utilisant une
classe interne anonyme, comme ceci :
public class MyThread3 {
Thread t;
public static void main(String argv[]) {
new MyThread3();
}
public MyThread3() {
t = new Thread(new Runnable( ) {
public void run( ) {
// Excuter des tches
}
});
[Link]( );
}
}
168 CHAPITRE 15 Utiliser des threads
Dans cet exemple, tout le code est contenu lintrieur
dune unique classe et se trouve donc parfaitement encap-
sul. On peut ainsi mieux voir ce qui se passe. Notre
implmentation Runnable est dfinie sous forme de classe
interne au lieu de crer explicitement une classe qui
implmente linterface Runnable. Cette solution est idale
pour les petites mthodes qui ninteragissent que trs peu
avec des classes externes.
Arrter un thread
Si vous souhaitez crer un thread que vous pourrez arrter
avant la fin de son excution (autrement dit, avant le retour
de la mthode run()), la meilleure solution consiste utili-
ser un drapeau boolen dont vous testerez ltat au dbut
public class StoppableThread extends Thread {
private boolean done = false;
public void run( ) {
while (!done) {
[Link]("Thread running");
try {
sleep(500);
}
catch (InterruptedException ex) {
// Ne rien faire
}
}
[Link]("Thread finished.");
}
public void shutDown( ) {
done = true;
}
}
169 Attendre quun thread se termine
dune boucle globale. Dans cet exemple, nous crons un
thread en tendant la classe Thread avec notre classe Stop-
pableThread. A lintrieur de la mthode run(), nous crons
une boucle while qui vrifie ltat dun drapeau boolen
done. Tant que le drapeau done vaut false, le thread
continue. Pour arrter le thread, il suffit un processus
externe de positionner le drapeau true. La boucle while
de la mthode run() quitte alors et termine ce thread.
La classe Thread contient une mthode stop() que lon
peut tre tent dutiliser pour arrter le thread, mais Sun
en dconseille lusage, car si votre thread opre sur un
objet de structure de donnes et que vous appelez soudai-
nement sa mthode stop(), les objets peuvent tre laisss
dans un tat incohrent. Si dautres threads attendent
que cet objet particulier soit libr, ils risquent alors de se
bloquer et dattendre indfiniment. Des problmes dinter-
blocage peuvent avoir lieu. La mthode stop() est ga-
lement dconseille depuis le JDK 1.2. Si vous utilisez la
mthode stop() dans lun de ces JDK, le compilateur
gnre des avertissements ce sujet.
Larticle de rfrence (en anglais) ladresse suivante
explique les raisons pour lesquelles la mthode stop() est
dconseille : [Link]
guide/misc/[Link].
Attendre quun thread se termine
Thread t = new Thread(MyThread);
[Link]();
// Raliser dautres oprations
[Link]();
// Continue aprs que le thread t se termine
170 CHAPITRE 15 Utiliser des threads
Dans certains cas, vous pourrez souhaiter quun thread
dexcution attende quun autre thread ait termin avant
de poursuivre. La jonction des threads est une mthode
courante pour interrompre un thread jusqu ce quun
autre thread ait achev son travail. Dans cet exemple,
nous dmarrons le thread t de lintrieur du thread qui
excute ces lignes de code. Des oprations sont ensuite
excutes, puis nous appelons la mthode join() de
lobjet de thread lorsque nous souhaitons arrter lexcu-
tion du thread en attendant que le thread t en ait fini.
Lorsque t a fini, lexcution se poursuit jusquaux instruc-
tions qui suivent la ligne dans laquelle nous avons appel
la mthode join(). Si le thread t a dj compltement
termin lorsque nous appelons join(), cette dernire
retourne immdiatement lexcution.
Une autre forme de la mthode join() prend un para-
mtre long contenant une valeur en millisecondes.
Lorsque cette mthode est utilise, le thread appelant
attend au maximum le nombre de millisecondes spcifi
avant de continuer, mme si le thread sur lequel la
mthode join() est appele na pas fini. Enfin, une troi-
sime implmentation de la mthode join() prend deux
paramtres, une valeur long en millisecondes et une
valeur int en nanosecondes. Cette mthode se comporte
exactement comme la version un paramtre, sauf que
les valeurs en millisecondes et en nanosecondes sont
additionnes pour dterminer la dure pendant laquelle
le thread appelant doit attendre avant de continuer.
Cette mthode offre un contrle plus fin sur le temps
dattente.
171 Synchroniser des threads
Synchroniser des threads
La synchronisation est utilise pour empcher que plu-
sieurs threads puissent accder simultanment des
sections spcifiques du code. Le mot-cl synchronized
qui apparat dans cet exemple permet de synchroniser
une mthode ou un bloc de code afin quun seul thread
puisse lexcuter la fois. Dans le contexte de cet exem-
ple, si un thread excute actuellement myMethod(), tous les
autres threads qui tentent dexcuter la mme mthode
sur la mme instance dobjet sont bloqus lextrieur de
la mthode jusqu ce que le thread courant termine son
excution et la retourne de myMethod().
Dans le cas des mthodes non statiques, la synchronisation
sapplique uniquement linstance dobjet sur laquelle un
autre thread excute la mthode. Les autres threads gardent
la possibilit dexcuter la mme mthode mais sur une ins-
tance diffrente. Au niveau de linstance, le verrouillage
sapplique toutes les mthodes synchronises de linstance.
Aucun thread ne peut appeler la moindre mthode syn-
chronise dune instance dont un thread excute dj une
mthode synchronise. Dans le cas des mthodes statiques,
seul un thread la fois peut excuter la mthode.
Le mot-cl synchronized peut galement tre appliqu
des blocs de code, sans ncessairement concerner lensem-
ble dune mthode. Le bloc de code suivant opre une
synchronisation de ce type :
synchronized(myObject) {
// Faire quelque chose avec myObject
}
public synchronized void myMethod() {
// Excuter quelque chose
}
172 CHAPITRE 15 Utiliser des threads
Lors de la synchronisation dun bloc de code, vous devez
spcifier lobjet sur lequel la synchronisation doit tre
opre. Bien souvent, le but est doprer la synchronisa-
tion sur lobjet qui contient le bloc de code, ce qui peut
tre fait en passant lobjet this comme objet synchroni-
ser, comme ceci :
synchronized(this) {
// Faire quelque chose
}
Lobjet pass au mot-cl synchronized est verrouill
lorsquun thread excute le bloc de code quil entoure.
La synchronisation est gnralement utilise lorsque laccs
concurrentiel par plusieurs threads peut risquer dendom-
mager des donnes partages.
Une classe dite thread-safe garantit quaucun thread nutilise
un objet qui se trouve dans un tat incohrent. Le bloc de
code suivant prsente un exemple de classe qui risquerait
dtre problmatique si elle ntait pas rendue thread-safe
en appliquant le mot-cl synchronized la mthode
adjust(). En gnral, les classes qui possdent des mem-
bres de donnes dinstance sont susceptibles de poser des
problmes dans les environnements multithreads. A titre
dexemple, supposons que deux threads excutent la
mthode adjust() et que cette dernire ne soit pas syn-
chronise. Le thread A excute la ligne size=size+1 et se
trouve interrompu juste aprs la lecture de la valeur size,
mais avant dattribuer la nouvelle valeur size.
Le thread B sexcute maintenant et appelle la mthode
reset(). Cette mthode positionne la variable size 0.
Le thread B est ensuite interrompu et retourne le contrle
au thread A, qui reprend maintenant lexcution de lins-
truction size=size+1, en incrmentant la valeur de size
dune unit. Au final, la mthode reset() ne parat pas
avoir t appele. Ses effets sont contrecarrs par les
173 Synchroniser des threads
imprvus du multithreading. Si le mot-cl synchronized
est appliqu ces mthodes, ce cas de figure ne se produit
plus, car un seul thread est alors autoris excuter lune
ou lautre des mthodes. Le deuxime thread doit atten-
dre que le premier ait termin lexcution de la mthode.
public class ThreadSafeClass {
private int size;
public synchronized void adjust() {
size = size + 1;
if (size >= 100) {
size = 0;
}
}
public synchronized void reset() {
size = 0;
}
}
La programmation thread-safe ne sapplique qu une appli-
cation qui possde plusieurs threads. Si vous crivez une
application qui nutilise pas de multithreading, vos soucis
senvolent. Avant dopter pour ce choix, considrez cepen-
dant aussi que votre application ou votre composant peu-
vent tre rutiliss dautres endroits. Quand vous
nutilisez quun seul thread, posez-vous cette question :
est-il possible quun autre projet utilise ce composant dans
un environnement multithread ?
La synchronisation peut tre utilise pour rendre un objet
thread-safe, mais noubliez pas quelle implique un com-
promis en termes de performances. Lexcution des
mthodes synchronises est consquemment plus lente en
raison de la surcharge lie au verrouillage des objets.
Veillez ainsi ne synchroniser que les mthodes qui
requirent vritablement dtre thread-safe.
174 CHAPITRE 15 Utiliser des threads
Suspendre un thread
MyThread thread = new MyThread();
[Link]();
while (true) {
// Quelques tches
synchronized (thread) {
[Link] = true;
}
// Quelques tches
synchronized (thread) {
[Link] = false;
[Link]();
}
}
class MyThread extends Thread {
boolean doWait = false;
public void run() {
while (true) {
// Quelques tches
synchronized (this) {
while (doWait) {
wait();
}
catch (Exception e) {
}
}
}
}
}
}
175 Suspendre un thread
Cet exemple montre comment suspendre un thread
depuis un autre thread. Nous utilisons la variable doWait
comme drapeau. Dans la mthode run() de MyThread,
nous vrifions ltat de ce drapeau aprs avoir ralis une
tche dans une boucle afin de dterminer si nous devons
suspendre lexcution du thread. Si le drapeau doWait vaut
true, nous appelons la mthode [Link]() pour sus-
pendre lexcution du thread.
Lorsque nous souhaitons relancer le thread, nous posi-
tionnons le drapeau doWait false et appelons la
mthode [Link]() pour relancer le thread et
poursuivre sa boucle dexcution.
La suspension du thread est trs simple raliser, comme
le montre le fragment suivant :
long numMilliSecondsToSleep = 5000;
[Link](numMilliSecondsToSleep);
Ce code suspend le thread courant pendant 5 000 millise-
condes, soit 5 secondes. En plus de ces mthodes, deux
mthodes appeles [Link]() et [Link]()
fournissent un mcanisme pour la suspension des threads,
mais elles sont dconseilles. Elles peuvent en effet sou-
vent crer des interblocages. Nous ne les mentionnons ici
que pour signaler quil convient de ne pas les utiliser.
176 CHAPITRE 15 Utiliser des threads
Lister tous les threads
Cet exemple liste tous les threads en cours dexcution.
Chaque thread rside dans un groupe de threads et chaque
groupe de threads peut contenir des threads et dautres
groupes de threads. La classe ThreadGroup permet de
public static void listThreads() {
ThreadGroup root =
[Link]().getThreadGroup().getParent();
while ([Link]() != null) {
root = [Link]();
}
visitGroup(root, 0);
}
public static void visitGroup(ThreadGroup group, int level) {
int numThreads = [Link]();
Thread[] threads = new Thread[numThreads];
[Link](threads, false);
for (int i=0; i<numThreads; i++) {
Thread thread = threads[i];
printThreadInfo(thread);
}
int numGroups = [Link]();
ThreadGroup[] groups = new ThreadGroup[numGroups];
numGroups = [Link](groups, false);
for (int i=0; i<numGroups; i++) {
visitGroup(groups[i], level+1);
}
}
private static void printThreadInfo(Thread t) {
[Link]("Thread: " + [Link]( ) +
" Priority: " + [Link]( ) + ([Link]( )?"
Daemon":"") + ([Link]( )?"":" Not Alive"));
}
177 Lister tous les threads
regrouper des threads et dappeler des mthodes qui
affectent tous les threads dans le groupe de threads. Les
ThreadGroup peuvent galement contenir des ThreadGroup
enfants. Les ThreadGroup organisent ainsi tous les threads
en une hirarchie complte.
Dans cet exemple, nous parcourons en boucle tous les
groupes de threads afin dimprimer des informations
concernant chacun des threads. Nous commenons par
retrouver le groupe de threads racine. Ensuite, nous utili-
sons la mthode visitGroup() pour consulter de manire
rcursive chaque groupe de threads situ sous le groupe
racine. Dans la mthode visitGroup(), nous numrons
dabord tous les threads contenus dans le groupe puis
appelons la mthode printThreadInfo() pour imprimer le
nom, la priorit et ltat (dmon ou non, vivant ou non)
de chaque thread. Aprs avoir parcouru en boucle tous les
threads dans le groupe courant, nous numrons tous les
groupes quil contient et oprons un appel rcursif la
mthode visitGroup() pour chaque groupe. Cet appel
de mthode se poursuit jusqu ce que tous les groupes et
tous les threads aient t numrs et que les informations
concernant chacun des threads aient t imprimes.
Les groupes de threads sont souvent utiliss pour regrou-
per des threads lis ou similaires, par exemple selon la
fonction quils ralisent, leur provenance ou le moment
o ils doivent tre dmarrs et arrts.
16
Programmation
dynamique
par rexion
La rflexion est un mcanisme permettant de dcouvrir
lexcution des donnes concernant un programme.
En Java, elle permet de dcouvrir des informations
concernant des champs, des mthodes et des construc-
teurs de classes. Vous pouvez aussi oprer sur les champs
et mthodes que vous dcouvrez de cette manire. La
rflexion permet ainsi de raliser en Java ce que lon
appelle couramment une programmation dynamique.
La rflexion sopre en Java laide de lAPI Java Reflec-
tion. Cette API est constitue de classes dans les paqueta-
ges [Link] et [Link].
180 CHAPITRE 16 Programmation dynamique par rflexion
Entre autres possibilits, lAPI Java Reflection permet
notamment :
b de dterminer la classe dun objet ;
b dobtenir des informations concernant des modifica-
teurs, des champs, des mthodes, des constructeurs et
des superclasses ;
b de retrouver les dclarations de constantes et de
mthodes appartenant une interface ;
b de crer une instance dune classe dont le nom nest pas
connu jusqu lexcution ;
b de retrouver et de dfinir la valeur dun champ dobjet ;
b dinvoquer une mthode sur un objet ;
b de crer un nouveau tableau, dont la taille et le type
de composant sont inconnus jusquau moment de
lexcution.
LAPI Java Reflection est couramment utilise pour crer
des outils de dveloppement tels que des dbogueurs, des
navigateurs de classes et des gnrateurs dinterfaces utili-
sateur graphiques. Ces types doutils requirent souvent
dinteragir avec des classes, des objets, des mthodes et des
champs sans que lon puisse savoir lesquels ds la compila-
tion. Lapplication doit alors retrouver ces lments en
cours dexcution et y accder de manire dynamique.
Obtenir un objet Class
Lopration la plus simple en programmation rflexive
consiste obtenir un objet Class. Une fois linstance
MyClass a = new MyClass();
[Link]();
181 Obtenir un objet Class
dobjet Class rcupre, il est ensuite possible dobtenir
toutes sortes dinformations concernant la classe et mme
de la manipuler. Dans cet exemple, nous utilisons la
mthode getClass() pour obtenir un objet Class. Cette
mthode est souvent utile avec une instance dobjet dont
vous ne connaissez pas la classe de provenance.
Plusieurs autres approches permettent dobtenir un objet
Class. Dans le cas dune classe dont le nom de type est
connu la compilation, il existe un moyen plus simple
dobtenir une instance de classe. Vous devez simplement
utiliser le mot-cl de compilateur .class, comme ceci :
Class aclass = [Link];
Si le nom de la classe nest pas connu la compilation et
se trouve seulement disponible lexcution, vous devez
utiliser la mthode forName() pour obtenir un objet
Class. Par exemple, la ligne de code suivante cre un
objet Class associ la classe [Link] :
Class c = [Link]("[Link]");
Vous pouvez aussi utiliser la mthode getSuperClass()
sur un objet Class afin dobtenir un objet Class reprsen-
tant la superclasse de la classe rflchie. Par exemple, dans
le code suivant, lobjet Class a rflchit la classe TextField
et lobjet Class b rflchit la classe TextComponent car
TextComponent est la superclasse de TextField :
TextField textField = new TextField();
Class a = [Link]();
Class b = [Link]();
182 CHAPITRE 16 Programmation dynamique par rflexion
Obtenir un nom de classe
Pour obtenir le nom dun objet Class, il suffit dappeler la
mthode getName() sur lobjet concern. Lobjet String
retourn par la mthode getName() est un nom de classe
pleinement qualifi. Dans cet exemple, si la variable
someObject est une instance de la classe String, le nom
retourn par lappel getName() est :
[Link].
Dcouvrir des modicateurs
de classe
Dans les dfinitions de classe, plusieurs mots-cls appels
modificateurs peuvent prcder le mot-cl class. Ces modi-
ficateurs sont public, abstract ou final. Pour dcouvrir
quel modificateur a t appliqu une classe, vous devez
dabord obtenir un objet Class reprsentant la classe
concerne avec la mthode getClass(). Ensuite, vous
devez appeler la mthode getModifiers() sur lobjet de
Class c = [Link]();
String s = [Link]();
Class c = [Link]();
int mods = [Link]();
if ([Link](mods))
[Link]("public");
if ([Link](mods))
[Link]("abstract");
if ([Link](mods))
[Link]("final");
183 Trouver des superclasses
classe pour rcuprer une valeur int code reprsentant
les modificateurs. Les mthodes statiques de la classe
[Link] peuvent ensuite tre utilises
pour dterminer les modificateurs qui ont t appliqus.
Ces mthodes statiques sont isPublic(), isAbstract() et
isFinal().
Info
Si lun de vos objets de classe peut reprsenter une interface, il
peut aussi tre souhaitable dutiliser la mthode isInterface().
Cette mthode retourne true si les modificateurs passs incluent
le modificateur interface. La classe Modifier contient des
mthodes statiques supplmentaires qui permettent de dter-
miner quels modificateurs ont t appliqus aux mthodes et
variables de la classe, dont les suivantes : isPrivate(), isPro-
tected(), isStatic(), isSynchronized(), isVolatile(), isTran-
sient(), isNative() et isStrict().
Trouver des superclasses
Les anctres dune classe sont appels ses superclasses. Elles
peuvent tre retrouves par rflexion. Une fois que vous
avez obtenu un objet Class, vous pouvez utiliser la mthode
getSuperclass() pour retrouver la superclasse de la classe. Si
la superclasse existe, un objet Class est retourn. Sil ny a
pas de superclasse, la mthode retourne null. Rappe-
lez-vous que le Java ne supporte que lhritage unique :
chaque classe ne peut donc avoir quune seule superclasse.
Class cls = [Link]();
Class superclass = [Link]();
184 CHAPITRE 16 Programmation dynamique par rflexion
Plus prcisment, chaque classe ne peut avoir quune seule
superclasse directe. En thorie, toutes les classes anctres
sont considres tre des superclasses. Pour les rcuprer
toutes, vous devez rcursivement appeler la mthode get-
Superclass() sur chacun des objets Class retourns.
La mthode suivante imprime toutes les superclasses asso-
cies lobjet pass :
static void printSuperclasses(Object obj) {
Class cls = [Link]();
Class superclass = [Link]();
while (superclass != null) {
String className = [Link]();
[Link](className);
cls = superclass;
superclass = [Link]();
}
}
Les EDI (environnements de dveloppement intgr)
comme Eclipse incluent souvent un navigateur de classes
qui permet au dveloppeur de parcourir visuellement la
hirarchie des classes. La technique que nous venons de
prsenter est gnralement utilise pour construire ces
navigateurs de classes. Pour dvelopper un navigateur
de classes visuel, votre application doit pouvoir retrou-
ver les superclasses dune classe donne.
185 Dterminer les interfaces implmentes par une classe
Dterminer les interfaces
implmentes par une classe
Dans lexemple prcdent, nous avons vu comment
retrouver les superclasses associes une classe donne.
Ces superclasses sont lies au mcanisme dhritage et
dextension des classes du Java. En plus des possibilits
qui vous sont offertes en matire dextension des classes,
le Java vous permet galement dimplmenter des inter-
faces. Les interfaces quune classe donne a impl-
mentes peuvent aussi tre retrouves par rflexion. Une
fois que vous avez obtenu un objet Class, vous devez
utiliser la mthode getInterfaces() pour rcuprer les
interfaces implmentes par la classe. getInterfaces()
retourne un tableau dobjets Class. Chaque objet du
tableau reprsente une interface implmente par la
classe concerne. Vous pouvez utiliser la mthode get-
Name() de ces objets Class pour rcuprer le nom des
interfaces implmentes.
Class c = [Link]();
Class[] interfaces = [Link]();
for (int i = 0; i < [Link]; i++) {
String interfaceName = interfaces[i].getName();
[Link](interfaceName);
}
186 CHAPITRE 16 Programmation dynamique par rflexion
Dcouvrir des champs de classe
Les champs publics dune classe peuvent tre dcouverts
laide de la mthode getFields() de lobjet Class.
La mthode getFields() retourne un tableau dobjets
Field contenant un objet par champ public accessible. Les
champs publics accessibles retourns ne sont pas
ncessairement des champs contenus directement dans la
classe avec laquelle vous travaillez. Il peut aussi sagir des
champs contenus :
b dans une superclasse ;
b dans une interface implmente ;
b dans une interface tendue partir dune interface
implmente par la classe.
A laide de la classe Field, vous pouvez rcuprer le nom,
le type et les modificateurs du champ. Ici, nous impri-
mons le nom et le type de chacun des champs. Vous pou-
vez galement retrouver et dfinir la valeur des champs.
Pour plus de dtails ce sujet, consultez les exemples
"Rcuprer des valeurs de champ" et "Dfinir des valeurs
de champ" de ce chapitre.
Si vous le prfrez, vous pouvez aussi rcuprer un champ
individuel dun objet au lieu de tous ses champs si vous en
Class c = [Link]();
Field[] publicFields = [Link]();
for (int i = 0; i < [Link]; i++) {
String fieldName = publicFields[i].getName();
Class fieldType = publicFields[i].getType();
String fieldTypeStr = [Link]();
[Link]("Name: " + fieldName);
[Link]("Type: " + fieldTypeStr);
}
187 Dcouvrir des constructeurs de classe
connaissez le nom. Lexemple suivant montre comment
rcuprer un champ unique :
Class c = [Link]();
Field titleField = [Link]("title");
Ce code rcupre un objet Field reprsentant le champ
nomm "title".
Les mthodes getFields() et getField() ne retournent
que les membres de donnes publics. Si vous souhaitez
rcuprer tous les champs dune classe et notamment ses
champs privs et protgs, utilisez les mthodes getDecla-
redFields() ou getDeclaredField(). Elles se comportent
comme leurs quivalents getFields() et getField() mais
retournent tous les champs en incluant les champs privs
et protgs.
Dcouvrir des constructeurs
de classe
La mthode getConstructors() peut tre appele sur un
objet Class afin de rcuprer des informations concernant
les constructeurs publics dune classe. Elle retourne un
Class c = [Link]();
Constructor[] constructors = [Link]();
for (int i = 0; i < [Link]; i++) {
Class[] paramTypes = constructors[i].getParameterTypes();
for (int k = 0; k < [Link]; k ++) {
String paramTypeStr = paramTypes[k].getName();
[Link](paramTypeStr + " ");
}
[Link]();
}
188 CHAPITRE 16 Programmation dynamique par rflexion
tableau dobjets Constructor, qui peuvent ensuite tre uti-
liss pour retrouver le nom, les modificateurs et les types
de paramtre des constructeurs et les exceptions qui peu-
vent tre leves. Lobjet Constructor possde galement
une mthode newInstance() permettant de crer une
nouvelle instance de la classe du constructeur.
Dans cet exemple, nous obtenons tous les constructeurs
de la classe someObject. Pour chaque constructeur trouv,
nous rcuprons un tableau dobjets Class reprsentant
tous ses paramtres. A la fin, nous imprimons chacun des
types de paramtre pour chaque constructeur.
Info
Le premier constructeur contenu dans le tableau de construc-
teurs retourn est toujours le constructeur sans argument par
dfaut lorsque ce dernier existe. Sil nexiste pas, le construc-
teur sans argument est dfini par dfaut.
Vous pouvez aussi retrouver directement un constructeur
public individuel au lieu de rcuprer tous les construc-
teurs dun objet pour peu que vous connaissiez les types
de ses paramtres. Lexemple suivant montre comment
procder :
Class c = [Link]();
Class[] paramTypes = new Class[] {[Link]};
Constructor aCnstrct = [Link](paramTypes);
Nous obtenons un objet Constructor reprsentant le
constructeur qui prend un unique paramtre String. Les
mthodes getConstructors() et getConstructor() ne retour-
nent que les constructeurs publics. Si vous souhaitez
retrouver tous les constructeurs dune classe et notamment
ses constructeurs privs, vous devez utiliser les mthodes
getDeclaredConstructors() ou getDeclaredConstructor().
189 Dcouvrir des informations de mthode
Celles-ci se comportent comme leurs quivalents get-
Constructors() et getConstructor() mais retournent tous
les constructeurs en incluant les constructeurs privs.
Dcouvrir des informations
de mthode
La mthode getMethods() peut tre appele sur un objet
Class afin de rcuprer des informations concernant les
mthodes publiques dune classe. Elle retourne un tableau
dobjets Method, qui peuvent ensuite tre utiliss pour
retrouver le nom, le type de retour, les types de param-
tres, les modificateurs de la classe et les exceptions qui
peuvent tre leves. La mthode [Link]() peut
galement tre utilise pour appeler la mthode. Pour plus
dinformations sur linvocation des mthodes, consultez
lexemple "Invoquer des mthodes" de ce chapitre.
Class c = [Link]();
Method[] methods = [Link]();
for (int i = 0; i < [Link]; i++) {
String methodName = methods[i].getName();
[Link]("Name: " + methodName);
String returnType = methods[i].getReturnType().getName();
[Link]("Return Type: " + returnType);
Class[] paramTypes = methods[i].getParameterTypes();
[Link]("Parameter Types:");
for (int k = 0; k < [Link]; k ++) {
String paramTypeStr = paramTypes[k].getName();
[Link](" " + paramTypeStr);
}
[Link]();
}
190 CHAPITRE 16 Programmation dynamique par rflexion
Dans lexemple prcdent, une fois que nous rcuprons
le tableau de mthodes, nous le parcourons en boucle
pour imprimer le nom, le type de retour et une liste des
types de paramtres de chacune des mthodes.
Vous pouvez aussi retrouver une mthode publique indi-
viduelle au lieu de rcuprer toutes les mthodes dun
objet, pourvu que vous connaissiez son nom et les types
de ses paramtres. Lexemple suivant montre comment
procder :
Class c = [Link]();
Class[] paramTypes =
new Class[] {[Link], [Link]};
Method meth = [Link]("setValues", paramTypes);
Dans cet exemple, nous obtenons un objet Method repr-
sentant la mthode nomme setValue qui prend deux
paramtres de type String et Integer.
Les mthodes getMethods() et getMethod() dont nous
venons de traiter retournent lensemble des mthodes
publiques auxquelles il est possible daccder avec une
classe. Des mthodes quivalentes appeles getDeclared-
Methods() et getDeclaredMethod() permettent dobtenir
toutes les mthodes quel que soit leur type daccs. Elles
se comportent exactement de la mme manire mais
retournent toutes les mthodes de la classe concerne
indpendamment de leur type daccs. Il est ainsi possible
dobtenir les mthodes prives galement.
Les EDI (environnements de dveloppement intgr)
comme Eclipse incluent souvent un navigateur de classes
qui permet au dveloppeur de parcourir visuellement la
hirarchie des classes. La technique que nous venons de
prsenter est gnralement utilise pour construire ces
navigateurs de classes. Pour dvelopper un navigateur
de classes visuel, votre application doit avoir un moyen de
connatre toutes les mthodes dune classe donne.
191 Retrouver des valeurs de champ
Retrouver des valeurs de champ
Pour retrouver une valeur de champ, vous devez com-
mencer par rcuprer un objet Field pour le champ dont
vous souhaitez connatre la valeur. Pour plus dinforma-
tions sur lobtention des objets Field dune classe, consultez
lexemple "Dcouvrir des champs de classe" prcdem-
ment dans ce chapitre.
La classe Field propose des mthodes spcialises pour
rcuprer les valeurs des types primitifs, dont getInt(),
getFloat() et getByte(). Pour plus de dtails sur les
mthodes getter de lobjet Field, consultez la JavaDoc
(en anglais) ladresse suivante : [Link]
j2se/1.5.0/docs/api/java/lang/reflect/[Link].
Pour retrouver des champs stocks sous forme dobjets et
non comme des primitifs, vous devez utiliser la mthode
plus gnrale get() et transtyper le rsultat de retour sur le
type dobjet appropri. Dans cet exemple, nous obtenons
le champ nomm "title". Aprs avoir rcupr le champ
sous forme dobjet Field, nous obtenons ensuite la valeur
du champ en utilisant la mthode get() et en transtypant
le rsultat en type String.
Dans cet exemple, nous connaissions le nom du champ
dont nous souhaitions retrouver la valeur. Cette valeur
pourrait cependant tre obtenue sans mme connatre
son nom la compilation, en combinant cet exemple
avec lexemple "Dcouvrir des champs de classe" o nous
avons montr comment obtenir des noms de champs.
Cette technique pourrait par exemple tre utile dans un
outil de gnrateur dinterface utilisateur graphique qui
Class c = [Link]();
Field titleField = [Link]("title");
String titleVal = (String) [Link](anObject);
192 CHAPITRE 16 Programmation dynamique par rflexion
ncessiterait dobtenir la valeur de diffrents champs dobjets
de linterface dont les noms ne seraient pas connus avant
lexcution.
Dnir des valeurs de champ
Pour dfinir une valeur de champ, vous devez dabord
obtenir un objet Field pour le champ dont vous souhaitez
dfinir la valeur. Pour plus dinformations sur lobtention
dobjets Field partir dune classe, consultez lexemple
"Dcouvrir des champs de classe" prcdemment dans ce
chapitre. Rfrez-vous aussi lexemple "Retrouver des
valeurs de champ" pour plus dinformations sur lobtention
des valeurs de champ.
La classe Field possde des mthodes spcialises pour dfi-
nir les valeurs des types primitifs, dont setInt(), setFloat()
et setByte(). Pour plus de dtails sur les mthodes set dis-
ponibles pour lobjet Field, consultez la JavaDoc (en
anglais) ladresse : [Link]
docs/api/java/lang/reflect/[Link].
Pour positionner des champs stocks sous forme dobjets et
non sous forme de types primitifs, vous devez utiliser la
mthode set() plus gnrale en passant linstance dobjet dont
vous dfinissez les valeurs de champ et la valeur de champ
comme objet. Dans cet exemple, nous positionnons le
champ nomm "title". Aprs avoir obtenu le champ sous
forme dobjet Field, nous dfinissons sa valeur avec set(),
en passant linstance dobjet dont nous positionnons les
valeurs de champ et la nouvelle valeur pour la chane de titre.
String newTitle = "President";
Class c = [Link]();
Field titleField = [Link]("title");
[Link](someObject, newTitle);
193 Invoquer des mthodes
Pour cet exemple, nous connaissions le nom du champ
dont nous souhaitions dfinir la valeur. Il est cependant
possible de dfinir la valeur des champs dont vous ne
connaissez pas le nom la compilation, en combinant
lapproche de cet exemple avec celle de lexemple
"Dcouvrir des champs de classe" prcdemment dans ce
chapitre. Cette technique peut par exemple tre utile
pour un gnrateur dinterface utilisateur graphique avec
lequel vous devez positionner la valeur de diffrents
champs dobjet dinterface utilisateur graphique dont les
noms ne peuvent tre connus avant lexcution.
Les dbogueurs vous permettent souvent de modifier la
valeur dun champ au cours dune session de dbogage.
Pour implmenter ce type de fonctionnalit, le dve-
loppeur du programme peut utiliser la technique de cet
exemple afin de positionner la valeur des champs car il ne
peut connatre la compilation le champ dont vous sou-
haiterez positionner la valeur lexcution.
Invoquer des mthodes
LAPI Reflection permet dinvoquer de manire dyna-
mique des mthodes dont vous ne connaissez pas le nom
la compilation. Vous devez dabord obtenir un objet
Method pour la mthode invoquer. Pour plus dinforma-
tions sur lobtention des objets Method partir dune
Baseball bbObj = new Baseball();
Class c = [Link];
Class[] paramTypes = new Class[] {[Link], [Link]};
Method calcMeth = [Link]("calcBatAvg", paramTypes);
Object[] args = new Object[] {new Integer(30),
new Integer(100)};
Float result = (Float) [Link](bbObj, args);
194 CHAPITRE 16 Programmation dynamique par rflexion
classe, consultez lexemple "Dcouvrir des informations
de mthode" prcdemment dans ce chapitre.
Dans lexemple prcdent, nous tentons dinvoquer une
mthode qui calcule une moyenne de russite en baseball.
La mthode nomme calcBatAvg() prend deux param-
tres entiers, un compte des coups russis et un compte des
"prsences la batte" (at-bats). La mthode retourne une
moyenne la batte sous forme dobjet Float. Pour linvo-
quer, nous suivons ces tapes :
b Nous obtenons un objet Method associ la mthode
calcBatAvg() de lobjet Class qui reprsente la classe
Baseball.
b Nous invoquons la mthode calcBatAvg() en utilisant
la mthode invoke() de lobjet Method. La mthode
invoke() prend deux paramtres : un objet dont la classe
dclare ou hrite la mthode et un tableau de valeurs
de paramtre passer la mthode invoque. Si la
mthode est statique, le premier paramtre est ignor
et peut valoir null. Si la mthode ne prend aucun para-
mtre, le tableau darguments peut tre de longueur
nulle ou valoir null.
Dans notre exemple, nous passons une instance de lobjet
Baseball comme premier paramtre la mthode invoke()
et un tableau dobjets contenant deux valeurs entires
encapsules en second paramtre. La valeur de retour de
la mthode invoke() correspond la valeur retourne par
la mthode invoque soit ici, la valeur de retour de
calcBatAvg(). Si la mthode retourne un primitif, la
valeur est dabord encapsule dans un objet et retourne
sous forme dobjet. Si la mthode possde le type de
retour void, la valeur null est retourne. La mthode
calcBatAvg() retourne une valeur Float. Nous transty-
pons donc lobjet retourn afin den faire un objet Float.
195 Charger et instancier une classe de manire dynamique
Cette technique pourrait tre utile pour limplmentation
dun dbogueur permettant lutilisateur de slectionner
une mthode et de linvoquer. La mthode slectionne
ne pouvant tre connue avant lexcution, elle peut tre
retrouve de manire rflexive puis invoque au moyen
de cette technique.
Charger et instancier une classe
de manire dynamique
Les mthodes [Link]() et newInstance() de lobjet
Class permettent de charger et dinstancier dynamique-
ment une classe dont vous ne connaissez pas le nom
jusqu lexcution. Dans cet exemple, nous chargeons
notre classe en utilisant la mthode [Link]()
laquelle nous passons le nom de la classe charger. for-
Name() retourne un objet Class.
Nous appelons ensuite la mthode newInstance() sur
lobjet Class pour instancier une instance de la classe. La
mthode newInstance() retourne un type Object gnral
que nous transtypons dans le type attendu.
Cette technique peut tre particulirement utile si vous
avez une classe qui tend une classe de base ou impl-
mente une interface et que vous souhaitez stocker le nom
de la classe dextension ou dimplmentation dans un
fichier de configuration. Lutilisateur final peut alors ajou-
ter de manire dynamique diffrentes implmentations
sans devoir recompiler lapplication. Par exemple, si notre
Class personClass = [Link](personClassName);
Object personObject = [Link]();
Person person = (Person)personObject;
196 CHAPITRE 16 Programmation dynamique par rflexion
application incluait le code dexemple prcdent et dans
un plug-in, le code suivant, nous pourrions lamener
instancier dynamiquement un objet BusinessPerson
lexcution en spcifiant le nom de classe complet de
lobjet BusinessPerson dans un fichier de configuration.
Avant dexcuter notre exemple, nous lirions le nom de
classe depuis le fichier de configuration et attribuerions
cette valeur la variable personClassName.
public class BusinessPerson extends Person {
//Corps de la classe, tends le comportement
de la classe Person
}
Le code de lapplication ninclurait ainsi aucune rfrence
la classe BusinessPerson elle-mme. Il ne serait donc
ncessaire de coder en dur que la classe de base ou linter-
face gnrique, limplmentation spcifique pouvant tre
configure de manire dynamique lexcution en di-
tant le fichier de configuration.
17
Empaquetage
et documentation
des classes
Les applications Java sont gnralement constitues de
nombreuses classes et peuvent parfois mme en compter
des centaines ou des milliers.
Puisque le Java requiert que chaque classe publique soit
dfinie dans un fichier spar, vous aurez au moins autant
de fichiers que vous avez de classes. Ce foisonnement
peut rapidement devenir ingrable lorsquil sagit de tra-
vailler avec des classes, de retrouver des fichiers ou dins-
taller et de distribuer une application. Ce problme a
heureusement t anticip ds la cration du Java. Sun a
dfini un mcanisme dempaquetage standard permettant
de placer les classes lies dans des paquetages. Les paque-
tages utiliss en Java permettent dorganiser les classes
daprs leurs fonctionnalits. Le mcanisme dempaque-
tage organise galement les fichiers source Java en une
structure de rpertoires connue dfinie par rapport aux
noms des paquetages utiliss.
198 CHAPITRE 17 Empaquetage et documentation des classes
Un mcanisme standard en Java est aussi propos pour
empaqueter les classes Java en fichiers darchive standard.
Les applications peuvent tre excutes directement
depuis le fichier darchive et des bibliothques distribues
sous forme darchive. Le fichier darchive Java standard est
le fichier JAR, qui possde lextension .jar. Il utilise le
protocole darchivage ZIP. Les fichiers JAR peuvent tre
extraits en utilisant nimporte quel outil prenant en charge
la dcompression des archives ZIP. Sun propose ga-
lement loutil jar pour crer et dcompresser des archives
JAR. Celui-ci fait partie de la distribution JDK standard.
JAR est lacronyme de Java Archive.
Crer un paquetage
Dans les applications ou les bibliothques de grande taille,
les classes Java sorganisent gnralement sous forme de
paquetages. Pour placer une classe dans un paquetage, il
vous suffit dinclure une instruction package au dbut du
fichier de classe, comme le montre lexemple prcdent.
Linstruction package doit correspondre la premire ligne
non commente du fichier de classe. Dans notre exemple,
nous attribuons la classe contenue dans le fichier o lins-
truction figure au paquetage [Link].
Le nom du paquetage de la classe fait partie de son nom
complet. Si nous crons une classe nomme MathBook
dans le paquetage [Link], le nom com-
plet de la classe est alors [Link]-
Book. Les noms de paquetage rgissent galement la
structure des rpertoires dans lesquels les fichiers source
package [Link];
199 Crer un paquetage
des classes sont stocks. Chaque lment du nom de che-
min reprsente un rpertoire. Par exemple, si votre rper-
toire racine du code source est project/src, le code
source pour la classe MathBook est stock dans le rpertoire
suivant :
project/src/com/timothyfisher/book/
Les bibliothques Java standard sont toutes organises dans
des paquetages avec lesquels vous devez tre familiaris.
Parmi les exemples de paquetages, on peut citer [Link],
[Link] ou bien encore [Link].
Les classes stockes dans un paquetage peuvent aussi tre
importes facilement dans un fichier. Vous pouvez ainsi
importer un paquetage entier dans votre fichier source
Java avec la syntaxe suivante :
import [Link].*;
Cette instruction import importe toutes les classes conte-
nues dans le paquetage [Link]. Notez cependant
quelle nimporte pas les classes contenues dans les sous-
paquetages de [Link], comme celles contenues dans
le paquetage [Link]. Une instruction import
spare est requise pour limportation de ces classes.
Le Java 5.0 a introduit une nouvelle fonctionnalit lie
limportation des classes appele importations statiques. Les
importations statiques permettent dimporter des mem-
bres statiques de classes en leur permettant dtre utiliss
sans qualification de classe. Par exemple, pour rfrencer
la mthode cos() dans le paquetage [Link], vous
pourrez vous y rfrer de la manire suivante :
double val = [Link](90);
200 CHAPITRE 17 Empaquetage et documentation des classes
Pour cela, vous devrez importer le paquetage [Link]
.Math laide dune importation statique, comme ceci :
import static [Link].*;
Vous pouvez faire rfrence la mthode cos() de la
manire suivante :
double val = cos(90);
Lors de lexcution dune application Java depuis la ligne
de commande avec lexcutable java, vous devez inclure
le nom de paquetage complet lorsque vous spcifiez la
classe excutable principale. Par exemple, pour excuter
une mthode main() dans lexemple MathBook signal pr-
cdemment, vous devrez taper ceci :
java [Link]
Cette commande est excute depuis la racine de la struc-
ture du paquetage ici, le rpertoire parent du rpertoire
com.
Les classes qui ne sont pas spcifiquement attribues un
paquetage avec une instruction package sont considres
tres incluses dans un paquetage "par dfaut". Le bon usage
exige que vous placiez toujours vos classes dans des paque-
tages dfinis par vos soins. Les classes qui se trouvent dans
le paquetage par dfaut ne peuvent pas tre importes ni
utilises lintrieur des classes des autres paquetages.
Documenter des classes
avec JavaDoc
javadoc -d \home\html
-sourcepath \home\src
-subpackages [Link]
201 Documenter des classes avec JavaDoc
JavaDoc est un outil permettant de gnrer de la docu-
mentation dAPI au format HTML partir de commen-
taires placs dans les fichiers de code source Java. Loutil
JavaDoc fait partie intgrante de linstallation standard
du JDK.
Lexemple prsent ici illustre un type dusage particulier
de loutil JavaDoc. JavaDoc possde de nombreuses options
et de nombreux drapeaux en ligne de commande qui peu-
vent tre utiliss pour documenter des classes et des paque-
tages. Pour obtenir une description complte des options
de JavaDoc, consultez la documentation de Sun (en
anglais) ladresse [Link]
docs/guide/javadoc/[Link].
La commande javadoc utilise dans cet exemple gnre
une documentation JavaDoc pour toutes les classes conte-
nues dans le paquetage [Link] et tous ses sous-paqueta-
ges. Le code source doit se trouver dans le rpertoire
\home\src directory. La sortie de la commande est crite
dans le rpertoire \home\html.
Voici un exemple classique de commentaire JavaDoc dans
un fichier source Java :
/**
* Un commentaire dcrivant une classe ou une mthode
*
* Les balises spciales sont prcdes par le caractre @
* pour documenter les paramtres de mthode, types de
* retour, nom dauteur de mthode ou de classe, etc. Voici
* un exemple de paramtre document.
* @param input Les donnes dentre pour cette mthode.
*/
202 CHAPITRE 17 Empaquetage et documentation des classes
Les squences de caractres /** et */ signalent le dbut et
la fin dun commentaire JavaDoc.
Loutil JavaDoc produit une sortie analogue la documen-
tation de classe Java standard que vous aurez invitablement
rencontre si vous avez consult des documents Java en
ligne par le pass. Le JDK est lui-mme document avec
la documentation JavaDoc. Pour visualiser la JavaDoc du
JDK, rendez-vous ladresse suivante : [Link]
.com/j2se/1.5.0/docs/api/[Link].
La documentation gnre par JavaDoc permet de par-
courir facilement les classes qui composent une applica-
tion ou une bibliothque. Une page dindex propose une
liste de toutes les classes et des liens hypertexte vers cha-
cune dentre elles. Des index sont galement fournis pour
chaque paquetage.
La cration de la documentation JavaDoc sintgre sou-
vent au processus de gnration des applications. Si vous
utilisez loutil de compilation Ant, il existe ainsi une tche
Ant permettant de gnrer la JavaDoc dans le cadre de
votre processus de gnration et de compilation.
La technologie qui permet JavaDoc de fonctionner a
galement t utilise il y a peu pour crer dautres outils
dont les fonctionnalits sortent du simple cadre de la
documentation des fichiers Java. LAPI Doclet est ainsi
utilise par JavaDoc et des outils tiers. Lun de ces outils
tiers, parmi les plus populaires, est le projet open source
XDoclet.
XDoclet est un moteur servant la programmation orien-
te attribut. Il permet dajouter des mtadonnes votre
code source afin dautomatiser des tches telles que la
cration dEJB. Pour plus dinformations sur XDoclet,
consultez le site [Link]
203 Archiver des classes avec Jar
LAPI Taglet est une autre API utile pour le travail avec les
commentaires de style JavaDoc qui fait partie du Java stan-
dard. Elle permet de crer des programmes appels Taglets
qui peuvent modifier et formater des commentaires de style
JavaDoc contenus dans vos fichiers source. Pour plus dinfor-
mations sur les Taglets, rendez-vous ladresse [Link]
.[Link]/j2se/1.4.2/docs/tooldocs/javadoc/taglet/
[Link].
Archiver des classes avec Jar
Lutilitaire jar est inclus dans le JDK. Il permet dempa-
queter des groupes de classes en un lot et de crer, mettre
jour, extraire, lister et indexer des fichiers JAR. Avec
linstruction de cet exemple, toutes les classes contenues
dans le rpertoire courant depuis lequel la commande jar
est excute sont places dans un fichier JAR nomm
[Link].
Loption c demande lutilitaire jar de crer un nouveau
fichier darchive. Loption f est toujours suivie par un
nom de fichier spcifiant le nom du fichier JAR utiliser.
Des applications compltes peuvent tre distribues sous
forme de fichiers JAR. Elles peuvent galement tre ex-
cutes depuis le fichier JAR sans avoir les extraire au
pralable. Pour plus dinformations ce sujet, consultez
lexemple "Excuter un programme depuis un fichier
JAR" de ce chapitre.
Toutes les classes contenues dans un fichier JAR peuvent
aisment tre incluses dans le CLASSPATH lors de lexcution
jar cf [Link] *.class
204 CHAPITRE 17 Empaquetage et documentation des classes
ou de la compilation dune application ou dune biblio-
thque Java. Pour inclure le contenu dun fichier JAR
dans le CLASSPATH, incluez le chemin complet au fichier
JAR au lieu du seul rpertoire. Par exemple, linstruction
CLASSPATH pourrait ressembler ceci :
CLASSPATH=.;c:\projects\[Link];c:\projects\classes
Cette instruction inclut toutes les classes contenues dans
larchive [Link] dans le CLASSPATH. Notez bien que
pour inclure les classes dans un fichier JAR, vous devez
spcifier le nom du fichier JAR dans le chemin de classe.
Il ne suffit pas de pointer vers un rpertoire contenant
plusieurs fichiers JAR comme il est possible de le faire
avec les fichiers .class.
Pour plus dinformations sur lutilisation de loutil jar,
consultez la documentation JAR officielle sur le site de
Sun ladresse [Link]
guide/jar/[Link].
Excuter un programme
partir dun chier JAR
Lexcutable en ligne de commande java permet dex-
cuter une application Java empaquete dans un fichier
JAR. Pour cela, vous devez utiliser le commutateur jar
lexcution de la commande java. Vous devez aussi
spcifier le nom du fichier JAR contenant lapplication
excuter.
La classe contenant la mthode main() que vous souhaitez
excuter doit tre dclare dans un fichier de manifeste.
java jar [Link]
205 Excuter un programme partir dun fichier JAR
Par exemple, pour excuter la classe [Link]-
[Link], vous pourriez utiliser un fichier de
manifeste dont le contenu serait le suivant :
Manifest-Version: 1.2
Main-Class: [Link]
Created-By: 1.4 (Sun Microsystems Inc.)
Ce fichier de manifeste devrait alors tre plac dans le
fichier JAR avec vos classes.
Cette fonctionnalit permet aux dveloppeurs Java de dis-
tribuer une application dans un unique fichier JAR et
dinclure un fichier de script comme un fichier BAT
Windows ou un script de shell UNIX qui peuvent tre
utiliss pour lancer lapplication laide dune instruction
analogue celle prsente dans cet exemple.
Index
A
abs() 70
abstract 182
accept() 104, 122
add() 48
adjust() 172
Ant 7
Apache
Ant 7
Jakarta RegExp 56
Log4J 81
Tomcat 129
API
DocumentBuilder 157
DOM 162
JavaMail 131
JAXP 154
JDBC 141
JDOM 162
Reflection 180
SAX 155
Taglet 203
append() 24
appendChild() 162
appendReplacement() 62
appendTail() 62
Archives
JAR 89, 198, 203, 204
ZIP 89, 91, 198
arraycopy() 32
ArrayList 32, 36, 38
Arrays 36
Arrondissement 71
Attributs
de fichier 97
Element 162
XML 155
B
Bases de donnes
JDBC 142
jeux de rsultats 148
BCC 134
before() 51
binarySearch() 38
Boolean 68
Boucles 33
for 22
parcours de collections 34
while 24, 91, 169
BufferedInputStream 113
BufferedOutputStream 115
BufferedReader 64, 80, 86, 111,
128
BufferedWriter 86
Byte 67
Bytecode 5
I
N
D
E
X
208 Calendar
C
Calendar 42, 84
conversion avec Date 42
proprits 51
CallableStatement 149
Caractres
casse 25, 59
expressions rgulires 57
nouvelle ligne 65
CASE_INSENSITIVE 59
catch 69, 110
CC 134
Chanes 17
comparer 18
convertir la casse 25
date 44
expressions rgulires 55
parser en dates 47
rechercher 21
remplacer 61
renverser 23
retrouver une portion 58
spares par des virgules 27
tokenizer 28
validit comme nombre 68
Champs 186
retrouver des valeurs 191
Character 68
characters() 156
charAt() 22
checkAccept() 122
Chemins
de classe 9, 203
relatifs et absolus 101
Class 181, 189, 195
Classes 14
ArrayList 32, 36, 38
Arrays 36
BufferedInputStream 113
BufferedOutputStream 115
BufferedReader 64
Calendar 42, 84
champs 186
chargement dynamique 195
Class 181
Collections 37
Comparator 36
Connection 144
DataInputStream 113
DataOutputStream 115
Date 42
dcouvrir des constructeurs 187
DefaultHandler 155
Document 157
documentation 197
DocumentBuilder 157
DocumentBuilderFactory 157
empaquetage 197
File 94
FilenameFilter 104
Folder 139
Formatter 82
Handler 126
HashMap 35, 40
HttpURLConnection 118, 119
InetAddress 109
instanciation dynamique 195
interfaces implmentes 185
InternetAddress 133
IOException 79
Iterator 34
Matcher 56
Math 67, 71, 75, 77
MimeBodyPart 135
MimeMessage 134
MimeMultiPart 135
I
N
D
E
X
209 currentTimeMillis()
modificateurs 182
MultiPart 135
Object 35
ObjectInputStream 116
OutputStream 73
OutputStreamWriter 124
PrintStream 73
PrintWriter 112
Properties 133
Random 75
RandomAccessFile 89
regPat 58
Scanner 25
ServerSocket 122
SimpleDateFormat 44
Socket 108
Stack 24
String 17, 83
StringBuffer 18, 23, 24
StringBuilder 18
StringReader 23
StringTokenizer 24, 27, 56
TextComponent 181
TextField 181
Thread 126
ThreadGroup 176
TreeMap 37
TreeSet 37
trouver des superclasses 183
URL 108
ZipEntry 90
ClassesPattern 56
CLASSPATH 9, 203
close() 89, 108, 123, 144
closeEntry() 91
Code-octet_ 5
collection 34
Collections 32, 37
convertir en tableau 40
mappes 35
parcourir en boucle 33
retrouver un objet 38
stocker 36
Commandes
java 8
javac 7
javadoc 201
Comparable 36
Comparaisons
chanes 18
dates 51
nombres virgule flottante 69
tolrance 70
Comparator 36
compareTo() 20, 51
compareToIgnoreCase() 20
Compilation 7
compile() 58
ConnectException 110
Connection 144
Constructeurs 187
contains() 38
containsKey() 38
containsValue() 38
Content-length 129
Conversions
Date et Calendar 42
nombre entier en binaire, octal
et hexadcimal 75
cos() 76
createNewFile() 94
createStatement() 144
createTempFile() 94
CSV 27
currentThread() 176
currentTimeMillis() 52
I
N
D
E
X
210 DataInputStream
D
DataInputStream 113
DataOutputStream 115
DataSource 144
Date 42
conversion avec
Calendar 42
Date() 42
Dates 41
additions et soustractions 48
codes de format 45
comparer 51
diffrence 49
formater 44
nanosecondes 53
parser 47
valeur courante 42
DAY_OF_WEEK 51
DefaultHandler 155
DELETE 145
delete() 96
deleteOnExit() 95, 97
Devises 74
Dictionnaires 33
Document 157
Documentation 197
DateFormat 47
Formatter 73
Jakarta 56
JavaDoc 201
JDK 7
StringTokenizer 29
DocumentBuilder 157
DocumentBuilderFactory 157, 159
DOM 157
Dossiers 93
afficher le contenu 103
crer 106
dplacer 99
renommer 95
supprimer 96
vrifier lexistence 99
Double 68
doWait 174
Drapeaux
boolens 168
CASE_INSENSITIVE 59
doWait 174
JavaDoc 201
MULTILINE 65
Pattern 60
DriverManager 143
DTD 159
E
Eclipse 5, 190
Ecriture
donnes binaires 114
donnes srialises 117
EDI 5, 190
EJB 108, 141
E-mails 131
envoyer 133
lire 137
MIME 135
empty() 24
endElement() 156
endsWith() 104
Ensembles 33
I
N
D
E
X
211 Flux
Entre
BufferedInputStream 113
BufferedReader 86, 111, 128
DataInputStream 113
donnes binaires 88
donnes srialises 115
InputStream 87
lire 80
ObjectInputStream 116
[Link] 80
texte 111
entries() 89
Entry 33
entrySet() 33, 40
Environnement 12
Epoque UNIX 48
equals() 18, 50, 69
equalsIgnoreCase() 18, 80
Erreurs 65
rseau 110
[Link] 80
Exceptions
ConnectException 110
FileNotFoundException 65
IOException 79, 110
NoRouteToHostException 110
NumberFormatException 69
SecurityException 122
SocketException 110
[Link] 80
UnknownHostException 110
executeQuery() 144, 145
executeUpdate() 145
Excution 8
exists() 99
Expressions rgulires 55
caractres spciaux 57
nouvelle ligne 65
regPat 58
F
Fichiers 93
atteindre une position 89
close() 89
crer 94
dplacer 99
entries() 89
JAR 9, 198, 204
mkdirs() 106
modifier des attributs 97
ouvrir 86
RandomAccessFile 89
renommer 95
supprimer 95, 96
taille 98
temporaires 94
vrifier lexistence 99
ZIP 198
Field 191
File 94, 102
mkdir() 106
FilenameFilter 104
FileNotFoundException 65
final 182
find() 58
Float 68
flush() 112
Flux
binaire 88
BufferedInputStream 113
BufferedOutputStream 115
BufferedReader 111, 128
DataInputStream 113
InputStream 87
ObjectInputStream 116
ObjectOutputStream 125
StreamSource 164
I
N
D
E
X
212 Folder
[Link] 80
[Link] 80
[Link] 80
ZipOutputStream 91
Folder 139
for 22
format() 44, 72, 83, 112
Formatage
devises 74
Locale 82
nombres 72
sortie 81
spcificateurs de
format 84
Formatter 82
codes 85
forName() 143, 181, 195
Frameworks
Collections 32
EJB 141
JAF 132
FRANCE 82
G
getAbsoluteFile() 101
getByName() 109
getByte() 191
getClass() 181, 182
getConnection() 143, 144
getConstructor() 188
getConstructors() 187, 188
getContent() 118
getCurrencyInstance() 74
getDateInstance() 47
getDeclaredConstructor() 188
getDeclaredConstructors() 188
getDeclaredField() 187
getDeclaredFields() 187
getDeclaredMethod() 190
getDeclaredMethods() 190
getDefaultInstance() 138
getElementsByTagName() 158
getenv() 12
getField() 187
getFields() 186, 187
getFloat() 191
getHostAddress() 109, 122
getInetAddress() 122
getInputStream() 111, 113, 116,
118
getInstance() 42, 48, 51, 83
getInt() 191
getInterfaces() 185
getKey() 33
getMessage() 110
getMethod() 190
getMethods() 189, 190
getModifiers() 182
getMoreResults() 150
getName() 182, 185, 189
getNumberInstance() 72
getOutputStream() 112
getParameterTypes() 187
getParent() 176
getPort() 122
getProperties() 13
getProperty() 13
getResponseCode() 119
getReturnType() 189
getSuperclass() 181, 183
getThreadGroup() 176
getTime() 42
getValue() 33
GMT 48
group() 58
I
N
D
E
X
213 JANUARY
H
Handler 126
hashCode() 36
HashMap 35
convertir en tableau 40
hasMoreElements() 89
hasMoreTokens() 24, 27
hasNext() 33, 34
Heures 41
codes de format 45
Hibernate 142
HTML 153
HTTP 107, 128
en-ttes 129
https 119
HttpURLConnection 118, 119
I
IANA 137
if 69
IMAP 132, 138
import 199
indexOf() 21, 38
InetAddress 109
InitialContext 144
InputStream 87
Instructions
catch 69, 110
if 69
import 199
prpares 146
try 69
Integer 67
Interfaces
CallableStatement 149
Comparable 36
dune classe 185
isInterface() 183
[Link] 116
[Link] 116, 125
[Link] 166
[Link] 166
Runnable 126, 166
InternetAddress 133
Inversion de chanes 23
invoke() 189
IOException 79, 110
IP 109
isAbstract() 183
isDirectory() 89, 102
isFinal() 183
isInterface() 183
isNative() 183
isPrivate() 183
isProtected() 183
isPublic() 183
isStatic() 183
isStrict() 183
isSynchronized() 183
isTransient() 183
isVolatile() 183
Iterator 34
iterator() 33, 34
J
J2EE 108
J2SE 6
JAF 132
JANUARY 83
I
N
D
E
X
214 JAR
JAR 9, 198, 203, 204
lire 89
Java
classes 14
servlets 129
types prdfinis 67
java 8
[Link] 73, 79
[Link] 116
[Link] 116, 125
[Link] 77, 179
[Link] 67, 199
[Link] 179
[Link] 183
[Link] 166
[Link] 166, 181
[Link] 108
[Link] 72
[Link] 33, 34, 37, 42, 75, 79
[Link] 81, 199
[Link] 133
[Link] 56
javac 7
JavaDoc 201
JavaMail 131
[Link] 131, 134
[Link] 135
[Link] 163
JAXP 154
JCP 162
JDBC 141, 142, 144
JdbcOdbcDriver 142
JDK 7
javac 7
versions
1.4 56, 131
1.5 35, 53, 73, 82
JDOM 162
JMS 108
JNDI 144
join() 169
Journalisation 81
JSP 129
JSSE 120
K
keySet() 33
L
Lecture
donnes binaires 113
donnes srialises 115
e-mails 137
page Web 118
texte 111
length 32
length() 87, 98
LIFO 25
list 33
list() 103, 139
Listes 33
Locale 82
log() 77
log10() 77
Log4J 81
Long 67
long 87
I
N
D
E
X
215 Mthodes
M
Machine virtuelle 8
Macintosh 12
main() 14
Majuscules 25
Mapping objet/relationnel 142
Matcher 56
matcher() 58
Math 71, 75, 77
fonctions trigonomtriques 76
Message 133
Method 189
Mthodes
abs() 70
accept() 104, 122
add() 48
adjust() 172
append() 24
appendChild() 162
appendReplacement() 62
appendTail() 62
arraycopy() 32
before() 51
binarySearch() 38
characters() 156
charAt() 22
checkAccept() 122
close() 89, 108, 123, 144
closeEntry() 91
compareTo() 20, 51
compareToIgnoreCase() 20
compile() 58
contains() 38
containsKey() 38
containsValue() 38
cos() 76
createNewFile() 94
createStatement() 144
createTempFile() 94
currentThread() 176
currentTimeMillis() 52
Date() 42
dcouvrir par rflexion 189
delete() 96
deleteOnExit() 95, 97
empty() 24
endElement() 156
endsWith() 104
entries() 89
entrySet() 33, 40
equals 18
equals() 50, 69
equalsIgnoreCase() 18, 80
executeQuery() 144, 145
executeUpdate() 145
exists() 99
find() 58
flush() 112
format() 44, 72, 83, 112
forName() 143, 181, 195
getAbsoluteFile() 101
getByName() 109
getByte() 191
getClass() 181, 182
getConnection() 143, 144
getConstructor() 188
getConstructors() 187, 188
getContent() 118
getCurrencyInstance() 74
getDateInstance() 47
getDeclaredConstructor() 188
getDeclaredConstructors() 188
getDeclaredField() 187
getDeclaredFields() 187
I
N
D
E
X
216 Mthodes
Mthodes (suite)
getDeclaredMethod() 190
getDeclaredMethods() 190
getDefaultInstance() 138
getElementsByTagName() 158
getenv() 12
getField() 187
getFields() 186, 187
getFloat() 191
getHostAddress() 109, 122
getInetAddress() 122
getInputStream() 111, 113,
116, 118
getInstance() 42, 48, 51, 83
getInt() 191
getInterfaces() 185
getKey() 33
getMessage() 110
getMethod() 190
getMethods() 189, 190
getModifiers() 182
getMoreResults() 150
getName() 182, 185, 189
getNumberInstance() 72
getOutputStream() 112
getParameterTypes() 187
getParent() 176
getPort() 122
getProperties() 13
getProperty() 13
getResponseCode() 119
getReturnType() 189
getSuperclass() 181, 183
getThreadGroup() 176
getTime() 42
getValue() 33
group() 58
hashCode() 36
hasMoreElements() 89
hasMoreTokens() 24, 27
hasNext() 33, 34
indexOf() 21, 38
invoke() 189
invoquer 193
isAbstract() 183
isDirectory() 89, 102
isFinal() 183
isInterface() 183
isNative() 183
isPrivate() 183
isProtected() 183
isPublic() 183
isStatic() 183
isStrict() 183
isSynchronized() 183
isTransient() 183
isVolatile() 183
iterator() 33, 34
join() 169
keySet() 33
length() 87, 98
list() 103, 139
log() 77
log10() 77
main() 14
matcher() 58
mkdir() 106
mkdirs() 106
nanoTime() 53
newInstance() 188, 195
newTranformer() 164
next() 33, 34, 148
nextDouble() 75
nextElement() 24, 89
nextInt() 75
nextToken() 27
I
N
D
E
X
217 Mthodes
Notify() 175
openConnection() 119
parse() 47, 155
parseInt() 68
pop() 24
prepareCall() 149
prepareStatement() 146
printf() 112
println 20
println() 112
printThreadInfo() 177
put() 35
putNextEntry() 91
random() 75
read() 23, 87, 88, 113
readBoolean() 114
readByte() 114
readChar() 114
readDouble() 114
readFloat() 114
readInt() 114
readLine() 80, 111
readLong() 114
readObject() 116
readShort() 114
readUnsignedByte() 113
readUnsignedShort() 114
renameTo() 95, 100
replaceAll() 61
reset() 172
resume() 175
reverse() 23
round() 71
run() 127, 166
seek() 89
send() 133
setArray() 146
setAsciiStream() 146
setBigDecimal() 146
setBinaryStream() 146
setBlob() 146
setBoolean() 146
setByte() 146
setBytes() 146
setCharacterStream() 146
setClob() 146
setContent() 136
setContentHandler() 155
setDate() 146
setDouble() 146
setFloat() 146
setInt() 146
setLastModified() 97
setLong() 146
setNull() 146
setObject() 146
setProperty() 13
setReadOnly() 97
setRef() 147
setSchema() 160
setShort() 147
setString() 147
setText() 136
setTime() 147
setTimestamp() 147
setURL() 147
setValidating() 159, 160
SimpleDateFormat() 44
sin() 76
sort() 36
split() 27
start() 126, 166
startElement() 156
stop() 169
StringBuffer() 62
substring() 22
suspend() 175
tan() 76
I
N
D
E
X
218 Mthodes
Mthodes (suite)
toArray() 40
toBinaryString() 75
toHexString() 75
toLowerCase() 104
toOctalString() 75
toString() 23, 42, 82
transform() 164
trim() 26
valueOf() 47
values() 33
visitGroup() 177
wait() 175
write() 114, 115, 123
writeBoolean() 115, 123
writeByte() 115, 123
writeBytes() 115, 123
writeChar() 115, 123
writeChars() 115, 123
writeDouble() 115, 123
writeFloat() 115, 123
writeInt() 115, 123
writeLong() 115, 123
writeObject() 125
writeShort() 115, 123
MIME 134
MimeBodyPart 135
MimeMessage 134
MimeMultiPart 135
Minuscules 25
mkdir() 106
mkdirs() 106
Modificateurs 182
abstract 182
final 182
public 182
MONTH 51
MULTILINE 65
MultiPart 135
N
NaN 70
nanoTime() 53
newInstance() 188, 195
newTranformer() 164
next() 33, 34, 148
nextDouble() 75
nextElement() 24, 89
nextInt() 75
nextToken() 27
Nombres 67
arrondir 71
chane valide 68
convertir en binaire, octal et
hexadcimal 75
formater 72
virgule flottante 69
NoRouteToHostException 110
Notify() 175
NumberFormat 72
NumberFormatException 69
O
Object 35
ObjectInputStream 116
ObjectOutputStream 125
Objets
ArrayList 32, 36, 38
Arrays 36
Boolean 68
BufferedInputStream 113
BufferedOutputStream 115
BufferedReader 64, 80, 86, 128
BufferedWriter 86
Byte 67
I
N
D
E
X
219 OutputStreamWriter
Calendar 42, 84
Character 68
Class 181, 189, 195
collection 34
Collections 37
Comparator 36
DataInputStream 113
DataOutputStream 115
DataSource 144
Date 42
DocumentBuilderFactory 159
Double 68
DriverManager 143
Field 191
File 94, 102
FilenameFilter 104
Float 68
Handler 126
HashMap 35, 40
HttpURLConnection 118, 119
InitialContext 144
InputStream 87
Integer 67
InternetAddress 133
Iterator 34
list 33
Long 67
Matcher 56
Message 133
Method 189
MimeBodyPart 135
NumberFormat 72
Object 35
ObjectInputStream 116
ObjectOutputStream 125
OutputStream 73
OutputStreamWriter 124
Pattern 56
PreparedStatement 146
PrintStream 73
PrintWriter 112
Properties 133
RandomAccessFile 89
regPat 58
ResultSet 144, 145, 148
SAXParser 155
ServerSocket 122
Session 133
set 33
Short 67
SimpleDateFormat 44
Socket 108
Stack 24
Statement 144, 145
Store 138
StreamSource 164
String 17, 83
StringBuffer 18, 23, 24
StringBuilder 18
StringReader 23
StringTokenizer 24, 27, 56
System 13
Thread 126
ThreadGroup 176
TranformerFactory 164
Transformer 164
TreeMap 37
TreeSet 37
XMLReader 155
ZipEntry 90, 91
ZipOutputStream 91
openConnection() 119
Options
_classpath 9
javac 7
JavaDoc 201
purge automatique 124
scurit Java 94
OutputStream 73
OutputStreamWriter 124
I
N
D
E
X
220 Paquetages
P
Paquetages
crer 198
Jakarta RegExp 56
[Link] 73, 79
[Link] 77, 179
[Link] 67, 199
[Link] 179
[Link] 183
[Link] 181
[Link] 108
[Link] 72
[Link] 33, 34, 37, 42, 75, 79
[Link] 199
[Link] 56
[Link] 131, 134
[Link] 135
[Link] 163
parse() 47, 155
parseInt() 68
PATH 12
Pattern 56
proprits 59
PI 82
Piles 24
POP 107
pop() 24
POP3 132, 138
prepareCall() 149
PreparedStatement 146
prepareStatement() 146
printf() 112
println() 20, 112
PrintStream 73
printThreadInfo() 177
PrintWriter 112
Procdures stockes 149
Programmes
compiler 7
excuter 8
[Link] 203
Properties 133
Proprits
CASE_INSENSITIVE 59
DAY_OF_WEEK 51
Entry 33
FRANCE 82
JANUARY 83
length 32
MONTH 51
MULTILINE 65
systme 13
timezone 13
UNICODE_CASE 60
WEEK_OF_YEAR 51
YEAR 51
public 182
put() 35
putNextEntry() 91
R
random() 75
RandomAccessFile 89
read() 23, 87, 88, 113
readBoolean() 114
readByte() 114
readChar() 114
readDouble() 114
readFloat() 114
readInt() 114
readLine() 80, 111
readLong() 114
readObject() 116
readShort() 114
I
N
D
E
X
221 setProperty()
readUnsignedByte() 113
readUnsignedShort() 114
Reflection 180
Rflexion 179
champs 186, 191
constructeurs 187
interfaces 185
mthodes 189
RegExp 56
Rgionalisation 82
regPat 58
renameTo() 95, 100
Rpertoires 93
afficher le contenu 103
crer 106
dplacer 99
renommer 95
supprimer 96
vrifier lexistence 99
replaceAll() 61
Rseau
clients 107
erreurs 110
retrouver des adresses IP 109
reset() 172
ResultSet 144, 145, 148
resume() 175
reverse() 23
round() 71
run() 127, 166
Runnable 126, 166
S
SAX 155
SAXInputSources 157
startElement() 156
SAXInputSources 157
SAXParser 155
Scanner 25
Schmas 160
SecurityException 122
seek() 89
SELECT 144, 148
send() 133
serialVersionUID 116
ServerSocket 122
Serveurs 121
contacter 108
contenu HTTP 128
crer 122
retourner un objet 125
retourner une rponse 123
Tomcat 129
Servlets 129
Session 133
set 33
setArray() 146
setAsciiStream() 146
setBigDecimal() 146
setBinaryStream() 146
setBlob() 146
setBoolean() 146
setByte() 146
setBytes() 146
setCharacterStream() 146
setClob() 146
setContent() 136
setContentHandler() 155
setDate() 146
setDouble() 146
setFloat() 146
setInt() 146
setLastModified() 97
setNull() 146
setObject() 146
setProperty() 13
I
N
D
E
X
222 setReadOnly()
setReadOnly() 97
setRef() 147
setSchema() 160
setShort() 147
setString() 147
setText() 136
setTime() 147
setTimestamp() 147
setURL() 147
setValidating() 159, 160
SGML 153
Short 67
SimpleDateFormat() 44
sin() 76
SMTP 107, 132
SocketException 110
Sockets 108, 122
exceptions 110
fermer 123
sort() 36
Sortie 112
BufferedOutputStream 115
BufferedWriter 86
donnes binaires 114
donnes srialises 117
crire 80
formater 81
ObjectOutputStream 125
[Link] 80
Sous-chanes 21, 58
Spcificateurs de format 84
split() 27
SQL
DELETE 145
SELECT 144, 148
UPDATE 145
SSL 119
Stack() 24
start() 126, 166
startElement() 156
Statement 144, 145
stop() 169
Store 138
StreamSource 164
String 17, 83
StringBuffer() 18, 23, 24, 62
StringBuilder 18
StringReader 23
StringTokenizer 24, 27, 56
Structures 31
substring() 22
Sun 6
Superclasses 183
suspend() 175
Synchronisation des threads 171
synchronized 171
System 13
[Link] 80
[Link] 80
[Link] 80
T
Tableaux
crer partir dune
collection 40
doctets 87
longueur 32
redimensionner 32
Taglet 203
tan() 76
TextComponent 181
Texte
caractres de nouvelle ligne 65
crire 112
crire vers une sortie
standard 80
I
N
D
E
X
223 writeChars()
[Link] 72
lire 111
dans un tableau doctets 87
depuis une entre standard 80
remplacer 61
retrouver 58
TextField 181
Thread 126
ThreadGroup 176
Threads 165
arrter 168
lancer 166
lister 176
suspendre 174
synchroniser 171
timezone 13
TO 134
toArray() 40
toBinaryString() 75
toHexString() 75
Tokenizer 28
Tolrance 70
toLowerCase() 104
Tomcat 129
toOctalString() 75
toString() 23, 42, 82
TranformerFactory 164
transform() 164
Transformer 164
TreeMap 37
TreeSet 37
trim() 26
try 69
U
UNICODE_CASE 60
UNIX 48
UnknownHostException 110
UPDATE 145
URL 108
V
valueOf() 47
values() 33
Variables
CLASSPATH 9
d'environnement 12
Macintosh 12
PATH 12
visitGroup() 177
void 37
W
wait() 175
WebLogic 143
WebSphere 143
WEEK_OF_YEAR 51
while 24, 91, 169
write() 114, 115, 123
writeBoolean() 115, 123
writeByte() 115, 123
writeBytes() 115, 123
writeChar() 115, 123
writeChars() 115, 123
I
N
D
E
X
224 writeDouble()
writeDouble() 115, 123
writeFloat() 115, 123
writeInt() 115, 123
writeLong() 115, 123
writeObject() 125
writeShort() 115, 123
X
XBNF 160
XDoclet 202
XHTML 153
XML 153
DOM 157
DTD 159
parser avec SAX 155
schmas 160
setSchema() 160
startElement() 156
transformations XSL 164
XBNF 160
XMLReader 155
XSL 163
XSLT 163
XStream 125
Y
YEAR 51
Z
ZIP 198
crer 90
lire 89
ZipEntry 90, 91
ZipOutputStream 91
Timothy Fisher
J
a
v
a
L
E
G
U
I
D
E
D
E
S
U
R
V
I
E
Fisher
LE GUI DE DE SURVI E
J ava
LESSENTIEL DU CODE ET DES COMMANDES
Ce Guide de sur vie vous livre tout le code dont vous avez
besoin pour raliser rapidement et efcacement vos projets
de dveloppement en J ava.
CONCIS ET MANIABLE
Facile transporter, facile utiliser nis les livres
encombrants !
PRATIQUE ET FONCTIONNEL
Plus de 100 fragments de code personnalisables
pour programmer du J ava fonctionnel dans toutes les
situations.
Timot hy Fisher est un professionnel du dveloppement de
logiciels J ava depuis 1997. Il est actuellement consultant
pour lentreprise Compuware Corporation Dtroit dans le
Michigan. Il aime crire sur cette technologie et a contribu
aux deux ouvrages Java Developer s Journal et XML Journal.
Tim est galement passionn par lducation et lutilisation
des technologies Internet avances dans ce domaine.
Niveau : Int ermdiaire
Cat gorie : Programmat ion
Con gurat ion : Mult iplat e-forme
LE GUI DE DE SURVI E
LESSENTIEL DU CODE ET DES COMMANDES
J ava