Vous êtes sur la page 1sur 50

Dvelopper des applications avec le langage Java

15 juin 1999

Table des matires

Prsentation du langage

1.1 Introduction
Le langage

jv

a fait une entre spectaculaire dans le monde du dvelop-

pement logiciel en 1995. Il combinait des options dj popularises par certains


de ces concurrents (l'orientation objet) , et des caractristiques particulirement
adaptes aux autres tendances dominantes du moment (Internet).

1.2 Philosophie
1.2.1 Un langage orient objet
L'orientation objet s'est progressivement impose comme technologie de dveloppement, laissant esprer dans la conception des applications:
 plus de rutilisation (du code, mais aussi de l'architecture)
 une plus grande ractivit au changement
 un moindre cot de maintenance

gCC et mlllk . jv
gCC en ce qui concerne le

Les langages orients objets les mieux connus taient


occupe une position intermdiaire, plus proche de

style de programmation. Nous verrons les principes de la programmation objet


un peu plus loin, mais la notion essentielle est celle de classe, qui dnit le
comportement des variables du langage, appels objets, et un programme

jv

est un ensemble de dnition de classes.

1.2.2 Un langage interprt


jv

est un langage compil, la compilation produisant un pseudocode des-

tin tre interprt par une machine virtuelle, habituellement dsigne sous
le nom de JVM. Les spcications prcises tant du peudocode que du modle
d'excution de la JVM font partie intgrante des spcications du langage.

1.2.3 Un langage multi-plateformes


Les spcications ci-dessus tant indpendantes de tout environnement physique, le premier bnce est la portabilit: en principe, une application crite

et

compile dans un environnement peut tre excute dans n'importe quel autre.
Bien sr quelques prcautions sont prendre:
 Un constructeur peut respecter les spcications de la machine virtuelle
tout en introduisant des extensions. Si une application tire partie de ces
extensions, elle ne pourra fonctionner que dans les environnement les implmentant.
 Un programme raliste doit procder avec le monde extrieur (le systme
chier, l'interface utilisateur, les bases de donnes). Les concepteurs du
langage ont fait de leur mieux pour rendre portable cet interfaage, mais
il n'est pas toujours possible de cacher le problme au dveloppeur qui
a besoin des fonctionnalits spciques d'un environnement.
 Un seul langage n'tant pas toujours susant pour toutes les applications,
certains programmes peuvent devoir utiliser l 'ouverture de

jv

pour

appeler des fonctions extrieures ( native). Ceci bien sr rend le dveloppeur


responsable de la portabilit correspondante.
Malgr ces rserves, la portabilit est nettement suprieure celle du

g, or celle-

ci, bien que plus imparfaite, tait dj assez bonne pour tre un des facteurs de
son succs. La portabilit de

jv

est donc

trs

satisfaisante.

1.2.4 Un environnement d'excution complet


La machine virtuelle est prolonge par une bibliothque de classes trs complte qui non seulement acclre le dveloppement des applications mais joue un
rle important dans leur portabilit. Ces classes sont regroupes en packages.

1.3 java et Internet


En plus des bnces dcrits dans les paragraphes prcdents, la structure
du pseudocode est telle qu'il est possible pour la machine virtuelle de requrir
des lments compils (les

Flss ), en fonction des besoins, auprs de n'importe

quelle source. Ceci est videmment trs adapt au Web, et a donn naissance
la notion d'applet, mini-applications pouvant fonctionner dans un browser sans
que l'utilisateur ait eu se procupper de leur installation, et qui ont t l'un
des principaux facteurs de l'explosion mdiatique de

jv,

mme si l'intrt du

langage est trs loin de s'y limiter.

1.4 Le march
La popularit de

jv

a atteint des sommets littralement inous pour un

langage de programmation: le grand public peut voir son nom dans tous les

media! De faon plus concrte pour son succs industriel, beaucoup d'entreprises
s'y sont intresses:
 Du point de vue du style de dveloppement, il remplit un crneau non
encore occup dans la gamme des langages orients objet (il reste proche
de

gCC,

dont le succs, mesur en nombre de developpeurs, est suprieur

celui de concurrents comme

mlllk ),

et nous verrons qu'il protge

le dveloppeur des dicults de plus bas niveau rencontres dans

gCC.

 Ses possibilits d'adaptation des environnements rpartis, bass sur des


composants, sont immdiates.
 La notion de langage interprt suscite toujours des inquitudes en ce
qui concerne les performances. S'il est vrai qu'une excution interprte
ne peut pas rivaliser avec l'excution de code machine, les machines virtuelles sont libres, une fois le pseudocode charg et vri, de le traduire en
language machine pour l'excution ultrieure. Ce mcanisme, connu sous
le nom de compilation Just In Time a beaucoup fait pour ddramatiser
le problme.

L'orientation ob jet

2.1 Les principes gnraux


Les 4 principaux mots magiques de la programmation objet sont: l'encapsulation l'abstraction, l'hritage, et le polymorphisme.
L'encapsulation: au lieu de s'intresser principalement aux procdures, le
dveloppement objet cherche regrouper un ensemble de donnes et de fonctions
qui peuvent leur tre appliques. L'ensemble de ces donnes (attributs) et de
ces fonctions (mthodes) constitue un objet, et, si le langage est typ, est dcrit
dans un type qu'on appelle une classe.
La combinaison de l'encapsulation et de l'abstraction conduit ne prsenter
aux utilisateurs d'une telle classe que les mthodes d'intrt public, les protgeant des dtails de la ralisation, et de leur volution.
L'hritage dsigne la possibilit de construire de nouvelles classes en s'appuyant sur des classes existantes: la nouvelle classe (drive), hrite des attributs
et des mthodes de l'ancienne (base).
Le polymorphisme dsigne la possibilit d'crire une seule fois du code qui
pourra s'appliquer des objets dirents, en excutant des mthodes direntes,
mais avec la mme signication. Il existe plusieurs formes de polymorphisme,
certaines sans rapport avec l'orientation objet, mais la plus importante est ralise travers l'hritage, en autorisant la classe drive

rednir

certaines

mthodes de la classe de base. La dirence entre l'hritage seul et l'hritage


combin avec le polymorphisme est peu prs la mme qu'entre une mobylette
et une moto de course, ne pas oublier qu'une moto de course peut tre trs dangereuse si elle est mal utilise! D'une part l'hritage peut tre utilis  tort,
quand par exemple un objet devrait simplement possder une rfrence d'un

autre type dont il a besoin, d'autre part tant qu'un langage ne comporte pas
des assertions smantiques (elles ont envisages pour

jv), la phrase ci-dessus

avec la mme signication reste incontrlable.

2.2 Elements de langage, classes et objets.


La notion de base est celle de la classe, qui est en quelque sorte un gabarit
de cration d'objets. Ce gabarit est utilis pour crer des instances d'objets.
Un objet ayant en gnral besoin d'tre initialis, il est possible de dnir des
pseudo-mthodes d'initialisation, appeles usuellement constructeurs, qui sont
automatiquement excutes au moment de l'instantiation. Des mthodes seront
ensuite invoques sur les objets instantis.
Outre les attributs et proprits (nous parlerons de membres) dcrits cidessus, qui sont associs des instances spciques d'objet , une classe peut
aussi possder des membres qui ne sont pas lis un objet particulier, appels
attributs ou mthodes de classe. Dans certains cas il est possible et intressant de dnir des classes qui ne sont mme pas destines tre intancies, et
contiennent un ensemble de mthodes qui ressemblent des fonctions traditionnelles dguises, mais nanmoins rgroupes logiquement. Ces classes sont
souvent dsignes sous le nom de classes utilits.
Les langages objet possdent gnralement une notion de protection, c-ad que seuls certains membres d'une classe, dits publics, sont destines tre
exposes au code extrieur la classe, les autres, dits privs, tant rserv son
propre usage, des ns d'implmentation. On trouve parfois une graduation
plus ne que les seuls niveaux publics et privs (c'est le cas de

jv

et de

gCC),

et la notion de protection s'applique souvent aussi aux classes elles-mmes. Il


est en gnral dconseill d'exposer directement des attributs comme publics,
souvent le monde extrieur n'a pas besoin d'tre conscient de leur existence, et
mme s'il doit l'tre, il est prfrable de dnir une ou deux mthodes, appeles
accesseurs, pour lire et/ou modier leur valeur.
Si le langage est hybride, une notion plus traditionelle de fonction peut
coexister avec les lments purement objets.

2.3 La position de java


Comment se positionne

jv

dans la gamme des langages orients objet? Si

l'on considre les deux langages les mieux connus:




gCC

est un langage hybride (il y a de nombreux types primitifs, on peut

crire du code

g,

c'est dire une sorte d'assembleur structur!), et forte-

ment typ.


jv

mlllk

est une langage pur, non typ.

occupe une position intermdiaire:

 Il est hybride, mais beaucoup moins que

gCC: il y a toujours des types pri-

mitifs (numriques+ hr +void ), mais le dveloppeur ne peut rien dnir

qui soit en dehors d'une classe, toute classe dnie par l'utilisateur drive
d'une classe prdnie ( Objet).
 Il est aussi fortement typ que
Par ailleurs,

gCC

jv s'est appuy sur une syntaxe trs proche de celle du gCC, aprs

avoir limin les complexits les plus redoutables, au prix bien sr de se priver
de certaines possibilits.

2.4 Le Garbage Collector


Instantier un objet signie le crer, ce qui pose le problme du cycle de vie
et de sa destruction. Les langages objets pargnent en gnral la gestion de
cette destruction au dveloppeur.

jv

est dans ce cas, contraitement

gCC

qui, pour satisfaire les besoins en performance d'une partie de son march,
laisse au dveloppeur le soin de spcier allocation et dallocation. Le Garbage
Collection a longtemps eu trs mauvaise rputation, cause de certaines implmentations de Lisp o l'excution de cette phase provoquait des pauses

trs

perceptibles dans l'excution des applications. La banalisation du multithread,


en permettant d'excuter ce nettoyage en parallle, a encore une fois ddramatis le problme. Il reste que combiner Garbage Collection et Temps Rel est,
sinon impossible, tout au moins dlicat.

Les programmes

java

3.1 Les environnements de dveloppement


3.1.1 Le jdk
Le produit de base est le  Java Development Toolkit  de Sun. Il contient
une implmentation de rfrence de la machine virtuelle, les librairies fondamentales ncessaires son fonctionnement, un compilateur, et quelques outils
supplmentaires. Il n'y a pas d'outil de dveloppement visuel, bien que le  Bean
Development Toolkit  contienne, lui, un tel outil, en la personne de la beanbox.
Il n'y a malheureusement pas non plus, pour l'instant, de debugger digne de ce
nom.

3.1.2 Les environnements intgrs


Beaucoup de constructeurs proposent des environnements intgrs avec debugger, dveloppement visuel, etc... Les plus connus sont:
 Visual J++ de Microsoft
 JBuilder d'Imprise (ex Borland)
 VisualAge for Java d'IBM
 Visual Cafe de Symantec
 Kawa de Tek-Tools

3.2 L'architecture des programmes java


3.2.1 Structure logique, classes et packages
Si

jv

comporte des types primitifs, il reste un langage objet plutt pur,

car le dveloppeur ne peut dnir que des classes. Le composant de base est donc
la classe. Les classes peuvent, nous l'avons dit tre regroupes en packages. les
packages jouent deux rles:
1. Ils reprsentent un espace de nommage, analogue au

nmespe

de

gCC.

Ceci vite entre autres les collisions de noms entre fournisseurs de composants.
2. Ils fournissent un niveau particulier de protection: il y a en
en

gCC,

jv,

comme

3 niveaux explicites de protection:

privte : uniquement pour un membre, ou une classe intrieure, seule


la classe englobante peut y faire rfrence

proteted : similaire, mais l'accs est autorise galement aux classes


drives de la classe englobante

puli :

membres ou classes, accs autoris pour tous

Mais contrairement

gCC, en l'absence de qualicateur explicite, le dfaut

n'est pas un de ces 3 niveaux, mais un 4me, le niveau package, c--d


accs autoris toutes les classes du mme package.
Une classe est spcie comme appartenant un package en prxant son code
par la syntaxe:

pkge testY
ou

pkge omFomgFgorY
Comme on le voit dans ce dernier exemple, les packages peuvent tre imbriqus.
Une classe sans spcication de 

pkge 

est considre appartenir un pa-

ckage global au nom vide. Les packages (non vides) font partie intgrante du
nom de la classe, ainsi dans

pkge testY
puli lss fenhmrk {FFF}
le nom complet de la classe est

testFfenhmrk .

Une rfrence depuis le code

d'une classe une classe appartenant un autre package doit normalement


spcier ce nom complet. On peut s'en dispenser avec la directive d'
ainsi, dans

kge testY
import frmeworkFBY
6

import :

puli lss fenhmrk {


FFF
epplition ppanew epplition@AY
FFF
}
epplition
que le package

frmeworkFepplition (il est dconseill


test contienne aussi une classe appele epplition !). On aurait

peut faire rfrence

pu obtenir le mme rsultat, de faon plus conomique, et plus sre, avec:

kge testY
import frmeworkFepplitionY
puli lss fenhmrk {
FFF
epplition ppanew epplition@AY
FFF
}

3.2.2 Structure physique, les chiers


L'unit de pseudo-code sera donc le code compil dnissant totalement
une classe. Le nom du chier est le nom exact de la classe suivi du suxe
 Flss . L'architecture des sources est presque aussi simple: un source java

doit contenir au plus la dnition d'une classe publique, et le nom du chier


doit alors tre le nom exact de cette classe suivi du suxe 

Fjv .

Une classe

peut avoir besoin de classes auxiliaires prives, celles-ci peuvent tre dnies
dans le mme chier source, mme si elles donneront lieu une unit de code
compil indpendante. D'autre part, depuis jdk1.1, on peut dnir des classes
intrieures une autre classe. Pour le code compil d'une classe appartenant
un package, les segments du nom du package sont traduits non pas directement
dans le nom de chier mais par des sous-rpertoires successifs. Ainsi le code
compil de la classe

testFfenhmrk

devra se trouver dans un chier dont la

spcication sera de la forme:

xxx testfenhmrkFlss
Bien qu'il soit souhaitable de respecter une cohrence identique pour les sources,
aucune contrainte n'est impose sur celles-ci, ni par la spcication, ni par les
outils.

3.2.3 La compilation
Dans le cas du jdk, la compilation est excute en lanant depuis la ligne de
commande l'utilitaire

jv .

La syntaxe est:

jv [options] fichier Fjv

Les options les plus utilises sont:




Elsspth

suivi d'une liste de rpertoires o rechercher les classes rf-

rences par le source compil, spars par des 


des  X sous Unix.


Ed

Y

sous Windows ou par

suivi de la spcication du rpertoire o crire le code compil

Si la classe appartient un package, l'argument de

Ed

sera la racine relative du

rpertoire eectif, c-a-d que:

jv Ed gXdevlsses enhmrkFjv
produira (en supposant que nous soyons dans le rpertoire o se trouve le source
de la classe

testFfenhmrk )

le chier:

gXdevlssestestfenhmrkFlss
lsspth est interprt de la mme faon, et si fenhmrk
frmeworkFepplition dont le compil se trouve dans:

rfrence la classe

gXdevlssesfrmeworkepplitionFlss
l'argument de

Elsspth

devra contenir, entre autres,

gXdevlsses

3.2.4 L'excution et les machines virtuelles


Le code compil est excut par la machine virtuelle. Quand une nouvelle
classe est requise (par exemple, parce qu'elle est rfrence par une classe dj
charge. Nous verrons plus loin comment la premire classe est charge), la machine virtuelle charge le code en mmoire puis excute des oprations regroupes
en 3 phases:
1. Vrication:
 Contrler que le bloc charg commence bien par le mot magique qui
identie les classes

jv

compiles

 Contrler que le code compil ne comporte que des bytecode lgaux


 Contrler que tout branchement dbouche bien sur un dbut d'instruction
 bien d'autres choses...
2. Prparation: principalement cration des variables de classes et leur aectation avec les valeurs par dfaut ou des valeurs initiales spcies tant
qu'elles sont dtermines la compilation
3. Rsolution: localiser les classes rfrences symboliquement et les charger.
Cette phase peut-tre retarde jusqu'au moment o une classe donne est
absolument ncessaire.
Quand la machine virtuelle est lance explicitement, par exemple depuis la ligne
de commande, elle accepte une option

Elsspth

lateur.

identique celle du compi-

3.2.5 Applications, applets , servlets


Une application autonome doit possder un point d'entre standard, sous la
forme d'une classe publique, possdant une mthode publique de classe dont le
nom est

min.

Plus prcisment l'en-tte de cette mthode (sa signature) doit

tre:

puli stti void min@tring rgA


stti signie que c'est une mthode de classe et pas une mthode d'instance,
void signale qu'elle ne renvoie aucun rsultat, et @tring rgA qu'elle reoit
comme un argument un tableau de chanes de caractres. Si une application est
lance par:

jv pilegopy input output


pilegopyFmin recevra comme argument un tableau de 2 chanes de caractres:
{ input  D output  }.
Une telle application est excute en lanant l'excutable de la machine
virtuelle avec le nom de la classe en argument. Certains environnements d'excution fournissent une application cadre ( framework ), qui gre des composants,
qui n'ont donc pas besoin d'un

min@A

propre, mais dont la responsibilit est

d'exporter d'autres mthodes. Les deux cas les plus frquemment rencontrs
sont:
 L'environnement d'excution d' applets au sein d'un navigateur web. Les
applets sont des classes

jv

qui enrichissent le contenu de pages web,

et qui doivent possder certaines mthodes d'initialisation, de lancement,


de suspension et de terminaison. Ce sont normalement des composants
graphiques qui doivent donc ragir des vnements, et se reprsenter
dans la page. L' excution d'un applet est dclenche par le chargement
dans le navigateur d'une page html contenant un rfrence cet applet .
 l'environnement d'excution de servlets au sein d'un serveur web. Les servlets sont des classes java qui permettent de gnrer, en rponse des requtes en provenance d'un navigateur lointain, des pages web dynamiques,
et qui doivent possder des mthodes de traitement de requtes

HTTP.

L'excution d'un servlet est dclenche par la rception par le serveur d'une
requte dont l' url rfrence ce servlet.

3.3 Les packages de base


Un certain nombre de packages font partie de la spcication du langage. La
liste suivante n'est pas exhaustive:
 Les packages noyau: bien qu'ils soient spars pour des raisons logiques,
chacun de ces packages fait rfrence aux autres, et ne pourrait fonctionner
sans eux, mme si la spcication


jvFlng

jv

l'autorisait:

C'est le seul package qui n'ait jamais besoin d'tre im-

port. Il contient entre autres la class

yjet ,

les classes

tring

et

tringfuffer

ixeption . Il contient aussi


ystem , celle-ci est une classe utilit, ne contenant

dj rencontres, la classe

la classe utilitaire

que des membres de classe, et en particulier s'appuie sur le package

jvFio , par exemple pour fournir l'quivalent de stdout et stderr.


jvFutil Un package d'intrt trs gnral, mais contenant des
classes moins systme : la trs utilise classe etor se trouve ici.
Ce ne sont pas des classes utilits, util signiant ici utilitaire, ce
qui possde (malheureusement) un sens dirent sous une apparence
proche!

jvFio

Le package de base d'accs aux entres-sorties (chiers, ter-

minaux).


jvFwt

Le package initial pour la programmation des GUI. Un des

points les plus remanis de

jv depuis sa sortie
jvxFswing .

( juste titre!), il est

maintenant conseill d'utiliser







jvFpplet Le package de dnition des applets .


jvFnet Le package pour la programmation de rseau.
jvFens le package des composants jv.
jvFseurity Le package de la scurit: signature, encryption, politique
de scurit. En fait bien que ce package puisse tre ignor dans un premier
temps par le dveloppeur applicatif, c'est absolument un package noyau,
et les 3 premiers packages y font rfrence.

En principe, les packages dont la racine est 

jv

sont ceux qui font partie des

spcications du langage, et ceux dont la racne est 


Nanmoins

jvx

jvxFswing

jvx 

sont des extensions.

fait partie intgrante de jdk1.2, et son inclusion dans

est base sur ce que l'on appelle en gnral pudiquement des raisons

socio-historiques.

Elments de base du langage

4.1 Elments lexicaux


Le jeu de caractres utilis pour l'criture des programmes est l'Unicode, qui
tend les codes ASCII pour y inclure tous les caractres nationaux de tous les
pays. Les caractres accentus sont typiquement accepts comme lettres dans
la dnition des identicateurs. Ceci signie qu'un dveloppeur Franais qui le
dsire peut dclarer des variables comme rsultat. En thorie ceci est aussi vrai
pour les noms de classe, mais ces noms ayant des consquences sur les noms de
chier, les environnements et les outils peuvent mal ragir de tels noms, et la
prudence est encore conseille.

4.2 Types, valeurs, et variables


jv

est un langage fortement typ, ce qui veut dire que toute variable doit

tre dclare et type avant qu'on puisse y faire rfrence, et que toute expression

10

possde un type dterminable la compilation.


Les types rentrent dans trois catgories:
1. Les types primitifs:
 Les types intgraux signs:





yte sur 8 bits (attention, en gGgCC , yte est souvent unsigned hr)
short sur 16 bits
int sur 32 bits
long sur 64 bits
unsigned

Le modicateur

jv.

n'existe pas en

Les valeurs de ces

types, et leurs constantes littrales, sont celles du

gCC

sur les ma-

chines o les tailles concident. Le fait que la taille de ces types soit
justement , en

jv,

indpendante de l'environnement, s'il peut tre

un blocage rhdibitoire pour les dveloppeurs qui

doivent

coller la

machine, est un immense soulagement pour tous les autres!




hr

un entier non sign sur 16 bits, reprsentant un code Unicode

Les valeurs et constantes littrales sont, cette fois, un sur-ensemble


du

gCC,

l'Unicode ajoutant les squences:

9uxxxx 9
o

xxxx

reprsente 4 chirs hexadcimaux.

 Les types ottants IEEE signs


 oat sur 32 bits
 double sur 64 bits


oolen

reprsentant une valeur de vrit, et dont les valeurs pos-

sibles sont


void

true

ou

flse

qui est un type sans valeur!

2. Les types qui rfrencent une classe.


Si l'on a une dclaration:

gr HY
en supposant que Car soit une classe dnie dans un package courant ou
import, sa signication est que l'identicateur o1 est une variable qui
dnote un objet de type Car. L'instruction:

HaIY
ne signie pas que

est cre, mais que

est modi en quoi que ce soit, ni qu'une copie de

dnote maintenant le mme objet que

I.

Si

est modiable, ce sera par:




HFattribute avalue Y

en admettant que

attribut de classe modiable

11

gr

possde au moins un

HFmodifyingMethod @AY

gr

en admettant que

possde au moins

une mthode modiante


Si

est pass en argument une mthode:

puli void use@gr rA {FFF}


par l'instruction

xxxFuse@HAY
ce n'est pas une copie qui est transmise, mais bien une rfrence partage
sur l'objet initial, et si la mthode appele modie cet objet ci-dessus,
ces modications seront visibles travers

H.

Par contre, si la mthode

excute

ranothergrY
H

n'est pas touch. Noter que, les types primitifs ne possdant ni m-

thodes ni attributs, ils ne peuvent tre modis en tant passs comme


argument. On dit quelquefois que les valeurs primitves sont passes par
valeur, alors que les objets sont passs par rfrence. En fait, en

tous les arguments

sont

toujours

passs

par valeur ,

jv,

mais les valeurs qui

dnotent des objets sont elles-mme des rfrences!


Nous verrons d'autre part, avec l'hritage, que dans le cas de la dclaration
 gr

HY , l'excution, H peut rfrencer un objet d'un type plus riche


gr.
Les types obtenus partir d'un autre type par l'adjonction de   , c'estque

3.

-dire les types tableaux.


En ralit un type tableau est une classe, que son type de base soit primitif ou non, gnr automatiquement par le systme compilateur/machine
virtuelle. Le type ne spcie pas la dimension d'un tableau, mais un tableau existant ne peut modier cette dimension: il possde un attribut

length

qui se comporte exactement comme une variable membre d'ins-

tance dclare

finl .

Les lments individuels du tableau sont accds

par la syntaxe:

rryi
la machine virtuelle vriant que la valeur de

est compatible avec la

dimension du tableau, et ils peuvent tre modis:

rryianewelementY
Les tableaux multi-dimensionnels sont raliss comme des tableaux de
tableaux.

12

Le type chane de caractres n'apparat pas explicitement: en eet ce n'est pas


un type primitif, mais une classe prdnie,

tring ,

laquelle le compilateur

rserve un traitement spcial: en eet les constantes littrales de ce type ont


la mme forme qu'en

gGgCC

( rello

orld3 ,  Xwinnt ),

l'oprateur

est

surcharg de son sens usuel numrique pour exprimer la concatnation, tous


les autres types sont susceptibles d'une conversion en

tring

qui peut tre

dclenche implicitement, par exemple quand une expression de ce type est un


oprande de la concatnation. Un objet de type

tring

ne peut jamais tre

modie: en eet les seuls membres d'instance non privs sont des mthodes
non modiantes. Les mthodes dont le nom semble modiant gnre en fait
de nouvelles chanes Dans le code suivant:

tring unixtha expression Y


tring winthaunixthFreple@99D9G9AY
unixth

est inchang. Pour avoir l'quivalent d'un tableau de caractres modi-

ables, on doit utiliser la classe

tringfuffer , qui est l'quivalent d'un hr


tringfuffer

dont la dimension serait modiable. On peut convertir aisment un


en

tring

et vice-versa.

4.3 Les dclarations


4.3.1 Les variables
Les dclarations de variable se trouvent aussi bien dans le corps qu'une
mthode que directement l'intrieur d'une classe.Une dclaration est toujours
de la forme:

type identificateur [ a valeur_initiale] Y


ce qui est beaucoup plus simple que la syntaxe correspondante en

gGgCC . L'initia-

lisation est optionelle, son absence impose certaines contraintes. Une dclaration
peut concerner:
1. Une variable membre
(a) d'instance
(b) de classe, la dclaration ci-dessus est alors prcde du mot-clef

stti

2. Une variable locale


Les consquences de l'absence d'initialisateur dans la dclaration varient suivant
les cas. Dans les cas 1, une valeur par dfaut est aecte. Cette valeur est
 Pour les types numriques, le 

hr)
Pour un oolen , flse

H

du type concern (par exemple,

9uHHHH9

pour

 Pour un type rfrnce sur un object, y compris un type tableau,


qui signie que la variable ne rfrence aucun objet

13

null,

Dans le cas 2, aucune valeur par dfaut n'est aecte, mais le compilateur exige
de pouvoir se convaincre que la variable recevra une valeur avant toute utilisation.
Une variable peut aussi tre qualie de

finl ,

ce qui signie qu'elle ne doit

prendre qu'une seule valeur au cours de son cycle de vie. L plus encore, en
l'absence d'initialisation, les exigences du systme sont variables:
 Dans le cas 2, le mcanisme est le mme que pour les variables non

finl ,

mais bien sr en outre le compilateur refuse toute autre aectation


 Dans le cas 1(b), une initialisation est exige (mais le message d'erreur de

jv

est un peu confus)

 Dans le cas 1(a), les valeurs par dfaut ne sont pas utilises,

teur

tout construc-

doit comporter une aectation ce membre, bien sr avant tout

usage, et non suivie d'une autre.


Du point de vue du style, c'est--dire de la lisibilit et de la maintenance du
code, il est toujours avantageux si cela est possible de ne dclarer une variable
locale que quand elle peut recevoir une initialisation signicative. Dans certains
cas, nanmoins, l'initialisation doit tre ralise dans des branches conditionnelles, et le compilateur garantit que le dveloppeur ne pourra pas oublier un
cas. Le traitement des variables

finl

membres d'instance est particulirement

intressant, car il permet de dclarer des attributs non modiables dont la valeur
dpend nanmoins des arguments du constructeur.

4.3.2 Les mthodes


La dclaration d'une mthode prend la forme:

return-type methodName @argument-list A optional-throws-clause {


methodBody
}
o:

returnEtype

est ou bien le type de l'expression renvoye par l'excution de la

mthode, ou bien

rgumentElist

void.

est une liste de dclarations sans qualicateurs ni initialisateurs

spare par des virgules, qui dcrit les arguments attendus par la mthode.
Cette liste peut tre vide.

optionlEthrowsEluse

a, si elle est prsente, la forme

throws exeptionElist ,

nous reviendrons plus tard sur les exceptions et cette clause.

methodfody

est une liste d'instructions (voir la dnition d'une instruction plus

loin) qui ne peut tre vide que si

return-type

void,
return
return-type .

est identique

sinon tout chemin d'excution doit se terminer par une instruction


renvoyant une expression dont le type est compatible avec

14

4.4 Les expressions


4.4.1 Structure des expressions
jv, et, jusqu' un certain point, leur signicagCC. Une expression est compose partir des lments

La syntaxe des expressions


tion, est trs voisine du
suivants:

1. Les constantes littrales. Il en existe de type


(a)
(b)
(c)
(d)
(e)
(f )
(g)

int: H, EIHH, IPQRSTUVWH


long: Hv, EIHHv , IPQRSTUVWIPQRSTUVWHv
hr: 99, 9n9, 9', 9, 99D 'uHQeW9
flot : Hf, QFIRf , ETFHPPeCISf
doule : HF, QFIR, IeIQU
oolen : flse et true
tring , bien que ce ne soit pas un type primitif:

 ,  rello  ,  ynenwo  .

En outre le compilateur transformera la concatnation de deux constantes


littrales de type

tringX

tring msga  rello  C orld3  Y


sera compil exactement comme

tring msga  rello orld3  Y


2. Les variables. Ce sont des identicateurs reconnus comme dnis et valides
dans le bloc d'instructions courant en tant que (certains cas font rfrence
des notions dcrites plus loin):
(a) Une variable locale, introduite par une dnition normale ou
(b) Une variable introduite par l'initialisation d'une instruction

for

en

cours d'excution.
(c) Un argument de la mthode ou du constructeur en cours d'excution.
(d) L'identicateur li l'exception en cours de traitement si un bloc de
traitement d'exception est en cours d'excution.
(e) Une variable membre d'instance de

thisD

si la mthode en cours

d'excution est une mthode d'instance ou un constructeur.


(f ) Une variable membre de classe de la classe dont une mthode (d'instance ou de classe) ou un constructeur est en cours d'excution.
Les cas (a) (d) sont en fait des variantes de variables locales, c'est--dire
des variables dont la dure de vie n'est pa s lie celle d'une instance ou
d'une classe, mais la dure d'excution d'un bloc de code. En
variable locale ne peut

jamais

jv,

une

en cacher une autre, c'est--dire rednir

une autre variable locale de mme nom qui serait visible au point de la
nouvelle dnition.

15

3. Les oprateurs :
(a) unaires:

CC, EE, C, E, , 3
gGgCC , CC et EE

Comme en

existent en prx et en postx

(b) binaires, groups par prcdence:

B, G, 7
CD E
de shift: `#`, b#b, `#`#`D b#b#b
de comparaison: `D `a , bD ba
d'galit: aaD 3a
de manipulation binaire: 8, |D
logiques: 88D || ,

i. multiplicatifs:
ii. additifs:
iii.
iv.
v.
vi.
vii.

(c) ternaire:

cond c expr0 X expr1

4. Les oprations lies au transtypage


(a) Les conversions:

@type Aexpr
expr instneof referenceType

(b) La comparaison de type:


5. Les aectations:

a, et op aD op

tant un des oprateurs binaires dnis en

(b)i, (b)ii, (b)iii, ou (b)vi.


6. L'oprateur d'accs un lment d'un tableau, concrtis par 
7. L'oprateur d'accs un attribut, concrtis par 
(a)
(b)

 : expr index

F :

expr FattrName
referenceType FattrName

8. Les invocations de mthodes:


(a)
(b)

expr FmethName @arguments A


referenceType FmethName @arguments A

9. Les instantiations d'objet:

new class @arguments A

En dehors de leurs utilisations syntaxiques explicites (conversions, dclarations


et invocations de mthode, instructions de boucle, traitements d'exceptions) les
parenthses sont utilises pour grouper des sous-expressions, soit par lisibilit,
soit pour imposer une signication dirente de celle implique par les prcdences par dfaut. Par exemple:

BxCy
a la mme signication que

@BxACy
16

et non pas la mme que

C@xByA
Contrairement

gGgCC ,  D

n'est

jamais

un oprateur, il intervient uniquement

comme sparateur, dans les cas suivants (certains font rfrence des notions
dnies dans des sections ultrieures):
 entre plusieurs variables dclares simultanment
 entre les paramtres formels d'une dclaration de mthode ou de constructeur
 entre les argments passs lors d'une invocation de mthode ou d'une instantiation d'objet
 entre plusieurs interfaces hrits par un mme interface ou une mme
classe
 entre plusieurs exceptions dclares leves dans une dclaration de mthode
 entre plusieurs instructions-expressions dans le code d'initialisation ou
d'itration d'une instruction

for.

4.4.2 Remarques sur les expressions


1. L'aectation exige que le membre gauche soit ce qu'on appelle an anblais
une lvalue, c'est--dire une expression dnotant non pas simplement une
valeur, mais une location o une valeur peut tre conserve. Les lvalue
en java sont:
(a) les variables, locales, ou membres de classe ou d'instances.
(b) Une expression d'accs un attribut de classe.
(c) Une expression d'accs un attribut d'instance dont le membre
gauche est une lvalue.
(d) Une expression d'accs un lment de tableau dont le membre
gauche est une lvalue.
En outre, pour tre aectable:
(a) une lvalue ne doit pas tre une variable

finl

ayant dj t initiali-

se.
(b) le type du membre droit doit tre compatible avec celui du membre
gauche (c'est--dire tre susceptible d'une conversion implicite dans
celui-ci, voir plus loin des remarques additionnelles sur ce que signie
la compatibilit pour les types primitifs)
(c) le membre gauche doit aussi satisfaire toutes les conditions d'accessibilit, mais ceci n'est pas une condition lie l'oprateur d'affectation, mais intrinsque toute expression.

17

2. Les oprateurs

CC

et

EE

sont considrer comme des oprateurs d'aec-

tation.
3. Nous avons dcrit plus haut quelles taient les conversions explicites et implicites valides entre types rfrence. Bien que les types primitifs se situent
en dehors de l'orientation objet, d'une certaine faon le type
extension du type

short .

int

est une

Un type numrique sera gnralement conver-

tible implicitement en un type plus tendu, une conversion explicite tant


ncessaire dans le sens inverse. Il n'y a aucune conversion entre les types

oolen

numriques et le type
en

flse ).

(pas plus que

null

ne peut tre converti

Attention: contrairement ce qu'on pourrait penser, il existe

des cas o une conversion implicite peut amener une perte silencieuse de
prcision:

int iaIPQRSTUVWHY
flot faiY
flot n'a pas susamment de prcision pour conserver tous les chires
i. Le mme problme se pose en aectant un long un
doule .
Un

signicatifs de

4. Une consquence de l'application stricte des rgles qui prcdent est que
la dernire instruction du bloc suivant gnre une erreur de compilation:

short saPY
int iaQY
short taiBsY
En eet, la division est comprise comme 

iB@intAs , puisqu'il s'agit d'une

conversion implicite acceptable, et l'instruction cherche alors aecter


un

int

un

short ,

ce qui exige une conversion explicite. Des formes

acceptes, ayant un sens dirent, mais, dans ce cas, le mme rsultat,


sont:

short ta@shortA@iBsAY
ou

short ta@shortAiBsY
Le compilateur admet une exception cetter rgle pour les aectations de
constantes calculables la compilation, ce qui est bien agrable car il n'y
a pas de constantes lexicales entires en dessous de l'

int.

Par exemple:

short saIY
est lgal, sans ncessiter 

@shortAI .

Cette exception ne concerne

aectations: si une mthode attend un argument de type


lui passer  @shortAI .

18

short ,

que

les

il faudra

5. Comme nous l'avons dj vu, les conversions implicites des type primitifs

vers

le type

tring

sont une exception ces rgles. Elles sont en

particulier dclenches par l'oprateur binaire

considr comme opra-

teur de concatnation, ce qui est dj une interprtation particulire du


compilateur.
6. Si les oprateurs de divison entire peuvent lever une
en cas de division par

H,

erithmetiixeption

ce n'est pas le cas des oprations ottantes, qui

utilisent les notions IEEE d'innit et de NAN (NotANumber ), et ne provoquent jamais d'exception.

4.5 Les instructions


Une fois encore, la syntaxe s'appuie sur le

gGgCC .

Elles peuvent tre re-

groupes en deux catgories, les instructions composes, qui peuvent contenir d'autres instructions , et les instructions simples, qui ne peuvent pas. Par
ailleurs, toute instruction peut optionellement tre prcde d'une tiquette,
sous la forme:

identificateur X
instruction
le sparateur de ligne n'tant pas obligatoire.

4.5.1 Instruction simples


Les instructions simples doivent toutes tre termines par un 

Y,

que nous

ne rpterons pas dans leur description. Ce sont:


1. L'instruction vide: sans commentaires.
2. L'instruction-expression: l'expression est value pour son eet de bord,
ce sera une aectation (y compris l'valuation des oprateurs

CC

et

EE),

une invocation de mthode, ou une instantiation d'objet. Le compilateur


rejetera toute autre expression.
3. L'instruction de retour de mthode. Deux formes:
(a)
(b)

return si la mthode n'a pas de type de retour


return expr si la mthode a un type de retour

(autre que

void)

dclar.
4. L'instruction

rek : sortie d'une instruction compose. Le mot-clef rek

peut optionnellement tre suivi d'un identicateur qui doit tre celui d'une
tiquette d'une instruction compose englobant l'instruction courante. Si
cette tiquette est spcie, elle identie l'instruction cible. Sinon, l'instruction cible est l'instruction compose de type boucle (

do)

ou

swith

for, while ,

ou

(voir plus loin leurs descriptions) la plus intrieure englo-

bant l'instruction courante. Si aucune instruction cible n'est identie le


compilateur rejetera le

rek .

Sinon l'eet est de transfrer le contrle

19

d'excution l'instruction suivant immdiatement l'instruction cible (ce


peut tre une instruction

return

implicite la n d'une mthode sans

type de retour).
5. L'instruction

ontinue :

enchanement de boucle. Le mot-clef

ontinue

peut optionnellement tre suivi d'un identicateur qui doit tre celui d'une
tiquette d'une instruction compose englobant l'instruction courante. Si
cette tiquette est spcie

tion de boucle ,

et si l'instruction identie est une instruc-

elle identie l'instruction cible. Sinon, l'instruction ci-

ble est l'instruction compose de type boucle la plus intrieure englobant


l'instruction courante. Si aucune instruction cible n'est identie le compilateur rejetera le

ontinue .

Sinon l'eet est de transfrer le contrle

d'excution au point de l'instruction de boucle qui enchane sur l'itration


suivante.
6. L'instruction

throw :

sa syntaxe est:

throw exceptionExpr
exceptionExpr devant s'valuer comme une instance drive de hrowle
(normalement ixeption ), et son eet est de lever l'exception en question,
et de transfrer abruptement le contrle d'excution au premier point de
code appelant ayant dclar traiter une exception de ce type (voir plus
loin l'instruction

try).

4.5.2 Instructions composes


1. Le bloc: la syntaxe du bloc est une liste d'instructions encadres par 
et  }. Cette liste peut tre vide, 

{}

{

est donc une instruction compose

lgale de type bloc.

synhronized@expr A.
expr doit s'valuer comme une rfrence non null un objet. Si expr possde un type primitif, le compilateur rejetera l'expression. Sinon, et si expr
s'value comme null , une exception sera leve l'excution

2. Le bloc synchronis: la syntaxe est celle du bloc prcde de 

3. L'instruction conditionnelle: sa syntaxe est:

if @booleanExpr A yesStatement [ else noStatement]


yesStatement et noStatement
partie else tant optionnelle.

tant des instructions quelconques, et la

4. L'instruction de branchement: sa syntaxe consiste en l'encadrement par


 swith@exprA

{

et  } d'une suite d 'tiquettes de choix et d'instruc-

tions, une tiquette de choix tant soit:

defultX
soit:

se constantExpr X
20

Cette forme est soumise certaines contraintes:




expr doit tre d'un type intgral autre que long.


constantExpr doivent tre dtermines au moment
lation et aectables au type de expr .

 les

de la compi-

 deux tiquettes de choix dans la mme instruction de branchement


ne peuvent pas tre identiques

exp r

A l'excution de cette instruction,

est value et une des tiquettes

est choisie en fonction de sa valeur . Si cette valeur ne corrrespond


aucun des  se

FFFX 

et si l'tiquette

defult

n'est pas prsente, le

contrle est transfr l'instruction suivant l'instruction de branchement.


Sinon le contrle est transfr l'instruction prcde par l'tiquette. Cette
instruction est certes utile, mais avant mme de ne pas tre oriente objet,
elle est aussi peu compatible avec la programmation structure. C'est en
fait un hritage quasi-direct de l'assembleur!
5. L'instruction de traitement d'exception. Sa syntaxe est:

try tryBlock
th@ExceptionClass id A handlerBlock
FFF
[ finlly finalBlock]
block

reprsentant une instruction de type bloc, les 

la clause

th

peut tre rpte, et les 

[] 

FFF

signiant que

signiant que la clause

finlly est optionelle (en ralit un tel bloc peut aussi comporter une
clause finlly sans aucune clause th ). Les ExceptionClass doivent
tre des types rfrences drivs de hrowle . A l'excution:
(a)

tryBlock

est excut.

(b) Si une exception est leve et non traite l'intrieur de cette excu-

tion, et si son type est compatible avec l' ExceptionClass d'une ou


plusieurs clauses

th :

i. le contrle est transfr au


clause,

id

handlerBlock

de la premire telle

rfrenant l'objet exception qui a t lev.

ii. si l'excution de ce bloc lve une nouvelle exception, elle est propage vers les niveaux suprieurs
(c) Si aucune clause ne satisfait la condition prcdente, l'exception originelle est propage vers les niveaux suprieurs.
(d) Si une clause
i.

finlly

est prsente, dans tous les cas :

finalBlock est excut


du handlerBlock

aprs terminaison du

mainBlock

et/ou

ii. si cette excution lve une exception, elle est propage vers les
niveaux suprieurs, remplaant ventuellement l'expression mentionne en (b)ii ou (c).

21

6. L'instruction

for:

la syntaxe en est:

for @[init] Y[booleanExpr] Y[next] A statement


statement tant une instruction, les  []  indiquant un caractre optionnel, init tant soit une dclaration de variable locale avec initialisation,
soit une liste d'instructions-expressions spares par des virgules, next
tant une liste d'instructions-expressions spares par des virgules. L'excution de l'instruction

for

se dcompose ainsi:

(a) Initialisation:
i. Si

init

est une dclaration de variable, elle est excute, la por-

te de la variable tant le reste des composants du


ii. Sinon, la ou les instructions composant

init

for.

sont excutes dans

l'ordre.
(b) Itration:

booleanExpr est prsent et si son valuation renvoie flse ,


for est termine
Sinon, statement est excut, la ou les instructions composant
next sont excutes dans l'ordre, et une autre itration est en-

i. Si

l'instruction

ii.

tame.
7. L'instruction

while :

la syntaxe en est:

while @booleanExpr A statement


L'excution ne comporte qu'une phase, l'itration:
(a) Si l'valuation de

booleanExpr

renvoie

flse ,

l'instruction

while

est termine
(b) Sinon,

statement

8. L'instruction

do:

est excut, et une autre itration est entame.

la syntaxe en est:

do statement while @booleanExpr A Y


ce qui en fait la seule instruction compose se terminer par un 

Y.

L'excution ne comporte qu'une phase, l'itration:


(a)

statement

est excut

(b) Si l'valuation de

booleanExpr

renvoie

flse ,

termine, sinon une autre itration est entame

22

l'instruction

do

est

Les classes de java

5.1 Dnition de base


Au minimum, la dnition d'une classe prend la forme:

lss glssxme {
GG dlrtion des memres
}
les membres tant des variables ou des mthodes, d'instance ou de classe, et
des constructeurs. La dclaration d'un membre de classe est identie en tant
prcde du qualicateur

stti (Depuis jdk1.1, un membre peut galement tre

une classe intrieure). Nous savons dj que la classe peut tre optionellement
dclare

puli . La dclaration de chaque membre peut aussi tre prcde d'un


puli , proteted , ou privte .

qualicateur de protection,

5.2 Attributs
La dclaration d'une variable membre est identique la dclaration d'une

finl , applicable galement aux vastti , applicable galement tous les membres

variable locale. En dehors du qualicateur


riables locales, du qualicateur

l'exclusion des constructeurs, et des qualicateurs de protection, applicables


galement tous les membres, deux qualicateurs sont rservs aux attributs:



trnsient , li la srialisation
voltile , li la concurrencr

5.3 Mthodes
Les mthodes sont, en
qu'on ne peut

rien

jv,

la seule forme des fonctions. On a dj vu

dnir en dehors d'une classe, mais on ne peut pas non

plus dnir de fonctions locales au corps d'une mthode. Si l'on a besoin de


fonctions n'tant pas associes un objet possdant un tat (c'est--dire un
ensemble d'attributs) propre, ces fonctions seront dnies comme mthodes de
classe d'une classe correspondant leur fonctionnalit.
Plusieurs mthodes d'une mme classe peuvent avoir le mme nom si le
nombre ou les types de leurs arguments sont dirents.

types de retour n'est pas susante!


pseudo-variable

this

La seule dirence des

Dans le code d'une mthode d'instance, la

est automatiquement dnie par le compilateur, et dnote

l'objet sur lequel la mthode a t invoque.

5.4 Constructeurs
Un constructeur est une pseudo-mthode n'ayant pas de spcication de type
de retour, et dont le nom est celui de la classe. Bien que le constructeur soit

23

plus proche d'une mthode de classe que d'une mthode d'instance, la pseudovariable

this

est dnie et dnote l'objet qui est en cours d'instantiation. Une

classe peut possder plusieurs constructeurs, toujours direncis par leurs listes
d'arguments. Si aucun constructeur n'est dclar, un constructeur implicite,
public, sans arguments, et avec un corps vide, est gnr.Un constructeur peut
en appeler un autre par une utilisation patriculire de

this:

puli lss gontiner {


puli gontiner@int sizeA {FFF}
puli gontiner@A {
this@IHAY
}
}
this@IHA

est ici interprt comme appelant le constructeur appropri la liste

d'arguments qui lui est pass. L'exemple ci-dessus permet de raliser une notion
de valeur par dfaut de l'argument
 Un appel

this

size.

Attention:

avec des arguments de mme type que le constructeur

courant provoquera une rcursion innie. heureusement les compilateurs


le dtectent.
 Un constructeur qui en appelle un autre peut excuter du code supplmentaire, mais l'appel

this

doit tre la premire instruction.

L'appel du constructeur est dclench par la syntaxe:

vranew glssxme@rgsAY
la liste d'arguments pouvant bien sr tre vide. Cette syntaxe est la seule pouvant dclencher la cration d'un objet. Dans le cas des tableaux, que nou savons
tre des classes dguises, le constructeur est accessible par une syntaxe particulire:

tring nmesanew tringnY


qui alloue un tableau de n chanes, dont tous les lments (traits comme des
attributs de la classe

tring ) sont initialiss null. Dans le cas des tableaux

multi-dimensionnels, cette syntaxe peut s'tendre sous deux formes:

tring nmesanew tringpqY


qui alloue un tableau de
initialiss

null,

tableaux de

chanes, chacun des

pBq

lments

ou

tring nmesanew tringpY


qui alloue un tableau de
type

tring

tableaux de chanes, chacun de ces

tant lui-mme initialis

24

null.

lements de

5.5 Destruction
Comme on l'a dit, la destruction d'un objet n'est jamais demande explicitement par le programme. Un objet vit tant qu'il est rfrenc, les rfrences
pouvant provenir directement:
1. d'une variable locale
2. d'une variable membre de classe d'une classe charge
3. d'une variable membre d'instance d'un objet vivant
4. d'un lment d'un tableau, ce qui est une variante particulire du cas
prcdent, et trs rpandue: tous les containers existant couramment
utilisent en dnitive un tableau.
Ds qu'un objet n'est plus rfrenc, la machine virtuelle est libre de librer son
espace mmoire, grce au Garbage Collector mentionn plus haut. Nanmoins,
l'initialisation de l'objet peut avoir allou des ressources prcieuses (comme des
connexions rseau) dont la machine virtuelle n'est pas consciente. Une mthode
particulire:

void finlize@A {FFF}


est dnissable comme l'endroit adquat pour librer les ressources autres que la
mmoire alloues par l'objet. Son rle est similaire celui du destructeur en

gCC.

Nanmoins, si la machine virtuelle est tenue de dtruire les objets non rfrencs
avant de se plaindre qu'il n'y a plus de mmoire pour en crer de nouveaux, et,
si possible avant que l'utilisateur ne se plaigne que l'application rame (!), elle
est, dans ces limites, totalement libre du moment de ces destructions, et de leur
ordonnancement. Ceci, joint au fait que le dveloppeur ne peut pas choisir entre
allocation dynamique des objets et allocation automatique sur la pile, fait que
le rle du naliseur est beaucoup moins crucial et prpondrant qu'en

gCC.

5.6 Hritage
Une classe peut hriter d'une autre. La syntaxe pour ceci est:

lss herivedglss extends fseglss {FFF}


Une classe ne peut tendre qu'une seule classe de base, ce qui limine l'hritage
multiple que l'on trouve dans d'autres langages objet. Nous verrons plus loin
comment une certaine forme d'hritage multiple est nanmoins possible. Une
classe drive hrite de tous les membres non privs de sa classe de base, mais
elle peut rednir les mthodes dont elle hrite, ce qui permet le polymorphisme.
En outre dans une mthode d'une classe drive, une nouvelle pseudo-variable,

super ,

est dnie. Elle permet:

 de forcer l'appel une mthode dnie dans la classe de base, quand celleci a t rednie dans la classe courante. Ceci est en particulier utile quand
une rednition veut s'appuyer sur la dnition de base.

25

 dans un constructeur, d'appeler un constructeur de la classe de base par

thisX

une technique analogue celle vue pour

super@rgsAY
En fait tout constructeur d'une classe drive ne contenant pas d'appel explicite

this@FFFA

super@FFFA

ou

est suppos commencer par

 super@AY , ce qui dclenchera une erreur du complateur si la classe de


base ne possde pas de constructeur sans argument, explicite ou implicite.

En fait, toutes les classes autres qu' yjet qui ne comportent pas de clause

extends explicite sont automatiquement considres comme ayant


 extends yjet . Toutes les classes autres qu' yjet sont donc

une clause
des classes

drives. Une classe peut par contre rsister sa propre drivation:


 Dclarer la classe elle-mme comme

finl interdit toute drivation


finl interdit la rednition

 Dclarer une mthode non prive comme

de

cette mthode particulire


Enn l'hritage permet des conversions, implicites ou explicites, entre les types
rfrences. De faon gnrale si
de

fseX

herived

1. Une expression de type


le type

fse,

fse

peut tre silencieusement convertie dans

ce qui permet une variable dclare

un objet de typ rel


dclar

fse est une classe, et herived une classe drive

herived ,

fse

de rfrence

et une mthode acceptant un argument

de recevoir un argument de type rel

herived ,

ce qui est la

base du polymorphisme.
2. Une expression de type

herived

fse peut tre explicitement convertie dans le type

par la syntaxe:

@herivedAexpr
qui sera accepte par le compilateur, mais qui pourra donner lieu une
erreur l'excution, si la promesse correspondante n'est pas tenue. Ceci
s'applique aussi au cas o
ou un interface qui n'est
3. Une expression de type
dans le type

fse ,

fse

pas

est un nterface, et

herived
fse.

est une classe

explicitement driv de

herived

peut tre silencieusement convertie

mais c'est une conversion dangereuse, qui peut

amener indirectement une erreur ultrieure l'excution: en eet le code


peut ensuite aecter un lment du tableau converti une rfrence
un objet qui n'est pas une instance de

26

herived .

Ceci est dmontr dans

l'exemple (par ailleurs inintressant!) suivant:

puli lss fug {


privte stti void spoil@yjet rgA {
if @rgFlengthbHA
rgHanew yjet@AY
}
puli stti void min@tring rgA {
spoil@rgAY
}
}
jv fug 

Ce code compile sans erreur ni avertissement, et l'excuter par 


ne provoque aucun incident, mais excuter:

jv fug quoi
provoque le message d'erreur suivant:

jvFlngFerrytoreixeptionX
t fugFspoil@fugFjvX RA
t fugFmin@fugFjvX UA
gCC, ceci correspondrait au fait que si herived drive de fse, herived B
fse B , mais que herived BB n'est pas acceptable
comme fse BB .

En

est acceptable comme

5.7 Accs
Il faut bien distinguer la visibilit de l'accessibilit, mme si les diagnostics
du compilateur ne le font pas toujours. Si un objet
un membre

elt,

 comme
 comme

oj d'une classe glz possde

hrit ou nom, ce membre est visible:

ojFelt dans tous les cas


glzFelt si c'est un membre

de classe, et c'est alors la notation

conseille.
Par contre, comme nous l'avons dj dcrit, le niveau de protection d'
la relation entre la classe qui contient le code rfrenant et
interdire l'usage. Dans le code d'une mthode de
ou

glzFelt

glz,

glz

les notations

peuvent tre remplaces par la forme abrge

elt,

elt,

et

peuvent en

thisFelt

dans la mesure

o il n'y a pas de conit avec le nom d'un argument ou d'une variable locale.
Pour viter les ambigits sans alourdir le code, il est conseill de donner aux
attributs, surtout ceux d'instance, un nom reconaissable, comme, dans ce cas,

elt

ou

melt .

27

5.8 Abstraction
Bien que les niveaux de protection procurent une certaine sparation de
l'interface et de l'implmentation, elle n'est pas totale, en particulier le source
d'une classe mlange les deux. Il existe un quivalent pur interface d'une classe,
introduit par le mot-clef

interfe , justement. La syntaxe de la dnition d'un

interface est voisine de celle d'une classe, avec quelques importantes dirences:
 Un interface peut tre public ou package, mais aucun qualicateur de
protection ne peut tre appliqu ses membres qui sont tous implicitement
publics
 Seules les mthodes peuvent tre des membres d'instances, tout membre
attribut est implicitement dclar

finl

 Les mthodes n'ont pas de dnition, la partie 


 Y. Elles sont abstraites.

{FFF} 

 Une classe qui veut hriter d'un interface dclare 

est remplace par

implements interface 

(en eet elle n'hrite que des dclarations, pas des dnitions qu'elle devra
fournir), et cette clause peut tre multiple, c'est--dire qu'une classe peut
implmenter plusieurs interfaces!
 Un interface ne peut bien sr pas hriter d'une classe, pas mme d'

yjet ,

mais il peut hriter d'un ou de plusieurs interfaces, en utilisant cette fois


le mot-clef

extends .

Cette notion d 'abstrait est galement tendue aux classes: une classe peut tre
dclare

strt , ce qui indique qu'elle n'implmente pas toutes les mthodes

qu'elle dclare (ou dont elle hrite). Les mthodes dclares sans tre implmentes doivent tre elles-mmes prcdes du mot-clef

strt .

Un cas typique

de classe abstraite est une classe qui implmente partiellement un interface. Une
classe abstraite est donc intermdiaire entre un interface et une classe normale, mais une autre classe ne peut ( nouveau) driver que d'une seule classe
abstraite, ce qui limite leur emploi dans une certaine mesure.
On peut dclarer une variable avec pour type une rfrence un interface ou
une classe abstraite, mais on est alors certain qu' l'excution, si cette variable
contient autre chose que la rfrence

null,

elle dnote un objet ayant un autre

type que le type dclar!

La gestion des exceptions

6.1 Mcanismes gnraux


De nombreuses erreurs peuvent survenir pendant l'excution d'un programme,
qui rendent impossible de pousrsuivre l'excution comme si rien n'tait arriv.

jv

dnit pour cela la notion d'exception. Une exception provoque la termi-

naison abrupte du bloc de code en cours d'excution, et le transfert du contrle


de l'excution en un point spci par le programmeur comme traitant cette

28

exception. Les exceptions sont en fait des classe

jv,

dclenches soit impli-

citement par une erreur du programme, soit explicitement par l'emploi de la


syntaxe:

throw new ExceptionClass @FFFAY


dans du code ayant dtermin qu'il ne peut pas s'excuter correctement dans
le cas prsent. Nous avons vu que le programmeur peut spcier le traitement
d'une exception par la syntaxe:

try tryBlock
th@ExceptionClass id A handlerBlock
FFF
Le contrle de l'excution sera tranfr au dbut du bloc

ExceptionClass

exception drive de la classe

tryBlock .

handlerBlock

si une

est leve pendant l'excution de

6.2 Particularits la compilation


Les exceptions ne peuvent pas tre n'importe quelles classes, elles doivent
tre drives de la classe

jvFlngFhrowle .

La hirarchie drive de cette

classe est divise en 3 parties:

jvFlngFirror et ses drives


La classe jvFlngFunimeixeption et ses drives
Les autres classes drives de jvFlngFixeption

1. La classe
2.
3.

Une mthode peut dclarer les mthodes que son excution peut lever sans
qu'elle les gre elle-mme par la clause:

throws ExceptionClass1D ExceptionClass2


Une mthode

doit

dclarer de telles exceptions si elles sont du type 3. Cette

obligation n'existe pas pour les autres types:


 Les drives de

irror

sont des erreurs dicilement rcuprables et qui

peuvent se produire n'importe o


 Les drives de

unimeixeption

sont des erreurs qui peuvent tre le-

ves par de nombreuses constructions du langage, mais dont le dveloppeur peut se garantir par des techniques que le compilateur n'est pas

erithmetiixeption (division par


xullointerixeptionD glssgstixeption (toutes ces exceptions
sont dans le package jvFlng ).
en mesure de reconnatre: par ex.

0),

Exiger que tout programme dclare ou traite ces erreurs nuirait en dnitive
la lisibilit et la maintenabilit du code.

29

Les Composants

java

7.1 Introduction
Au dbut, les seuls composants

jv taient les classes drives de jvFwtFgomponent ,

c'est--dire des composants graphiques interactifs, destins tre programms


explicitement par le dveloppeur. Le notion maintenant recouvre des composants
qui peuvent ne pas avoir de facette interactive, mais surtout qui peuvent tre
manipuls par des outils de conception, voire interagir avec d'autres composants,
qui ne les connaissaient pas au moment de la compilation. Ces mcanismes ont
besoin de moyens de communication standardiss mais aussi extensibles.

7.2 Srialisation
La capacit de sauvegarder l'tat d'un objet et de le restaurer ultrieurement
est intressante en soi. Elle l'est particulirement dans le cas de composants que
des outils visuels permettent de paramtrer sur-mesure, car ce paramtrage

jv

est perdu si on ne peut le sauvegarder.

prvoit un mcanisme pour sau-

vegarder un objet sur un ux de sortie (comme un chier). Ce mcanisme est


 plusieurs vitesses, c'est--dire qu(il est plus ou moins automatique ou sous
contrle du programme suivant le dsit du dveloppeur. Une classe qui implmente l'interface

erilizle

prote au maximum de l'automatisation. Une

certaine mesure de contrle peut tre amene par un nouveau qualicateur pour
les attributs,

trnsient . Un attribut dclar trnsient

ne sera ni crit, ni relu

au moment de la srialisation. Il y a plusieurs possibles pour dclarer un attribut

trnsient :

 C'est un attribut temporaire, calcul partir des autres pour faciliter ou


acclrer certaines oprations (par exemple un cache).
 C'est un attribut qui n'a de sens qu' l'excution (par exemple une connection base de donnes).
 C'est une rfrence sur un objet qui n'est pas srialisable. Bien sr, si
connatre son tat est indispensable pour reconstituer l'tat de l'objet
courant, celui-ci n'est pas non lus srialisable!
 C'est une attribut sensible, au sens de la scurit. Aprs tout, crire tous
ses attributs sur un ux de sortie sur simple demande est un peu contre
courant de la scurit (de l'encapsulation aussi, si l'on y rchit!).
Mais si la classe veut tre srialisable, mais en contrlant totalement ce qui est
crit et relu, et dans quel format, elle doit implmenter l'interface
et fournir les mthodes

writeyjet

et

redyjet .

ixternlizle ,

7.3 Gestion des vnements


Les vnements sont un des principaux moyens de communication des composants, tels qu'ils soient, entre eux. Les composants ayant de plus en plus d'importance dans

jv, le modle vnementiel est d'autant plus important. Trs re30

mani galement depuis jdk1.0, initialement dni dans


de base sont maintenant dans

jvFutil

jvFwt , les interfaces

(pourquoi pas?), avec les implmen-

tations prdnies interessantes partages entre

jvFens

et

jvxFswing .

Le modle relve du principe abonnement/notication. Il y a 3 type d'acteurs,


ayant des relations logiques trs circulaires:
1. Les vnements eux-mme. Ce sont des classes drives de

jvFutilFiventyjet ,

c'est une classe concrte, mais sa seule proprit est sa source. Des objets
de cette classe peuvent tre instantis et transmis, mais ils ne comportent
aucun tat, ne transportent aucune autre information que celle d'avoir t
suscits, et par qui.
2. Les listeners. Il existe un interface

jvFutilFiventvistener ,

mais il

est vide. Pour chaque classe spcique d'vnement, on dnit un interface qui tend

iventvistener ,

et qui contient une mthode pour traiter

l'vnement en question. Par exemple, un vnement trs populaire est

jvFwtFeventFetionivent .

Cet vnement correspond l'action de

l'utilisateur sur un bouton, ou un item de menu, et contient (entre autres)


une variable d'tat reprsentant la commande sous forme d'une chane de
caractres. Il lui correspond, dans le mme package, un listener:

puli interfe etionvistener extends iventvistener {


void etionerformed@etionivent eAY
}
Une implmentation concrte de ce listener pourra agir en fonction de la
proprit

tiongommnd

de l'etionivent .

3. Le source d'un vnement. Il n'y a pas de classe ni d'interface de base,


part

yjet3

Une source est un gnre des vnements, elle doit donc

connatre certains types d'vnements , donc les types de listener correspondants et doit dnir des mthodes X

ddiventvistener@xiventvistener listenerAY
et

removeiventvistener@xiventvistener listenerAY
rien n'interdit un objet de, ni ne le force , tre simultanment source
et listener. Des sources typiques sont:
 des composants graphiques classiques, dans
Par exemple les boutons sont des sources de
 des javabeans

31

jvYwt ou jvxFswing .
etionivent .

7.4 Les Java Beans


La notion de JavaBean est assez informelle: il n'y a pas d'interface de ce nom
implmenter obligatoirement. Presque n'importe classe publique

jv

peut

tre un bean, condition de respecter un petit nombre de contraintes, au moins


si elle veut tre un bean intressant :
 Un bean qui se respecte doit tre srialisable, c'est dire qu'il doit impl-

erilizle , soit ixternlizle (tous les deux, dans le


jvFio ). Un bean est cens tre instanti par des mthodes de
particulres de jvFensFfens , qui chercheront rtablir, par

menter soit
package
classe

dsrialisation, un tat antrieur conserv par srialisation.


 Un bean doit possder un constructeur public appelable sans argument.
L'instantiation ci-dessus n'a pas d'argument particulier passer un
constructeur.
 Un bean doit possder un certain nombre de mthodes publiques reconnaissables par les outils grce un mcanisme appel introspection.
Une mtaclasse d'information peut tre utilise pour publier ces mthodes,
mais par dfaut des rgles de nommage simple sont appliques, ce qui suit
se rfrera ce cas simpli. Les mthodes reconnues par les outils sont
de plusieurs types:
 Les proprits: un bean exporte une proprit

nme

de type

type

s'il

possde au moins une des deux mthodes publiques suivantes:





type getxme@AY
void setxme@type vlueAY

S'il possde ces deux mthodes, la proprit est accessible en lecture/criture, si seule la mthode

get

existe, la proprit est acces-

set existe, la proprit est


type est oolen , la mthode get peut

sible en lecture seule, si seule la mhode


accessible en criture seule. Si
tre remplace par

isxme@A

 Les vnements (voir plus haut la description des sources): Un bean


annonce qu'il est une source d'vnements

iventxme

s'il possde

deux mthodes publiques:




ddiventxmevistener@iventxmevistener listenerA , accomthrows oownyvisteners


removeiventxmevistener@iventxmevistener listenerAY
pagne ou nom d'une clause

 Les deux peuvent se combiner: deux vnements lis aux proprits sont prdnis:

ropertyghnge

et

etoleghnge . Le premier

sert dnir la notion de proprit lie, c'est--dire de proprit


dont il est possible de demander tre noti des changements. Le
second sert dnir la notion de proprit contrainte, c'est--dire
de proprit aux changements de laquelle il est possible de s'opposer.

32

Un bean qui possde une proprit accessible en criture dont il veut


faire une proprit lie doit se signaler comme source d'vnements

ropertyghnge

(il existe des versions des fonctions

ddGremove

avec un argument supplmentaire pour spcier le nom de la pro-

set.

prit), et bien sr, gnrer les lments dans la mthode


classe auxiliaire,

ropertyghngeupport

Une

existe pour faciliter cette

implmentation (toutes les classes et interfaces mentionns ici sont


dans le package

jvFens ).

Un mcanisme semblable est dni

pour les proprits contraintes.


 Les mthodes publiques dont le nom n'est pas conforme un des
schmas que nous venons de voir sont simplement reconnues comme
mthodes accessibles.
 En fait, les spcications dec beans lies au jdk1.2 ont enrichi ce modle et
en particulier, spcient un interface,

fenghild , qu'un bean est encourag

implmenter pour proter de toutes les nouveauts apportes par 1.2.


Nanmoins, pour des raisons de compatibilit, il n'est pour l'instant pas
envisag de rendre l'implmentation de cet interface obligatoire.
Bien que cette liste soit longue, ce qu'un bean est

oblig d'implmenter est limit,

car il peut exporter n'importe quel nombre de proprits, y compris 0, et de


mme pour les vnements. En fait dans un cas limite d'utilisation des servlets de
WebSphere (extension IBM pour serveur HTTP), avec une dnition pr- jdk1.2
des Java Server Pages , il est possible d'utiliser comme bean... un

tring !

Mais

si le bean a t conu pour interoprer avec d'autres, un outil de manipulation


visuelle, comme la BeanBox de Sun, peut prsenter ses proprits diter, puis
les sauver par srialisation, peut assembler plusieurs

beans, et connecter des

vnements gnrs par l'un des mthodes publiques de l'autre, tout cela avec
un pilotage purement visuel du dveloppeur.

Programmation

java

avance

8.1 Introduction
L'un des attraits que possdait

jv ds sa sortie, mme en version

jdk1.0beta ,

c'est qu'il tait accompagn de librairies qui rendaient extrmement facile de


dvelopper des applications qui aurient mrit le qualicatif d'avanc avec tout
autre environnement (par exemple une maquette de serveur

HTTP). En par-

ticulier, le support de la programmation rseau, et de la concurrence, taient


remarquable d'entre par leur facilit d'utilisation.

8.2 Les threads et le multithreading


La concurrence est reprsente en
 Une classe prdnie,

jv

par deux lments:

hred , qui modlise ce qu'on appelle aussi un prounnle .

cessus lger, accompagne d'une classe auxiliaire

33

 Un mot-clef particulier,

synhronized ,

qui prend en charge tous les be-

soins de synchronisation

8.2.1 Qu'est ce qu'un thread


On appelle thread en gnral (pas spcialement en

jv)

un processus ex-

cutable interne un processus systme. Un nombre potentiellement illimit de


threads peuvent coexister au sein d'un processus systmes. Ils ont de gros avantages en ce qui concerne les performances par rapport la multiplication des
processus lourds que sont les processus systmes:
1. Ils partagent priori leurs ressources, en particulier l'accs la mmoire
(ce qui prsente d'autres inconvnients)
2. Ils peuvent s'allouer des ressources prives si cela est ncessaire
3. La transition entre deux threads d'un mme processus est peu coteuse
La contrepartie de 1 est que le systme ne fournit aucune protection directe
contre des utilisations asociales de ses ressources. Une programmation multithread demande donc en gnral une gestion attentive de la synchronisation des
accs ces ressources partages.

8.2.2 Les hred jv


Crer une instance de la classe

hred est la seule faon de lancer l'excution

d'une fonction dans un nouveauprocessus lger. Il y a deux mthodes, lgrement


direntes:
1. Ecrire une classe qui drive de

hred ,

et rednir la mthode

run@A :

puli lss sk extends hred {


puli void run@A {
GG ode exuter
}
}
puis lancer l'excution par

new sk@AFstrt@AY
2. Ecrire une classe qui implmente l'interface
thode

run@A :

unnle ,

puli lss tsk implements unnle {


puli void run@A {
GG ode exuter
}
}

34

et dnir la m-

puis lancer l'excution par:

new hred@new sk@AAFstrt@AY


hred

Bien sr, une rfrence sur le


ncessaire, un

hred

peut tre conserve, mais ce n'est pas

actif est rfrenc par le systme, et ne sera pas Garbage

run@A

collect tant que sa mthode

s'excute.

8.2.3 Les dicults lies la concurrence


La dicult de la conception d'une application multithread rside dans le
fait de devoir prendre en compte les problmes de synchronisation des threads.
D'une faon gnrale, ces problmes rentrent dans deux catgories:
1. L'exclusion mutuelle, qui correspond la notion de sections critiques, c'est-dire de traitements dont on veut garantir qu'un seul

hred peut les ex-

cuter la fois. Il s'agit par exemple de modications de donnes partages


entre les threads
2. La notion d'vnement/notication, qui correspond qu'un peut se mettre
en attente d'un signal de la part d'un autre. Il s'agit par exemple du cas
d'un
En

hred

consommant des donnes produites par un autre

hred .

jv, ce seront des objets qui joueront aussi bien le rle de verrou d'exclusion

mutuelle (moniteur) que d'vnement. En fait un objet ne peut jouer le rle


d'vnement que s'il joue dj celui de moniteur.

8.2.4 L'exclusion mutuelle


Pour mettre en vidence ce problme, considrons simplement la trs utilise

jvFutilFetor .
elements , soit visible par
classe

Supposons qu'une variable de type

etor ,

disons

deux sections de code excuts par deux threads

dirents:
1. code excut par le 1er

hred :

yjet eltanullY
if @elementsFsize@AbHA
eltaelementsFelementet@HAY
2. code excut par le 2me

hred :

if @elementsFsize@AbHA
elementsFremoveet@HAY
En l'absence de toute synchronization, l'ordonnancement des instructions entre
les deux threads est libre. Dans le cas o les deux threads arrivent au dbut
des sections de code alors que
deux appels

size@A

elements

contient exactement

peuvent renvoyer 1, puis l'appel

35

un

lment, les

removeilementet

peut

s'excuter en premier, suivi par l'appel

elementet qui dclenchera maintenant


size@A auparavant. Le mot-

une exception, malgr la prcaution prise de tester


clef

synhronized

sert rsoudre ce problme. On rcrit les deux sections:

1. code excut par le 1er

hred :

yjet eltanullY
synhronized@elementsA {
if @elementsFsize@AbHA
eltaelementsFelementet@HAY}
2. code excut par le 2me

hred :

synhronized@elementsA {
if @elementsFsize@AbHA
elementsFremoveet@HAY}
L'eet de

synhronized

est d'acqurir le verrou li l'objet

elements

pour

la dure du bloc entre accolades. Maintenant les deux threads ne pourront pas
pntrer en mme temps dans les sections synchroniss, le deuxime arriv devra
attendre que le premier en soit sorti.
Ceci est l'usage le plus gnral de synchronized, mais l'usage le plus frquent
est en fait un cas particulier, o

synhronized

est utilis comme qualicateur

d'une mthode. Si la mthode est une mthode d'instance, ceci est quivalent
encadrer le code par la mthode par

synhronised@thisA{FFF} .

Deux m-

thodes d'instance synchronises ne peuvent pas s'excuter en parallle sur un


mme objet, c'est--dire que l'excution de l'une prcdera totalement l'excution de l'autre. Si

synhronized

est appliqu une mthode de classe, l'eet

est de synchroniser sur l'unique objet reprsentant la classe. Deux mthodes de


(la mme) classe synchronises ne peuvent pas s'excuter en parallle.
Un

hred peut acqurir plusieus fois le mme verrou. Une mthode synhronized

peut donc en appeler une autre, sans provoquer de deadlock, le verrou ne sera
relch qu'aprs la terminaison du bloc
les blocs

synhronized

synhronized

le plus externe. Bien sr,

qui sont termins par une exception sont grs propre-

ment.
Pour des raisons analogues celles rencontres dans l'exemple prcdent, la
plupart des mthodes d'instance de

etor sont dj synchronises. Nanmoins,

la synchronisation n'est pas gratuite en termes de performance. C'est pourquoi


les nouvelles classes de

golletion

du jdk1.2 ne sont plus synchronises par

dfaut.
D'autre part l'accs a des attributs individuels d'un objet peut tre garanti
des problmes de synchronisation moindre cot, grce aux deux points suivante:
 L'accs une variable individuelle est atomique, c'est--dire que, par
exemple, un

hred

qui lit une variable de type

36

short

dans une mthode

non synchronise ne risque pas de recevoir un monstre dont 8 bits contiendraient ce qu'il y avait mis son dernier accs, et les 8 autres ce qu'un
autre

hred

vient d'y mettre. Attention, ceci n'est pas garanti pour les

variables sur 64 bits ( long et


 Si un attribut est dclar

doule )!
voltile , chaque

lecture est garantie renvoyer

son tat le plus rcent, c'est--dire que toute modication eectue par

hred

un

est immdiatement visible par les autres. Sans ce qualicateur,

la machine virtuelle n'est absolulment pas tenue de garantir ce comportement.

8.2.5 Attente et notication d'vnement.


Si un

hred

a acquis le verrou associ un objet, la mthode

tre invoque sur cet objet dans le contexte de ce

hred .

wit

peut

Celui-ci est alors

mis en attente (aprs avoir temporairement libr le verrou), jusqu' ce qu'un

hred

actif, et ayant son tour acquis le verrou, invoque sur cet objet la

mthode

notify , notifyell , ou aprs un time-out si l'invocation de wit en


notify slectionne au hasard un hred parmi ceux

a spci un. La mthode

en attente sur l'objet pour le ractiver, alors que dans les autres cas tous les
threads concerns le sont. Mme si le

hred

est choisi, il doit pour devenir

eectivement actif obtenir de niveau le verrou, et d'autres threads peuvent tre


en comptition (en particulier le

hred

ayant invoqu

notify

qui avait acquis

le verrou ce moment, s'il ne l'a pas relch depuis).


1. Voici un exemple simple, mettant en jeu un producteur et un consommateur. La classe

hredht

dnit une donne partage, ici un simple

entier. Le consommateur peut lire la donne par la mthode


producteur peut lk'crire par la mthode

putlue .

getlue ,

le

La synchronisation

est double: le consommateur ne peut rcuprer la donne (une fois) que


si le producteur vient de la mettre disposition, et le producteur ne peut

37

dposer une donne que si la prcdente a t consomme.

puli lss hredht {


privte int ontentsY
privte oolen villeaflseY
puli synhronized int getlue@A {
while @3villeA {
try {
wit@AY
} th@snterruptedixeption eA {
}
}
villeaflseY
notifyell@AY
return ontentsY
}
puli synhronized void setlue@int vlueA {
while @villeA {
try {
wit@AY
} th@snterruptedixeption eA {
}
}
villeatrueY
ontentsavlueY
notifyell@AY
}
}
2. Voici maintenant un exemple plus complexe, permettant un

hred d'ac-

qurir une ressource en exclusivit pour la modier, mais permettant un


accs partag en lecture aux autres threads. La classe

38

vok

ci-dessous

implmente un verrou de ce type.

puli lss vok {


privte int shred a HY
privte oolen exlusive a flseY
puli synhronized void quirehred@A {
if @exlusiveA {
while @exlusiveA
try {
wit@AY
} th@snterruptedixeption eA {
}
}
shredCCY
}
puli synhronized void relese@A {
if @shredbHA {
shredEEY
if @shredaaHA
notify@AY GG xotify to one witing exlusive hred
}
else if @exlusiveA {
exlusive a flseY
notifyell@AY GG xotify to all witing shred threds
}
}
puli synhronized void quireixlusive@A {
if @exlusive || shredbHA {
while @exlusive || shredbHA
try {
wit@AY
} th@snterruptedixeption eA {
}
}
exlusive a trueY
}
}

39

et voici la donne partage:

puli lss hredht {


privte int ontentsY
privte vok thevokanew vok@AY
puli int getlue@A {
int vlueaHY
try {
thevokFquirehred@AY
vlueaontentsY
} finlly {
thevokFrelese@AY
}
return vlueY
}
puli void setlue@int vlueA {
try {
thevokFquireixlusive@AY
ontentsFsetlue@vlueAY
} finlly {
thevokFrelese@AY
}
}
}
Cette fois, la donne n'est pas consomme par la lecture.

8.3 La programmation rseau


8.3.1 Introduction
Les classes du package

jvFnet

contiennent principalement:

 Des classes URL permettant d'accder au contenu d'une ressource WEB


 Des classes correspondant la notion de socket pour la communication
programme programme.
Les classes socket permettent une communication programme programme
aussi bien en mode datagramme qu'en mode connect. Nous reprendrons dans
ces deux cas un mme exemple de couple client serveur, le serveur se bornant
ici faire l'cho de chanes de caractres envoyes par le ou les clients.

8.3.2 oket en mode connect


En mode connect, on commence d'abord par crer un canal de communication entre les deux applications. Le mcanisme est dissymtrique, le client utilise

40

un objet

oket pour tablir un connexion avec un serveur qui utilise de son ct

un ServerSocket pour recevoir ces demandes de connexion. Un fois la connexion


tablie, on dispose d'un

snputtrem

et d'un

yutputtrem ,

respectivement

pour lire ou crire dans le socket. Dans notre exemple, de faon pouvoir servir

hred pour chaque nouveau


erveroket , le constructeur a comme

plusieurs clients simultanment, le serveur cre un


client. Le serveur cre un objet de type

argument la porte sur laquelle le socket est l'coute. La mthode accept est
bloquante jusqu' la connexion d'un nouveau client, elle retourne un nouveau
socket ouvert avec le client, ce socket est transmis au constructeur du
service qui cre un

fufferededer

et un

lire et crire dans le socket.

import jvFioFBY
import jvFnetFBY

41

rintriter ,

hred

de

respectivement pour

lss erviehred extends hred {


privte finl oket soketY
privte finl fufferededer inY
privte finl rintriter outY
erviehred@oket soketA throws syixeption {
soket a soketY
in a new fufferededer@
new snputtremeder@
soketFgetsnputtrem@AAAY
out a new rintriter@
new fufferedriter@
new yutputtremriter@
soketFgetyutputtrem@AAAD trueAY
}
puli void run@A {
try {
while@trueA {
tring str a inFredvine@AY
if @str aa nullA
rekY
outFprintln@strFtoppergse@AAY
}
}
th@syixeption eA {
}
finlly {
ystemFoutFprintln@4gonnetion losed4AY
try {
soketFlose@AY
}th@syixeption eA {
}
}
}
}
puli lss hrededihoerver {

42

puli stti void min@tring rgsA throws syixeption {


int portaHY
try {
port a sntegerFprsesnt@rgsHAY
} th @ixeption eA {
ystemFoutFprintln@4sgeX ihoerver port4AY
ystemFexit@IAY
}
try {
erveroket listen a new erveroket@portAY
ystemFoutFprintln@4vistening on soket 4 C listenAY
try {
while@trueA {
oket soket a listenFept@AY
ystemFoutFprintln@4xew onnetion 4 C soketAY
try {
new erviehred@soketAFstrt@AY
} th@syixeption eA {
soketFlose@AY
}
}
} finlly {
listenFlose@AY
}
} th@syixeption eA {
ystemFoutFprintln@eAY
}
}
}
Du cot client, le constructeur du socket comporte comme argument l'adresse
Internet de la machine serveur ainsi que la porte sur laquelle coute le serveur.
L'adresse Internet est obtenue partir du nom de la machine serveur par la
mthode

getfyxme

qui fait appel au service de nom. De la mme faon que le

serveur, le client cre des stream pour lire et crire dans le socket.

import jvFioFBY
import jvFnetFBY

43

puli lss ihoglient {


puli stti void min@tring rgsA {
int portaHY
tring hostanullY
try {
port a sntegerFprsesnt@rgsIAY
host a rgsHY
}
th @ixeption eA {
ystemFoutFprintln@4sgeX ihoglient host port4AY
ystemFexit@IAY
}
try {
sneteddress ddress a sneteddressFgetfyxme@hostAY
oket soket a new oket@ddressD portAY
try {
ystemFoutFprintln@4oket 4 C soketAY
fufferededer in a new fufferededer@
new snputtremeder@
soketFgetsnputtrem@AAAY
rintriter out a new rintriter@
new fufferedriter@
new yutputtremriter@
soketFgetyutputtrem@AAAD trueAY
fufferededer sysin a new fufferededer@
new snputtremeder@ystemFinAAY
while@trueA {
tring str a sysinFredvine@AY
if@str aa nullA
rekY
outFprintln@strAY
str a inFredvine@AY
ystemFoutFprintln@strAY
}
}
finlly {
soketFlose@AY
}
}
th@syixeption eA {
ystemFoutFprintln@eAY
}
}
}
44

8.3.3 oket en mode datagramme


Un socket de type

htgrmoket

permet l'envoi ou la rception de paquets

de donnes. Cot mission, on construit un paquet de donnes

htgrmket

partir du contenu du message, de l'adresse de destination (un objet de type

snetedress ) et de la porte de destination. On peut ensuite transmettre le message par la mthode send sur un htgrmoket . Cot rception, on construit
galement un htgrmket que l'on fournit comme argument la mthode
reeive sur un htgrmoket .
Le serveur d'cho en mode datagramme:

import jvFioFBY
import jvFnetFBY
puli lss htgrmihoerver {
puli stti void min@tring rgsA {
int portaHY
try {
port a sntegerFprsesnt@rgsHAY
}
th @ixeption eA {
ystemFoutFprintln@4sgeX ihoerver port4AY
ystemFexit@IAY
}
try {
htgrmoket soket a new htgrmoket@portAY
yte uffer a new yteIHHHY
htgrmket inpketa new htgrmket@
ufferD ufferFlengthAY
while@trueA {
soketFreeive@inpketAY
ystemFoutFprintln@4wessge from 4 C

inpketFgeteddress@AFgetrostx

inpketFgeteddress@A C 4A port 4 C inpketFgetort@AAY


tring str a new tring@ufferDHDinpketFgetvength@AAY
str a strFtoppergse@AY
htgrmket outpket a new htgrmket@
strFgetfytes@AD strFlength@AD

45

inpketFgeteddress@AD inpketFgetort@AAY
soketFsend@outpketAY
inpketFsetvength@ufferFlengthAY
}
}
th@syixeption eA {
ystemFoutFprintln@eAY
}
}
}
Le client en mode datagramme:

import jvFioFBY
import jvFnetFBY

46

puli lss htgrmihoglient {


puli stti void min@tring rgsA {
int portaHY
tring hostanullY
try {
port a sntegerFprsesnt@rgsIAY
host a rgsHY
}
th @ixeption eA {
ystemFoutFprintln@4sgeX ihoglient host port4AY
ystemFexit@IAY
}
try {
sneteddress ddress a sneteddressFgetfyxme@hostAY
htgrmoket soket a new htgrmoket@AY
yte uffer a new yteIHHHY
htgrmket inpket a new htgrmket@
ufferD ufferFlengthAY
fufferededer sysin a new fufferededer@
new snputtremeder@ystemFinAAY
while@trueA {
tring str a sysinFredvine@AY
if@str aa nullA
rekY
htgrmket outpket a new htgrmket@
strFgetfytes@AD strFlength@AD
ddressD portAY
soketFsend@outpketAY
soketFreeive@inpketAY
str a new tring@ufferDHDinpketFgetlength@AAY
ystemFoutFprintln@strAY
inpketFsetlength@ufferFlengthAY
}
soketFlose@AY
}
th@syixeption eA {
ystemFoutFprintln@eAY
}
}
}

47

La scurit

9.1 Les mcanismes de la scurit


Plusieurs mcanismes interviennent dans le maintien de la scurit:
1. Au niveau le plus bas, le compilateur et le langage garantissent que le code
excut ne peut pas faire exploser la machine virtuelle, mais peut tout au
plus lever des exceptions propres.
2. Nous avons vu tout l'heure les mcanismes de la vrication de pseudocode.Le vricateur protge la machine virtuelle contre du pseudo-code
invalide, peut-tre malicieux, qui pourrait dclencher l'excution de znes
de code rserves.
3. Les chargeurs de classe sont un autre mcanisme scurisant: Un chargeur
de classe est un objet

jv responsable de trouver

une classe tant donn

une rfrence symbolique rsoudre, et peut-tre de la charger. Une table


est maintenue par la machine virtuelle, dont les clefs sont des couples d'un
nom complet de classe et d'une rfrence sur un chargeur de classe, et dont
les data sont des classes
mmoires par des objets

jv
jv

jv reprsentes en
jvFlngFglss ). Toute classe

charges (les classes


de classe

contient une rfrence au chargeur de classe qui l'a charg, et donc qui l'a
instanti. Quand une rfrence symbolique sur une classe est rencontre
dans du code appartenant une classe dj prsente, la procdure suivante
est observe pour la rsoudre:
(a) On cherche dans la table ci-dessus s'il existe une entre dont la clef
est la combinaison du nom constituant la rfrence symbolique et du
chargeur de la classe courante. Si c'est le cas, la classe correspondante
est utilise

sans appeler aucune mthode du chargeur de classe . Ceci

a deux consquences:
i. Le chargeur de classe ne peut pas pervertir le systme en rsolvant diremment une mme rfrence symbolique en deux
occasions.
ii. Si une classe ayant le mme nom est dj prsente mais associe
un autre chargeur, elle ne sera pas forcment utilise dans ce
contexte. Ceci vite qu'une classe charge par exemple par un applet malveillant et possdant le mme nom qu'une classe systme
non encore charge soit trouve et appele par du code sain.
(b) Si la classe n'a pas t trouve en (a), alors la mthode

lodglss

est invoque sur le chargeur de la classe courante. Quand cette mthode retourne avec succs, le rsultat est utilis pour crer une nouvelle entre dans la table, avec le nom de la classe, et ce chargeur.
Ceci n'implique pas nanmoins que ce chargeur soit celui associ; la
classe, car rien un chargeur peut demander un autre chargeur de
cooprer avec lui pour trouver une classe, si la politique de scurit
ne s'y oppose pas.

48

Au lancement de la machine virtuelle, il existe un seul chargeur de classes,


appel le chargeur primordial (qui n'est pas rellement un objet

jv mais

plutt partie intgrante de la machine virtuelle), qui est utilis pour charger les classes locales, et en particulier les classes des packages de base.
Plus tard d'autres chargeurs de classe pourront tre instantis applicativement, en particulier pour aller chercher des classes sur le rseau. Un
chargeur dirent est cr pour chaque serveur source de classes. La methode

lodglss

de ces chargeurs commence normalement par demander

la coopration du chargeur de classe primordial. C'est ce qui fait que des


applets en provenance d' URLs dirents ne partageront pas des classes
applets mme si elles ont le mme nom, mais que tous utiliserons la mme
classe

tring .

4. La politique de scurit. C'est un objet global qui ralise un mapping


entre un

godeoure

et un ensemble de permissions. Un

godeoure

re-

prsente l'origine d'une classe, en un sens similaire, mais plus riche que
celui utilis par les chargeurs de classes, puisqu'il combine URL originateur
et (ventuel) certicat de scurit. Les permissions couvrent tous les domaines sensibles de l'activit d'une application, comme l'accs aux chiers,
l'accs au rseau, l'ouverture de fentres, etc... La politique de scurit est
un nouveau mcanisme du jdk1.2, qui permet un contrle plus n de la
scurit, sans avoir besoin de le programmer, car une politique peut tre
spcie par un chier texte, lui-mme aisment congurable par un outil
spcialis,

poliytool .

5. Le gestionnaire de scurit. C'est encore un objet global dont les mthodes


vrient que l'application n'outrepasse pas les permissions attribues par
la politique de scurit en fonction des

godeoure .

Quand on lance une

machine virtuelle depuis la ligne de commande, il n'y a pas de gestionnaire de scurit global tant que le code applicatif n'en installe pas un,
ce qui fait que la politique de scurit n'est pas applique! Bien sr, un
browser en installe un. Jusqu'au jdk1.1, c'tait une classe abstraite qu'il
tait ncessaire d'implmenter, mais avec l'introduction de la politique de
scurit, la classe de base est parfaitement utilisable telle quelle.
6. Nous avons mentionn les certicats de scurit en 5. Ils annoncent les
mcanismes extrieurs de la scurit, avec les archives et les cabinets,
pour empaqueter ensemble classes et certicats, la cryptographie, pour
garantir la valeur du rsultat, les couches scurises de transport, etc...

9.2 L'volution du modle


1. Dans les premires versions, le modle de scurit tait gr en tout-ourien, par exemple, dans le jdk1.0:
 Le code local, c'est--dire charg depuis le disque par le chargeur
de classes primordial, est considr sr, et n'est soumis aucune
restriction

49

 Le code lointain, c'est--dire tout le reste, par exemple des applets


chargs sur le web, tait suspect, et n'tait autoris accder aucune
resource extrieure: systme de chiers, excution d'autres applications, etc... C'est ce qu'on appelle le sandbox.
2. Avec le jdk1.1, le modle est toujours en tout ou rien, mais la frontire
est plus souple: les certicats sont introduits, si un applet est sign et
accompagn d'un certicat, celui-ci est montr l'utilisateur, qui peut
dcider de s'y er ou non. Suivant sa dcision l' applet tournera en dehors
ou en dedans du sandbox.
3. Avec le jdk1.2, le modle est maintenant totalement dclinable. Les classes
systmes ont toujours toutes les permissions, mais en dehors du cas o
aucun gestionnaire de scurit n'est install, le code de toute autre origine
peut recevoir des droits opration par opration. La toute puissance des
classes systmes ne doit pas tre interprte htivement: le code qui s'ex-

i tous les intervenants


dans la pile des appels possdent cette permission . Cette remarque doit
cute un moment donn n'a une permission que s
son tour tre nuance, dans deux sens opposs:
(a) Si du code est excut pour le compte d'un autre
gence sera tendue la pile des appels du

hred

hred ,

cette exi-

client

(b) Du code autoris peut explicitement demander rlaxer cette exigence vis--vis de ses appelants.

50

Vous aimerez peut-être aussi