• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Apprentissage du java
 

Apprentissage du java

on

  • 1,016 views

 

Statistics

Views

Total Views
1,016
Views on SlideShare
1,016
Embed Views
0

Actions

Likes
0
Downloads
22
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Apprentissage du java Apprentissage du java Document Transcript

    • Ecole Sup´rieure d’Ing´nieurs de Luminy e e Universit´ de la M´diterran´e e e e Support de cours pourl’apprentissage du langage JAVA ESIL - GBM 2 Claudine Chaouiya 2003/2004 chaouiya@esil.univ-mrs.fr http ://www.esil.univ-mrs.fr/˜chaouiya
    • Chapitre 1Introduction Java est un langage de programmation orient´ objets adapt´ ` la distribution e e ad’aplications sur Internet et qui s’int`gre au Web. Nous verrons avant tout les ediff´rentes approches de programmation. e Avant d’´crire un programme, il faut poser le probl`me que ce programme devra e er´soudre. La formulation du probl`me influe sur l’´criture du programme, on parle e e ede paradigmes de programmation. S’il est ` peu pr`s possible d’impl´menter tous les a e eparadigmes avec tout langage de programmation, chaque langage est quand mˆme eplus adapt´ ` un paradigme donn´. Ainsi, C est un langage dit proc´dural, C++ et ea e eJava sont orient´s objets. e1.1 Programmation proc´durale e C’est l’approche que vous connaissez. Le langage C est adapt´ ` la programma- eation proc´durale. Dans ce style de programmation, l’accent porte sur l’algorithme emis en oeuvre. Chaque ´tape de l’algorithme peut elle mˆme ˆtre d´coup´e. C’est e e e e ela programmation structur´e qui indique qu’il faut isoler et clairement identifier les ediff´rentes op´rations. On utilise ainsi des fonctions auxquelles on fournit des ar- e eguments et qui retournent des r´sultats. Ces fonctions peuvent ´ventuellement ˆtre e e erang´es dans des biblioth`ques, pour que l’on puisse les r´utiliser. On retrouve ici les e e enotions de modules (voir plus loin), et de compilation s´par´e vues l’an dernier. e eExemple du calcul du pgcdint pgcd(int a, int b){ int r; if (a<b){r=a;a=b;b=r;} do { r=a%b; a=b; b=r; } while (r!=0); return a;}... 1
    • 1.2. PROGRAMMATION MODULAIREvoid fonction1(....) { .... x=pgcd(1990,y); ....}Exemple de la pile#include <stdio.h>typedef struct elt { char info; struct elt *suiv;} Maillon, *Pile;Pile empiler(char c,Pile P) { Pile q; q=(Pile)malloc(sizeof(Maillon)); q->info=c; q->suiv=P; return(q);}char depiler(Pile *P) { Pile q; char c; q=*P; *P=q->suiv; c=q->info; free(q); return(c);}int vide(Pile P){ return (P==NULL);}int main() { char c; Pile P=NULL; for (c=’a’;c<’e’;c++) P=empiler(c,P); while(!vide(P)) { printf("%c n",depiler(&P)); }}1.2 Programmation modulaire L’encapsulation des donn´es est fondamentale d`s que la taille des programmes e eest importante. Cela permet de se concentrer sur l’essentiel. Ainsi, l’ensemble desproc´dures ou fonctions et les donn´es qu’elles manipulent sont regroup´es dans un e e emodule. Un programme est alors constitu´ de diff´rents modules, et la communication e eentre modules se fait ` travers une interface, les d´tails d’impl´mentation de chaque a e emodule ´tant cach´s aux autres modules. On a vu ce principe dans le cours de C avec e eles fichiers d’entˆtes. eSupport de cours programmation Java - GBM2 - 2-
    • 1.2. PROGRAMMATION MODULAIRE Les types abstraits de donn´es (TAD) sont bas´s sur deux id´es : e e e – L’encapsulation : c’est la d´finition d’un type et d’un ensemble d’op´rations e e pour le manipuler ` l’int´rieur d’une unit´ syntaxique (un contenant : fichier, a e e classe, module, package, etc.) – La dissimulation de l’information : c’est le masquage des d´tails d’impl´mentation e e qui ne concernent pas l’utilisateur de l’abstraction. L’encapsulation est utilis´e pour la compilation s´par´e : on regroupe dans un e e efichier les parties d’un programme qui sont s´mantiquement li´es. Lors d’une modi- e efication, on n’a pas ` recompiler tout le programme mais seulement le module qui a achang´. Les TAD sont d´finis par : e e – La sp´cification du type tel que vu de l’ext´rieur, elle d´finit comment utiliser e e e le type (donn´es et op´rations accessibles). Elle d´crit aussi l’interface, ce qui est e e e export´. Les programmes utilisant le TAD importent l’interface pour pouvoir e utiliser le type. – La repr´sentation des objets de ce type (structure de donn´e du type), elle e e d´crit comment les objets du TAD sont construits. e – L’impl´mentation des op´rations qui manipulent les objets de ce type. Il y a e e parfois deux op´rations particuli`res : constructeur et destructeur qui sp´cifient e e e comment cr´er un objet du type et quoi faire quand on veut le d´truire. e e Un bon TAD ne devrait exporter que des op´rations, pas de donn´es (champs). e eEventuellement, les donn´es sont acc´d´es au travers d’op´rations tr`s simples ap- e e e e epel´es fonctions d’acc`s (getters et setters) pour donner une valeur ou extraire la e evaleur d’une donn´e.eRemarque : Les classes du mod`le ` objets sont des TAD. e aExemple de TAD : Type Polynome - Interface Constructeurs ZERO → polynome PLUS(Polynome, entier, reel) → Polynome Autres g´n´rateurs e e ADD(Polynome,Polynome) → Polynome SOUSTR(Polynome,Polynome) → Polynome MULT(Polynome,reel) → Polynome PROD(Polynome,Polynome) → Polynome DERIV(Polynome) → Polynome Fonctions d’acc`s et d’interrogation e NUL(Polynome) → booleen DEGRE(Polynome) → entier COEF(Polynome, entier) → reel VAL(Polynome,reel) → reelSupport de cours programmation Java - GBM2 - 3-
    • ´ 1.3. PROGRAMMATION ORIENTEE OBJETS Dans l’exemple de la pile, on aurait pu impl´menter cette structure avec un etableau, ou encore une liste doublement chaˆ ee... Si, pour un probl`me donn´, on ın´ e ea besoin de cette structure de donn´e, la fa¸on dont elle est mise en oeuvre nous e cimporte peu. Ce qui compte, c’est son comportement (caract´risations des fonctions eempiler, depiler,...). Or, tel que le module pile a ´t´ ´crit, on a le fichier pile.h eeesuivant pour d´crire l’interface. Notez que rien n’empˆche l’utilisateur du module e epile d’acc´der directement aux donn´es (champ info par exemple) : e e// interface du module Pile de caracteres (pile.h)#include <stdio.h>typedef struct elt { char info; struct elt *suiv;} Maillon, *Pile;Pile empiler(char c,Pile P);char depiler(Pile *P);int vide(Pile P);Exemple des formes g´om´triques e eenum type{cercle,triangle,carre}typedef struct{ float l; point c; type f;} forme;float surface(forme x) { switch(x.f) { case cercle : return(PI*l*l); break; case triangle : ..... break; case carre : ..... break; }} L’ajout ou la suppression d’une nouvelle forme am`nent ` reprendre l’ensemble e ades fonctions et ` les adapter. De plus, un cercle a un rayon, un carr´ un cˆt´, un a e oerectangle une longueur et une largeur...1.3 Programmation orient´e objets e Dans l’exemple des piles de caract`res, comment faire lorsqu’on veut utiliser des epiles d’entiers, et non plus de caract`res ? Il faudrait r´´crire un module (alors que, e eefondamentalement, une pile a toujours le mˆme comportement, que ce soit une pile ed’entiers, de caract`res, ou de n’importe quoi). L’approche orient´e objets permet de e eSupport de cours programmation Java - GBM2 - 4-
    • 1.4. JAVA, QU’EST-CE-QUE C’EST ?r´soudre ce probl`me. La POO permet ´galement de r´soudre de fa¸on ´l´gante le e e e e c eeprobl`me pos´ par le petit exemple des formes g´om´triques, et ceci grˆce ` la notion e e e e a ad’h´ritage que l’on verra au chapitre 4. e Les objets sont au coeur de la POO... Un objet a deux caract´ristiques : son e´tat courant et son comportement. Dans l’exemple de la pile de caract`res, l’´tat este e erepr´sent´ par le contenu de la pile, le comportement par les fonctions que l’on peut e eappliquer ` la pile. a L’´tat d’un objet est repr´sent´ par des attributs, son comportement par des e e em´thodes. On ne peut modifier l’´tat d’un objet que par l’utilisation de ses m´thodes ; e e el’encapsulation des donn´es permet de cacher les d´tails d’impl´mentation d’un ob- e e ejet. Ceci dit, cette vue id´ale est trop rigide pour des applications informatiques. eAinsi, en POO, on pourra avoir des attributs priv´s (modifiables uniquement via une em´thode appropri´e) ou publics (accessibles directement par l’ext´rieur). e e e En POO, on utilise le concept de classe, qui permet de regrouper des objets demˆme nature. Par exemple, une pile de caract`res n’est qu’une pile de caract`res e e eparmi d’autres. En POO, on dira que notre pile particuli`re est une instance de la eclasse des objets connus sous le nom de piles de caract`res. Toutes les piles de ca- eract`res ont des caract´ristiques communes mais peuvent ˆtre dans un ´tat diff´rent. e e e e e – Une classe est un moule (on dira prototype) qui permet de d´finir e les attributs (ou champs) et m´thodes communs ` tous les objets de e a cette classe. – Les types abstraits de donn´es dans le mod`le ` objets s’appellent e e a des classes. – Les instances des classes sont des objets (ou instances). – Les op´rations d’une classe sont ses m´thodes. e e attributs surface, couleur... m´thodes e afficher, detruire, changerCouleur... Tab. 1.1 – La classe Forme g´om´trique e eL’h´ritage Une notion fondamentale en POO est la notion d’h´ritage. Si l’on re- e eprend notre exemple des formes g´om´triques, une fa¸on de proc´der est de d´finir la e e c e eclasse FormeGeometrique avec les attributs et comportements communs ` toutes les aformes g´om´triques. La sous-classe Cercle h´rite alors de la classe FormeGeometrique e e eet a ses propres sp´cificit´s. e e1.4 Java, qu’est-ce-que c’est ? Java est compos´ de 4 ´l´ments : e ee – un langage de programmation – une machine virtuelle (JVM)Support de cours programmation Java - GBM2 - 5-
    • 1.4. JAVA, QU’EST-CE-QUE C’EST ? £   FormeGeometrique type (chaine de caracteres) centre (point) couleur (de remplissage) afficher() ¢ ¨ rr ¡ ¨¨¨ r rr ¨ r ¨¨ rr £   ¨ £   ¨ % r j Carre Rectangle longueur £ c   longueur ¢ ¡ Cercle ¢ largeur ¡ rayon ¢ ¡ Fig. 1.1 – Classe m`re et ses sous-classes e – un ensemble de classes standards r´parties dans diff´rentes API (Application e e Programming Interface) – un ensemble d’outils (jdb, javadoc,...).Le langage Java est connu et est tr`s souvent associ´ aux applets que l’on peut voir e esur certaines pages WEB, g´n´ralement de jolies applications graphiques... Il ne faut e epas r´duire Java ` un langage d´di´ aux pages WEB. Il s’agit bien d’un langage ` e a e e apart enti`re, qui vous permettra de r´aliser de vraies applications ! e e Dans ce qui suit, on reprend les adjectifs associ´s ` Java par leurs concepteurs e a(voir http ://java.sun.com/docs/white/langenv/Intro.doc2.html).1.4.1 Simple et familier Java est simple et familier car il n’utilise qu’un nombre restreint de conceptsnouveaux. Sa syntaxe est tr`s proche du langage C. Toutes les embˆches sur lesquelles e ubutte le programmeur en C ou C++ sont ´limin´es, par exemple : e e – seul existe le concept de classe, plus de struct, union et enum, – plus de pointeurs et leur manipulation (avec parfois des pointeurs adressant des emplacements non maˆ es !), ıtris´ – plus de pr´occupation de gestion de la m´moire, Java a un “ramasse-miettes” e e (garbage collector) qui se charge (presque) de restituer au syst`me les zones e m´moires inaccessibles, e – plus de pr´processeur : e – comme Java est ind´pendant de la plateforme (voir plus loin), il n’est plus e n´cessaire d’´crire du code d´pendant de la plateforme, e e e – les fichiers d’entˆte .h n’ont plus lieu d’ˆtre, le code produit contient toutes e e les informations sur les types de donn´es manipul´s. e e – ...1.4.2 Orient´ objets e Enfin, Java est orient´ objets, car un programme Java est compl`tement centr´ e e esur les objets. Mis ` part les types primitifs et les tableaux, en Java tout est objet, aSupport de cours programmation Java - GBM2 - 6-
    • 1.4. JAVA, QU’EST-CE-QUE C’EST ?autrement dit, toutes les classes d´rivent de java.lang.Object. L’h´ritage en Java e eest simple, mais il existe l’h´ritage multiple pour les interfaces. Les objets se mani- epulent via des r´f´rences. Enfin une librairie standard fournit plus de 500 classes au eeprogrammeur (l’API).1.4.3 Interpr´t´, portable et ind´pendant des plateformes e e e C’est justement pour une question de portabilit´ que les programmes Java ne esont pas compil´s en code machine. Le compilateur g´n`re un code appel´ bytecode, e e e ecode interm´diaire qui est ensuite interpr´t´ par la JVM (cf figure 1.2). De plus il e een’y a pas de phase d’´dition de liens ; les classes sont charg´es dynamiquement en e efonction des besoins, au cours de l’ex´cution, de mani`re incr´mentale. La taille des e e etypes primitifs est ind´pendante de la plateforme. e La Java Virtual Machine (JVM) est pr´sente sur Unix, Windows, Mac, Netscape, eInternet Explorer, ... 4 Fichier Bonjour.java 4 public class Bonjour{ BONJOUR ! public static void main(String[ ] arg){ System.out.println(”BONJOUR !”) ; } }  7  7             interpr´teur e   JVM (Java Virtual Machine) compilateur   Fichier Bonjour.class   java Bonjour javac Bonjour.java  ~  Bytecode Fig. 1.2 – Compilation et ex´cution d’un programme Java e1.4.4 Robuste et sˆ r u Il s’agit d’un langage fortement typ´, beaucoup d’erreurs sont donc ´limin´es ` e e e ala compilation. Le ramasse-miettes assure une bonne gestion de la m´moire et il n’y ea pas d’acc`s direct ` la m´moire. Le m´canisme des lev´es d’exceptions permet une e a e e ebonne gestion des erreurs d’ex´cution. Le compilateur est contraignant. e La s´curit´ est prise en charge par l’interpr´teur avec trois niveaux : e e e – Verifier qui v´rifie le code byte e – Class Loader qui est responsable du chargement des classes – Security Manager qui v´rifie les acc`s ressources e eSupport de cours programmation Java - GBM2 - 7-
    • ´ 1.5. ENVIRONNEMENT DE DEVELOPPEMENT1.4.5 Dynamique et multithread Un programme Java est constitu´ de plusieurs classes. Lorsqu’un classe incon- enue dans un programme est requise par celui-ci, la JVM la recherche et la chargedynamiquement. Un thread (appel´ aussi “processus l´ger”) est une partie de code s’ex´cutant en e e econcurrence avec d’autres threads dans un mˆme processus. Cela permet donc ` un e aprogramme unique d’effectuer plusieurs tˆches “simultan´ment”. La notion de thread a eest int´gr´e au langage et aux API. e e1.4.6 Distribu´ e1.5 Environnement de d´veloppement e Le JDK (Java Developer Kit) contient l’ensemble des librairies standards de java(java.lang, java.util, java.awt, ...), le compilateur (javac), un interpr´teur ed’applets (appletviewer), un interpr´teur (java), un g´n´rateur de documentation e e e(javadoc) et quelques autres outils... C’est le minimum pour d´velopper des appli- ecations en Java. Par ailleurs, il existe de nombreux environnement de d´veloppement. On en cite edeux ci-dessous (cf. http ://java.developpez.com/outils/edi/) pour plus de d´tails... e JBuilder de Bordland est tr`s bien plac´ parmi les environnements professionnels e epour le d´veloppement d’applications Java (http ://www.borland.fr/jbuilder/index.html). e Anciennement connu sous le nom de Forte for Java, Sun ONE (Open NetEnvironnement) Studio s’appuie sur le noyau de NetBeans, projet initi´ par Sun e(http ://developers.sun.com/prodtech/devtools/). GNU/Emacs est un ´diteur polyvalent. Pour l’´dition du code, il poss`de de nom- e e ebreux ”modes” : C, C++, HTML, Java, qui vont adapter le fonctionnement d’Emacs.Il dispose d’un grand nombre de fonctions, couramment utilis´es (en programma- etion) : recherche/remplacement (supporte les expressions r´guli`res ), indentation e eautomatique du code, coloration syntaxique, (Re)d´finition des raccourcis claviers, eauto-compl´tion, gestion du multifenˆtrage, etc... ( plus de 1600 fonctions assur´es e e e). Nous choisirons de travailler avec cet ´diteur et de compiler et ex´cuter en ligne e ede commande.Support de cours programmation Java - GBM2 - 8-
    • Chapitre 2Syntaxe de base Dans ce chapitre, on introduit la syntaxe de base du langage. Vous verrez qu’elleest assez proche de celle du langage C, avec quelques ajouts et diff´rences. Ce qui echange radicalement, c’est l’approche orient´e objets, ce sera l’objet du chapitre esuivant.2.1 Unit´s lexicales e Le compilateur Java reconnait cinq types d’unit´s lexicales : les identificateurs, eles mots r´serv´s, les litt´raux, les op´rateurs et les s´parateurs. e e e e e2.1.1 Jeu de caract`res e Java utilise le jeu de caract`res Unicode. Les caract`res sont cod´s sur 16 bits e e e(au lieu de 7 pour le code ASCII). Ce code a ´t´ introduit pour tenir compte de tous ee(ou presque !) les alphabets.2.1.2 Commentaires Java reconnait trois types de commentaires : – les commentaires sur une ligne : tous les caract`res suivants //... jusqu’` la e a fin de la ligne sont ignor´s e – les commentaires multilignes : tous les caract`res entre /* ... et...*/ sont e ignor´s e – les commentaires de documentation : quand ils sont plac´s juste avant une e d´claration, les caract`res entre /** ...et...*/ sont inclus dans une docu- e e mentation g´n´r´e automatiquement par l’utilitaire javadoc. e ee2.1.3 Identificateurs Les identificateurs ne peuvent commencer que par une lettre, un soulign´ (’ ’) ou eun dollar (’$’). Les caract`res suivants peuvent ˆtre des lettres ou des chiffres ou tout e ecaract`re du jeu Unicode de code sup´rieur ` H00C0. e e a 9
    • ´ 2.1. UNITES LEXICALESExemples : x Bidule Bidule $BiduleNote : on convient de r´server des noms commen¸ant par une majuscule aux classes, e cles noms compos´s sont sous la forme “NomCompos´” ou bien “nomCompos´”, et de e e efa¸on g´n´rale, on conseille de nommer les variables et m´thodes de fa¸on parlante. c e e e c2.1.4 Mots r´serv´s e e Les identificateurs du tableau suivant sont des mots cl´s du langage et sont ` ce e atitre des mots r´serv´s que vous ne pouvez en aucun cas utiliser comme identifica- e eteurs. abstract double int super boolean else interface switch break extends long synchronized byte final native this case finally new throw catch float package throws char for private transient class goto * protected try const * if public void continue implements return volatile default import short static do instanceof while* indique un mot cl´ qui n’est pas utilis´ dans les versions actuelles e e Il y a encore trois mots r´serv´s du langage qui ne sont pas des mots cl´s mais e e edes litt´raux :true false et null. e2.1.5 Types primitifs simples Toute variable ou expression a un type qui permet de d´finir l’ensemble des valeurs eet des actions l´gales. Java a un petit nombre de types pr´d´finis appel´s aussi types e e e eprimitifs, le m´canisme des classes et interfaces permet ensuite de d´finir d’autres e etypes. Java a deux sortes de types : les types simples, atomiques (entiers, r´els, bool´ens e eet caract`res) et les types composites (tableaux, classes et interfaces). eSupport de cours programmation Java - GBM2 - 10-
    • ´ 2.1. UNITES LEXICALESCaract`res e Le type caract`re est char. Il est repr´sent´ sur 16 bits (jeu de caract`res Uni- e e e ecode).Bool´ens e Le type bool´en est boolean. Les deux seules valeurs qu’il peut prendre sont true eet false. Il s’agit du type retourn´ par les op´rateurs relationnels (cf.2.3.4). e eEntiers Ils sont tr`s similaires ` ceux de C, sinon qu’ils sont ind´pendants de la plate- e a eforme. Les 4 types d’entiers sont : – byte =⇒ entier sur 8 bits (compl´ment ` 2) e a – short =⇒ entier sur 16 bits (compl´ment ` 2) e a – int =⇒ entier sur 32 bits (compl´ment ` 2) e a – long =⇒ entier sur 64 bits (compl´ment ` 2) e aR´els e Il n’y a que deux types de r´els en Java : e – float=⇒ repr´sent´ sur 32 bits e e – double=⇒ repr´sent´ sur 64 bits e e2.1.6 Constantes litt´rales eConstantes bool´ennes e On l’a vu, les seules possibles sont true et falseConstantes caract`res e Elles sont constitu´es d’un caract`re ou une s´quence d’´chappement entre des e e e eguillemets simples : ’a’, ’b’,... ’’’, ’"’, ’’ ’n’ nouvelle ligne ’t’ tabulationConstantes enti`res e Elles peuvent s’´crire e – en notation d´cimale : 123, -123 e – en notation octale avec un z´ro en premi`re position : 0123 e eSupport de cours programmation Java - GBM2 - 11-
    • 2.2. LES VARIABLES – en notation hexad´cimale, avec les caract`res 0x ou 0X au d´but : 0xDead, e e e 0XbaBA Le type d’une constante est toujours int, pour pr´ciser qu’une constante est de etype long, la faire suivre de l ou L (par exemple, 1L, 0x7FFL,...).Constantes r´elles e Elles se pr´sentent sous la forme d’une partie enti`re suivie d’un point (.), suivi e ed’une partie d´cimale, d’un exposant et un suffixe de type. L’exposant est un E ou e esuivi d’un entier. 3.1415, 3.1E12, .1E-4 2.0d (ou 2.0D) est un r´el double e 2.0f (ou 2.0F) est un r´el float eConstantes chaˆ ınes de caract`res e Une chaˆ de caract`res est une suite de caract`res d´limit´e par des guillemets. ıne e e e eAttention, en Java les chaˆ ınes de caract`res sont des objets et forment ` ce titre e aun type ` part enti`re, il ne s’agit pas d’un tableau de caract`res. On verra la classe a e eString plus loin (6)2.2 Les variables Toute variable doit avoir ´t´ d´clar´e. La d´claration d’une variable consiste ` ee e e e alui donner un nom et un type, ´ventuellement une valeur initiale et un qualificatif. eLa d´claration alloue la place m´moire n´cessaire au stockage, la taille d´pendant du e e e etype. Java distingue diff´rentes natures de variables (pas n´cessairement incompa- e etibles) : – les variables d’instances, – les variables de classe, – les param`tres de m´thodes, e e – les param`tres de constructeurs, e – les variables de type exception, – les variables locales. Le qualificatif final permet d’interdire la modification ult´rieure d’une variable. e La d´claration des variables locales se fait dans le bloc o` elles sont utilis´es, elles e u esont alors visibles ` partir de leur d´claration jusqu’` la fin du bloc. a e a...for(int i=0;i<10;i++) { ... // i est visible dans ce bloc}...Support de cours programmation Java - GBM2 - 12-
    • ´ 2.3. EXPRESSIONS ET OPERATEURS Il n’y a pas vraiment de notion de variable globale en Java. Toute d´claration de evariable se trouve n´cessairement dans la d´claration d’un classe. Seules les variables e equalifi´es de static (dites de classe) et public peuvent ressembler aux variables eglobales de C et C++.2.3 Expressions et op´rateurs e Les expressions en Java ressemblent beaucoup ` celles que l’on ´crit en C. Elles a esont compos´es de constantes, variables et op´rateurs, assembl´s “correctement”. e e e L’essentiel d’un programme consiste ` ´valuer des expressions pour produire ce aequ’on appelle des effets de bord, ou pour calculer des valeurs. Une expression aveceffet de bord est une expression qui, lorsqu’elle est ´valu´e, produit un changement e ede l’´tat du syst`me. Par exemple, l’affectation est une expression qui a pour effet e ede bord la modification du contenu de l’op´rande gauche. e Le r´sultat de l’´valuation d’une expression est soit une valeur, soit une variable e e(une lvalue, (pour left ou location value) une adresse, membre gauche d’une affecta-tion, ` opposer ` une rvalue qui est une valeur), soit void. Ce dernier cas apparaˆ a a ıtlors de l’invocation d’une m´thode qui ne retourne rien. e2.3.1 Priorit´ des op´rateurs et ordre d’´valuation e e e Les op´rateurs, de la priorit´ la plus forte ` la plus faible sont donn´s dans le e e a etableau 2.3. Introduire des parenth`ses rend souvent l’expression plus lisible, et dans etous les cas l`ve les ambiguit´s. L’ordre d’´valuation est important. A part dans le e e ecas des op´rateurs && || et ? : les op´randes de chaque op´ration sont compl`tement e e e e´valu´es avant d’effectuer l’op´ration. Java garantit ´galement que les op´randes sonte e e e e´valu´es de gauche ` droite (dans l’expression x + y, x est ´valu´ avant y). Ceci este e a e eimportant lorsqu’on a des expressions avec effets de bord. Les op´rateurs de Java esont d´taill´s plus loin (2.3.4). e e2.3.2 Type d’une expression Toute expression a un type, connu d`s la compilation. Ce type est d´termin´ par e e ecelui des op´randes et par la s´mantique des op´rateurs. Si le type d’une expres- e e esion n’est pas appropri´, cela conduit ` une erreur de compilation. Par exemple, si e al’expression dans une structure de test if n’est pas de type boolean, le compila-teur produit une erreur. Dans d’autres cas, plutˆt que de demander au programmeur od’indiquer une conversion de type explicite, Java produit une conversion implicitedu type de l’expression en un type qui convient au contexte. Il existe ainsi plusieurssortes de conversions implicites. Les conversions d’un type primitif ` un type primitif plus large pour lesquelles aon ne perd pas d’information : – byte → short,int,long,float, ou double – short → int, long, float, ou doubleSupport de cours programmation Java - GBM2 - 13-
    • ´ 2.3. EXPRESSIONS ET OPERATEURS – char → int, long, float, ou double – int → long, float, ou double – long → float ou double – float → doubleLes conversions d’un type primitif ` un type primitif plus restreint pour lesquelles aon perd de l’information, ou de la pr´cision : e – byte → char – short → byte ou char – char → byte ou short – int → byte, short, ou char – long → byte, short, char, int – float → byte, short, char, int,ou long – double → byte, short, char, int,long, float Pour les conversions sur les r´f´rences, nous verrons cela plus loin... ee2.3.3 Erreur d’´valuation d’une expression e L’´valuation d’une expression peut conduire ` une erreur, dans ce cas Java lance e aune exception qui pr´cise la nature de l’erreur (voir chapitre 7). e OutOfMemoryError espace m´moire requis insuffisant e ArrayNegativeSizeException une dimension de tableau est n´gative e NullPointerException valeur de r´f´rence ` null ee a IndexOutOfBoundsException valeur d’indice de tabelau hors des bornes ClassCastException op´ation de cast interdite r ArithmeticException division par z´ro e ArrayStoreException affectation ` un ´l´ment de tableau d’une r´f´rence a ee ee de type incompatible des exceptions g´n´r´es par l’invocation d’une m´thode e ee e des exceptions g´n´r´es par les constructeurs e ee bien d’autres !... Tab. 2.1 – Exemples de lev´es d’exceptions e2.3.4 Op´rateurs e Le tableau 2.2 pr´sente tous les op´rateurs du langage, avec leur ordre d’´valuation e e eet leur s´mantique. Il manque dans ce tableau les op´rateurs : e e – les op´rateurs d’affectation (+=, -=, *=, ...) dont l’´valuation est faite de droite e e a ` gauche, – les op´rateurs de manipulation de bits : e & (ET bit ` bit), | (OU bit ` bit), ∧ (OU exclusif bit ` bit) et ∼ (compl´mentation a a a e bit ` bit), aSupport de cours programmation Java - GBM2 - 14-
    • ˆ 2.4. STRUCTURES DE CONTROLE << >> >>> de d´calage des bits ; e – l’op´rateur ternaire conditionnel (si-alors-sinon) : cond ?expr1 :expr2 e Op´rateur(s) e Ordre Type Description = D/G variable affectation * / % G/D arithm´tique e multiplication, division, reste + - G/D arithm´tique e addition, soustration + - G/D arithm´tique e plus, moins unaires ++ - - G/D arithm´tique e pr´ et post incr´ment, d´cr´ment1 e e e e < > ≤ ≥ G/D arithm´tique e comparaison arithm´tique e == != G/D objet, type primitif comparaison ´gal et diff´rent e e + G/D chaˆınes de caract`res e concat´nation e ! D/G bool´en e non bool´en e & ∧ | G/D bool´en e ET, OU exclusif, OU (les 2 op´randes sont ´valu´es) e e e && || G/D bool´ens e ET, OU conditionnels (l’op´rande e de droite n’est pas n´cessairement ´valu´e) e e e Tab. 2.2 – Op´rateurs de Java e2.4 Structures de contrˆle o2.4.1 Instructions et blocs d’instructions Un programme Java est constitu´ de d´clarations de classes dans lesquelles fi- e egurent des m´thodes. Ces derni`res sont construites ` l’aide d’instructions combin´es e e a eentre elles par des structures de contrˆle. o Une instruction est une expression suivie d’un point virgule. Les instructionscompos´es ou blocs d’instructions sont des suites d’instructions simples ou compos´es e ed´limit´es par des accolades { et }. L’accolade fermante n’est pas suivie de point e evirgule.Exemple :{ int i; i=4; System.out.println("coucou ! "); System.out.println("i vaut "+i);} 1 la valeur d’une expression de post-incr´ment est la valeur de l’op´rande et a pour effet de bord e ele stockage de la valeur de l’op´rande incr´ment´e de 1, la valeur d’une expression de pr´-incr´ment e e e e eest la valeur de l’op´rande incr´ment´e de 1 et a pour effet de bord le stockage de cette valeur. e e eC’est similaire pour le d´cr´ment. e eSupport de cours programmation Java - GBM2 - 15-
    • ˆ 2.4. STRUCTURES DE CONTROLE op´rateurs postfixes e [] . (params) expr++ expr– op´rateurs unaires e ++expr –expr +expr -expr ∼ ! cr´ation ou cast e new (type)expr op´rateurs multiplicatifs e * / % op´rateurs additifs e + - op´rateurs de shift e << >> >>> op´rateurs relationnels e < > <= >= instanceof op´rateurs d’´galit´ e e e == != ET bit ` bit a & OU exclusif bit ` bit a ∧ OU inclusif bit ` bit a | ET logique && OU logique || op´rateur conditionnel e ?: affectations = += -= *= /= %= &= ∧= |= <<= >>= >>>= Tab. 2.3 – Op´rateurs dans l’ordre d´croissant de priorit´ e e e L’objet de cette section est de passer bri`vement en revue toutes les structures ede contrˆle (vous les connaissez d´j`). o ea2.4.2 Instruction conditionnelle : if Elle permet d’ex´cution des instructions de mani`re s´lective, en fonction du e e er´sultat d’un test. eif (expression) instruction1if (expression) instruction1 else instruction22.4.3 Etude de cas : switch Elle permet de choisir un bloc d’instruction selon la valeur d’une expressionenti`re : eswitch (expression) { case cste1 : instruction1 case cste2 : instruction2 ... case csteN : instructionN default :Support de cours programmation Java - GBM2 - 16-
    • ˆ 2.4. STRUCTURES DE CONTROLE instructionDefaut} Attention, si la valeur de expression vaut csteI, instructionI sera ex´cut´e e eainsi que toutes les suivantes (instructionI+1...instructionDefaut) sauf si uneinstruction break a ´t´ rencontr´e. L’exemple suivant illustre le fonctionnement de ee ecette structure de contrˆle : oExemple :char c;...switch (c) { case ’1’: case ’2’: case ’3’: // notez l’absence d’intruction case ’5’: case ’7’: System.out.println(c+"est un nombre premiern"); break; // notez l’instruction break case ’6’: System.out.println(c+"est un multiple de 3n"); // notez l’absecnce de break case ’4’: case ’8’: System.out.println(c+"est un multiple de 2n"); break; case ’9’: System.out.println(c+"est un multiple de 3n"); break; default : System.out.println(c+"n’est pas un chiffre non nuln");}...2.4.4 It´rations : while, do...while et for e La structure de contrˆle while ´value une condition et ex´cute l’instruction tant o e eque cette condition reste vraie.while (condition) instructionExemple :Support de cours programmation Java - GBM2 - 17-
    • ˆ 2.4. STRUCTURES DE CONTROLEint i=10;while (i>=0) { System.out.println(i); i=i-1;} L’instruction do...while est une variante de la pr´c´dente. Une it´ration est e e etoujours ex´cut´e. Il faut la traduire en fran¸ais par Faire... tant que. Attention de e e cne pas confondre avec la structure r´p´ter...jusqu’` ce que ! e e ado instructionwhile (condition)Exemple :int i=-1;do { System.out.println(i); i=i-1;} while (i>=0); Enfin, l’instruction for qui comporte une initialisation, une condition d’arrˆt, et eune ou des instructions de fin de boucle :for (instruction1;condition_de_poursuite;instruction2) instruction3est ´quivalente ` : e ainstruction1;while (condition_de_poursuite) { instruction3 instruction2} La virgule (,) est utilis´e pour combiner plusieurs initialisations et plusieurs ins- etructions de fin de boucle.2.4.5 Etiquettes, break, continue et return Toute instruction peut ˆtre ´tiquet´e. e e elabel : instruction L’instruction break d´j` vue avec le switch est utilis´e aussi dans les structures ea ede boucle et permet la sortie imm´diate de la boucle, sans tenir compte des conditions ed’arrˆt de cette derni`re. Une variante permet d’associer une ´tiquette ` l’instruction e e e abreak.Support de cours programmation Java - GBM2 - 18-
    • 2.5. STRUCTURE D’UN PROGRAMME AUTONOME JAVAlabel : instruction1while(...){...break label;...} Ceci dit, l’usage des ´tiquettes et du break est fortement d´conseill´, ce n’est e e epas ´l´gant, cela nuit ` la lisibilit´ du programme, c’est contraire aux principes de la ee a eprogrammation structur´e ! La plupart du temps, on peut s’en passer. e L’instruction continue apparaˆ dans les structures de boucles. Elle produit ıtl’abandon de l’it´ration courante et, si la condition d’arrˆt n’est pas satisfaite, le e ed´marrage de l’it´ration suivante. e e L’instruction return quant ` elle est indispensable ! Elle provoque l’abandon de ala fonction en cours et le retour ` la fonction appelante. Quand elle est suivie d’une aexpression, le r´sultat de cette expression est la valeur que la fonction appel´e renvoie e ea` la fonction appelante. Mais attention, il est d´conseill´ de placer une instruction e ereturn dans le corps d’une boucle, cela signifie que vous n’avez probablement pasbien ´crit la condition de sortie de la boucle ! e2.5 Structure d’un programme autonome Java Un programme Java est constitu´ d’une ou plusieurs classes. Parmi ces classes, il edoit y en avoir au moins une qui contienne la m´thode statique et publique main qui eest le point d’entr´e de l’ex´cution du programme. Voici un exemple (l’in´vitable !) : e e eExemple :// Fichier Bonjour.javapublic class Bonjour { public static void main(String[] arg) { System.out.println("Bonjour !n"); }} On a d´fini une classe Bonjour qui ne poss`de qu’une seule m´thode. La m´thode e e e emain doit ˆtre d´clar´e static et public pour pouvoir ˆtre invoqu´e par l’in- e e e e eterpr´teur Java. L’argument arg est un tableau de chaˆ e ınes de caract`res qui corres- epond aux arguments de la ligne de commande lors du lancement du programme. Avant tout, il faut compiler ce programme avec la commande javac :javac Bonjour.java La compilation traduit le code source en byte code. Le compilateur produit autantde fichiers que de classes pr´sentes dans le fichier source. Les fichiers compil´s ont e el’extension .class.Support de cours programmation Java - GBM2 - 19-
    • 2.5. STRUCTURE D’UN PROGRAMME AUTONOME JAVA Enfin, pour ex´cuter le programme, il faut utiliser l’interpr´teur de code Java et e elui fournir le nom de la classe public que l’on veut utiliser comme point d’entr´e : ejava BonjourSupport de cours programmation Java - GBM2 - 20-
    • Chapitre 3Classes et Objets En C on utilise des structures pour cr´r des TAD (Types Abstraits de Donn´es), e eou structures de donn´es complexes. Dans les langages orient´s objets, on utilise le e econcept de classes. Elle permettent de d´finir de nouveaux types de donn´es qui se e ecomportent comme des types pr´d´finis et dont les d´tails d’impl´mentation sont e e e ecach´s aux utilisateurs de ces classes. Seule l’interface fournie par le concepteur peut eˆtre utilis´e.e e Un objet est une instance d’une classe (qui peut ˆtre vue comme un moule). Les eobjets communiquent entre eux par des messages qui sont ´valu´s par des m´thodes. e e eCes messages ´valu´s par des m´thodes de l’objet, induisent des modification de son e e e´tat ou de son comportement. Les objets vivent en famille, et peuvent donc h´ritere edes caract´ristiques de leurs ancˆtres, en affinant (sp´cialisant) ces caract´ristiques. e e e eUn objet est caract´riq´ par : e e – un ensemble d’attributs, typ´s et nomm´s repr´sentant des propri´t´s statiques. e e e ee L’ensemble des valeurs des attributs consitue l’´tat de l’objet, e – un ensemble de m´thodes, d´finissant son comportement et ses r´actions ` e e e a des stimulations externes. Ces m´thodes impl´mentent les algorithmes que l’on e e peut invoquer sur ces objets, En Java, on ne peut acc´der ` un objet que par une r´f´rence vers celui-ci. Une e a eer´f´rence est une sorte de pointeur vers la structure de donn´es, avec la diff´rence qu’il ee e eest interdit de manipuler les r´f´rences comme les pointeurs en C ou C++. On ne peut eepas connaˆ la valeur d’une r´f´rence, ni effectuer d’op´rations arithm´tiques. La ıtre ee e eseule manipulation possible consiste ` changer la valeur de la r´f´rence pour qu’elle a ee“fasse r´f´rence” ` un autre objet. ee a Une classe est un moule d’objets, elle en d´crit la partie priv´e (structure de e edonn´es interne ou attributs et corps des m´thodes), et la partie publique (nom e eet param`tres des m´thodes). C’est un g´n´rateur d’objets, on peut ainsi cr´er un e e e e eensemble d’objets rentrant dans ce moule.3.1 D´claration des classes e Basiquement, une classe d´finit : e 21
    • ´ 3.1. DECLARATION DES CLASSES – les structures de donn´es associ´es aux objet de la classe, les variables d´signant e e e ces donn´es sont appel´es champs ou attributs, e e – les services ou comportements associ´s aux objets de la classe qui sont les e m´thodes, d´finies dans la classe. e e3.1.1 Champs ou attributs Java poss`de trois mots cl´s pour l’encapsulation des donn´es (les droits d’acc`s) : e e e epublic, private et protected. Nous les reverrons plus en d´tail, mais retenez ici que eles donn´es et m´thodes d´clar´es public sont accessibles par toutes les classes. In- e e e eversement, les donn´es et m´thodes d´clar´es private ne sont accessibles que par les e e e em´thodes de cette classe. Enfin, le mot cl´ protected institue une notion de “famil- e ele”. Supposons que nous voulions d´clarer une structure de donn´es Date constitu´e e e ede trois entiers codant le jour, le mois et l’ann´e : eclass Date{ private int mois; private int jour; private int annee; ...} Les donn´es mois, jour et ann´e ont ´t´ d´clar´es priv´es. Elles ne seront acces- e e ee e e esibles que par des m´thodes d´finies de la classe Date dans la section qui suit. e e3.1.2 M´thodes e Elles sont d´finies par un identificateur, des param`tres formels, un type de retour, e eun corps et ´ventuellement un qualificatif (comme pour les champs) public, private eou protected.class Date{ private int mois; private int jour; private int annee; ... public void affecter(int m, int j, int a) { mois=m; jour=j; annee=a; } public int quelJour(){return jour;} public int quelMois(){return mois;} public int quelleAnnee(){return annee;} public void imprimer(){ System.out.println(jour+"/"+mois+"/"+annee); }}Support de cours programmation Java - GBM2 - 22-
    • ´ 3.1. DECLARATION DES CLASSES La m´thode affecter fait partie de la classe Date, il lui est donc permis d’acc´der e ea` ses champs priv´s. Et cette m´thode, puisqu’elle est d´clar´e public, permet de e e e emodifier les champs d’un objet de la classe Date. Les m´thodes publiques d’une classe econstituent ce que l’on appelle son interface publique. Contrairement au langage C++ la d´finition effective des m´thodes de la classe e edoit se faire dans la d´finition de la classe. e Une m´thode est un message envoy´ ` un objet. Ainsi, pour afficher la date e e acontenue dans l’objet d, on lui envoie le message imprimer :d.imprimer();De telles m´thodes sont appel´es m´thodes d’instances, elles sont ´voqu´es via un ob- e e e e ejet. Nous verrons plus loin qu’il existe des m´thodes de classes. La m´thode imprimer e en’est utilisable que parce qu’elle fait partie des m´thodes publiques. Par contre, il ne esera pas possible d’acc´der aux champs d.jour, d.mois et d.annee car ce sont des edonn´es priv´es. e e3.1.3 Cr´ation d’objets e Une fois la classe d´clar´e, pour pouvoir utiliser un objet de cette classe, il faut e ed´finir une instance de cette classe. La d´claration suivante ne fait que d´finir une e e er´f´rence vers un objet ´ventuel de la classe Date : ee eDate d;La variable d repr´sente une r´f´rence vers un objet de type Date qui doit ˆtre e ee einstanci´ (cr´´) explicitement avec le mot cl´ new et le constructeur (cf. section3.1.4) e ee ede la classe Date :Date d; //d´claration de la r´f´rence d e e ed = new Date(); // instanciation de l’objet r´f´renc´ par d e e e3.1.4 Constructeurs On a dit que pour d´finir un objet d’une classe, il fallait faire appel ` son construc- e ateur. En l’absence de constructeur(s) explicite(s), un constructeur implicite, sansargument, est invoqu´ par d´faut. e e Lorsque l’on veut d´finir un objet, il est souvent utile de pouvoir initialiser cet eobjet. Dans notre exemple de la classe Date, il est possible d’utiliser la m´thodeeaffecter pour donner une valeur aux champs d.jour, d.mois et d.annee. Date aujourdhui=new Date(); aujourdhui.affecter(8,25,1961);Mais ce n’est pas tr`s agr´able. Le constructeur est une m´thode sp´cifique qui est e e e eautomatiquement appel´e lors de la cr´ation d’un objet. Elle a la particularit´ de e e eporter le mˆme nom que la classe, d’ˆtre publique et n’a pas de valeur de retour. e eSupport de cours programmation Java - GBM2 - 23-
    • ´ 3.1. DECLARATION DES CLASSESclass Date { ... public Date(int j, int m, int a) { jour=j; mois=m; annee=a;} ...} Maintenant, pour cr´er un objet de type Date il faudra fournir imp´rativement e ele jour, le mois et l’ann´e. On peut contourner ce probl`me en fournissant plusieurs e econstructeurs :class Date { ... public Date(int j, int m, int a) { jour=j; mois=m; annee=a;} public Date(int j, int m) { jour=j; mois=m; annee=2000;} public Date(int j) { jour=j; mois=1; annee=2000;} public Date() { jour=1; mois=1; annee=2000;} ...}3.1.5 Destructeurs En g´n´ral, en Java, on n’a pas ` se soucier de la restitution de l’espace m´moire e e a eoccup´ par un objet qui n’est plus r´f´renc´. On a d´j` ´voqu´ le “ramasse-miettes” e ee e eae e(garbage collector) qui est un syst`me de r´cup´ration de m´moire automatique. Par e e e ed´faut, ce syst`me tourne en arri`re-plan pendant l’ex´cution de vos programmes. Il e e e erep`re les objets qui ne sont plus r´f´renc´s, et lib`re l’espace en m´moire allou´ ` e ee e e e eaceux-ci. Vous pouvez d´sactiver le ramasse-miettes (option -noasyngc sur la ligne ede commande de lancement de la JVM). Selon les applications, un objet peut bloquer d’autres types de ressources que lam´moire (descripteur de fichiers, socket, ...), il est alors bon d’utiliser un destruc- eteur pour lib´rer ces ressources. De plus, vous pouvez ne pas vouloir attendre que ele ramasse-miettes lib`re des ressources critiques. Il existe une m´thode sp´cifique e e efinalize qui est un destructeur et red´finit la m´thode protected void finalize e ede la classe Object. Une classe peut donc impl´menter une m´thode finalize qui e eest d´clar´e de la fa¸on suivante : e e cprotected void finalize() throws Throwable { super.finalize(); ...} Ce code s’´claircira plus tard, avec les notions d’h´ritage et d’exceptions. e eSupport de cours programmation Java - GBM2 - 24-
    • ´ 3.2. DEFINITIONS DE CHAMPS3.2 D´finitions de champs e3.2.1 Champs de classe Si l’on d´finit trois objets de type Date, chacun aura ´videmment son propre jeu e ede valeurs pour les champs jour, mois, annee. De tels champs sont appel´s variables e(ou attributs) d’instances. Il est des cas o` il est souhaitable d’avoir une donn´e u ecommune ` tous les objets d’une mˆme classe. Un champ d’une classe est dit static a e(ou de classe) ; il n’y a qu’un seul exemplaire de ce champ pour tous les objets decette classe. Ce champ existe mˆme s’il n’y a aucune instance de la classe. eExemple :class Date{ private int mois; private int jour; private int annee; public static int nbDate=0; public Date(int j, int m, int a){ mois=m; jour=j; annee=a; nbDate++; } public int quelJour(){return jour;} public int quelMois(){return mois;} public int quelleAnnee(){return annee;} public void imprimer(){ System.out.println(jour+"/"+mois+"/"+annee); }}class Programme{ public static void main(String[] arg){ Date aujourdhui=new Date(25,9,2000); Date noel=new Date(25,12,2000); aujourdhui.imprimer(); noel.imprimer(); System.out.println(noel.nbDate); System.out.println(Date.nbDate); }}Voici le r´sultat obtenu : echaouiya@pccc:~/coursJava/Notes_cours$ javac Programme.javachaouiya@pccc:~/coursJava/Notes_cours$ java ProgrammeSupport de cours programmation Java - GBM2 - 25-
    • ´ 3.2. DEFINITIONS DE CHAMPS25/9/200025/12/200022Initialisation des champs de classe Les champs static sont initialis´s une fois lors du chargement de la classe qui eles contient. Une erreur de compilation se produit lorsque : – un champ de classe est initialis´ relativement ` un champ de classe d´fini plus e a e loin class X{ static int x = y+1; // erreur, y est declare apres x static int y =0; static int z=z+1; // erreur } – un champ de classe est initialis´ relativement ` un champ d’instance e a class X{ public int x=120; static int y=x+10; // erreur, x variable d’instance }Initialisation des champs d’instance Les champs d’instance sont initialis´s lors de l’instanciation (` la cr´ation) des e a eobjets de la classe. Contrairement aux champs de classe, chaque instanciation pro-voque l’intialisation des champs de l’objet cr´´. Une erreur de compilation se produit eesi un champ d’instance est initialis´ par r´f´rence ` un champ d’instance d´fini plus e ee a eloin. On peut utiliser les valeurs des champs de classe pour initialiser des champsd’instance.3.2.2 Mot cl´ this e Il d´signe l’objet sur lequel la m´thode est invoqu´e. On peut par exemple r´´crire e e e eela m´thode affecter comme suit : e public void affecter(int m, int j, int a) { this.mois=m; this.jour=j; this.annee=a; } Dans l’exemple qui suit, l’int´rˆt du mot cl´ this est certainement mieux illustr´. ee e eOn cr´e une liste chaˆ ee de tous les objets de type Date qui ont ´t´ instanci´s : e ın´ ee eclass Date{Support de cours programmation Java - GBM2 - 26-
    • ´ ´ 3.3. DEFINITION DE METHODES private int mois; private int jour; private int annee; private Date suivant; public static Date listeDates=null; public Date(int j, int m, int a){ jour=j; mois=m; annee=a; suivant=listeDates; listeDates=this; } public void imprimer(){ System.out.println(jour+"/"+mois+"/"+annee); }}class Test { public static void main(String[] arg){ Date noel=new Date(25,12,2000); Date aujourdhui=new Date(25,9,2000); for (Date d=Date.listeDates; d!=null; d=d.suivant) d.imprimer(); }}3.2.3 Champs final Un champ peut ˆtre d´clar´ final pour indiquer qu’il ne peut pas ˆtre modif´, et e e e e egardera donc une valeur constante. Leur initialisation doit se faire de la mˆme fa¸on e cque pour les champs de classe.3.3 D´finition de m´thodes e e3.3.1 Le passage des param`tres e Tous les param`tres sont pass´s par valeur. Les seuls types possibles de param`tres e e esont les types primitifs et les r´f´rences. Autrement dit : ee – les types primitifs sont pass´s par valeur. Une m´thode ne peut donc jamais e e modifier la valeur d’une variable de type primitif, – les r´f´rences ´galement sont pass´es par valeur (valeur de la r´f´rence vers ee e e ee l’objet). Si la m´thode modifie un champ de l’objet r´f´renc´, c’est l’objet qui e ee e est modifi´, et le code appelant voit donc l’objet r´f´renc´ modifi´. e ee e e3.3.2 Signature et polymorphisme Contrairement ` ce que vous connaissez en C, un mˆme identificateur peut ˆtre a e eutilis´ pour d´signer deux m´thodes ` condition que leur signature soit diff´rente. e e e a eSupport de cours programmation Java - GBM2 - 27-
    • ´ ´ 3.3. DEFINITION DE METHODESOn appelle signature d’une m´thode, la donn´e de son nom, du nombre de ses pa- e eram`tres formels et de leurs types. eint methode1(int i){...} // erreur, type retour de la methode nefloat methode1(int i){...} // fait pas partie de sa signatureint methode2(int i){...}float methode2(float f){...} //OKint methode3(int i) {...}int methode3(int i, int j) {...} //OK3.3.3 Variables locales Les variables locales sont allou´es lors de l’invocation de la m´thode et sont e ed´truites ` la fin de celle-ci. Ces variables ne sont visibles qu’` l’int´rieur de la e a a em´thode ou du bloc d’instructions o` elles sont d´clar´es. e u e e3.3.4 M´thodes de classe e Les m´thodes vues juqu’` pr´sent s’appliquent toujours ` une r´f´rence sur un ob- e a e a eejet. Les m´thodes qualifi´es de static sont celles qui n’ont pas besoin d’une instance e epour ˆtre invoqu´es. e e Comme toute m´thode, une m´thode de classe est membre d’une classe. Elle est e einvoqu´e en lui associant, non pas un objet mais la classe ` laquelle elle appartient. e aPar exemple, la m´thode sqrt qui calcule la racine carr´e appartient ` la classe Math. e e aPour l’invoquer on ´crit : Math.sqrt(x) ; e Une m´thode static, puisqu’elle ne s’applique pas sur un objet, ne peut acc´der e eaux variables d’instances. De mˆme, le mot cl´ this n’a pas de sens dans une m´thode e e estatic.class Date{ private int mois; private int jour; private int annee; private Date suivant; public static Date listeDates=null; public Date(int j, int m, int a){ jour=j; mois=m; annee=a; suivant=listeDates; listeDates=this; } ... public void imprimer(){ System.out.println(jour+"/"+mois+"/"+annee); } public static void listerDate(){Support de cours programmation Java - GBM2 - 28-
    • ´ ´ 3.3. DEFINITION DE METHODES for (Date d=Date.listeDates; d!=null; d=d.suivant) d.imprimer();* }}class Test { public static void main(String[] arg){ Date noel=new Date(25,12,2000); Date aujourdhui=new Date(25,9,2000); Date.listerDate(); }}Support de cours programmation Java - GBM2 - 29-
    • Chapitre 4H´ritage e4.1 Introduction La notion d’h´ritage est fondamentale en POO. Elle permet de sp´cialiser des e eclasses. Reprenons l’exemple de la classe Date, et supposons que nous devions main-tenant d´finir une classe DateAnniversaire, qui associe ` une date donn´e le nom e a eet le pr´nom d’une personne n´e ` cette date. Une premi`re solution consisterait ` e e a e ad´finir compl`tement la nouvelle classe : e eclass DateAnniversaire{ private int mois; private int jour; private int annee; private String nom; private String prenom; public DateAnniversaire(int j,int m,int a,String n,String p) { jour=j; mois=m; annee=a; nom=n; prenom=p; } public affecter(int m,int j,int a,String n,String p) { jour=j; mois=m; annee=a; nom=n; prenom=p; } ... public void imprimer(){ System.out.println(prenom+" "+nom+" est ne le "+jour+"/"+mois+"/"+annee); }} Cette approche va ` l’encontre de l’esprit de la POO. Dans la mesure o` l’on a a ud´j` ´crit une classe Date, il s’agit de la r´utiliser, en la sp´cialisant. C’est l’id´e de eae e e el’h´ritage. Une DateAnniversaire est une Date avec des fonctionnalit´s suppl´mentaires. e e e L’h´ritage est une caract´ristique des langages orient´s objets. Une classe obte- e e enue par h´ritage poss`de la totalit´ des champs et m´thodes de la classe de base e e e e(dont elle h´rite). Une classe B peut donc se d´finir par rapport ` une classe A dont e e aelle h´rite. On dit que la classe B est une sous classe de la classe de base A. Une e 30
    • 4.1. INTRODUCTIONsous classe doit ´videmment compl´ter (enrichir) la classe de base, on parle aussi de e esp´cialisation. Elle d´finit donc des champs et comportements suppl´mentaires, et e e epeut, ´ventuellement, modifier une ou des m´thodes de la classe de base. e e Notre exemple de classe DateAnniversaire poss`de beaucoup de caract´ristiques e ede la classe Date (´videmment, c’est une date !). Elle comporte deux champs suppl´- e ementaires, et les m´thodes (constructeur, m´thodes d’acc`s et de modification) doivent e e eˆtre compl´t´es et/ou adapt´es en fonction de l’ajout de ces nouveaux champs. One ee ed´finira la classe DateAnniversaire comme une sous classe de la classe Date. Cela ese fait en Java grˆce au mot cl´ extends. a e Voici l’exemple complet de la classe DateAnniversaire. Nous y reviendrons parla suite :class Date { protected int mois; protected int jour; protected int annee; public Date(int j, int m, int a) { jour=j; mois=m; annee=a; } public void affecter(int j, int m, int a) { mois=m; jour=j; annee=a; }}class DateAnniversaire extends Date{ private String nom; private String prenom; public DateAnniversaire(int j,int m,int a,String n,String p) { super(j,m,a); nom=n; prenom=p; } public void affecter(int j,int m,int a,String n,String p) { super.affecter(j,m,a); nom=n; prenom=p; } public void imprimer(){ System.out.println(prenom+" "+nom+" est ne(e) le "+super.jour+"/"+super.mois+"/"+super.annee); }}class TestDate{ public static void main(String[] arg){ DateAnniversaire d=new DateAnniversaire(0,0,0,"",""); d.affecter(10,3,1920,"Boris","Vian"); d.imprimer(); }}Support de cours programmation Java - GBM2 - 31-
    • 4.2. RETOUR SUR LES QUALIFICATIFS DE CLASSES ET CHAMPS4.2 Retour sur les qualificatifs de classes et champs Il existe trois qualificatifs (on dit aussi modifieurs) pour les classes : – public : une seule classe ou interface peut ˆtre d´clar´e public par fichier e e e source .java, et par convention, le fichier porte le nom de la classe d´clar´e e e public. Une telle classe est accessible depuis l’ext´rieur (nous reverrons ces e notions avec les paquetages). – final : une classe d´clar´e final ne peut ˆtre d´riv´e (et ne peut donc jamais e e e e e suivre la clause extends). – abstract : une classe d´clar´e abstract ne peut jamais ˆtre instanci´e. Nous e e e e verrons l’int´rˆt de telles classes un peu plus loin. Disons simplement pour le ee moment que leur int´rˆt est de fournir une esp`ce de mod`le pour les classes ee e e d´riv´es. e e Pour les champs, voici les qualificatifs possibles : – public : pour signifier que le champ est accessible partout o` est accessible la u classe dans laquelle il est d´clar´, e e – protected : pour signifier que le champ est accessible par les classes du mˆme e paquetage et les classes d´riv´es de la classe o` il est d´clar´, e e u e e – package : pour signifier que le champ est accessible par les classes du mˆme e paquetage (c’est le qualificatif par d´faut), e – private : pour signifier que le champ n’est accessible qu’` l’int´rieur de la a e classe o` il est d´clar´, u e e – static : pour signifier qu’il s’agit d’un champ de classe, un seul exemplaire est cr´´, ee – final : pour signifier qu’il s’agit d’une constante, – transient : que nous verrons plus tard... lorsque nous aborderons les notions de persistance, – volatile : que nous verrons plus tard... lorsque nous aborderons les notions de processus (threads). Maintenant, vous devez mieux comprendre les qualificatifs donn´s aux champs ede la classe Date.4.3 Constructeur de la sous-classe4.3.1 Invocation du constructeur Lors de la d´finition d’une classe d´riv´e, il faut s’assurer que, lors de l’instancia- e e etion des objets de cette nouvelle classe, les champs propres ` cette classe mais aussi ales champs de la classe de base seront bien initialis´s. Souvent, les champs de la classe ede base sont priv´s et la classe d´riv´e ne peut donc se charger de leur initialisation. e e eSupport de cours programmation Java - GBM2 - 32-
    • ´ 4.4. REDEFINITION ET SURCHARGEAinsi le constructeur de la classe d´riv´e devra faire appel ` celui de la classe de base e e apour l’initialisation de ces champs. Dans notre exemple de dates, on dira que pourcr´er une DateAnniversaire, il faut d’abord cr´er une Date. e e Voici quelques points essentiels : – Le constructeur est appel´ au moment de la cr´ation de l’objet (instanciation). e e Il initialise cet objet en fonction des param`tres fournis. e – Si la classe ne comporte pas de constructeur, Java en cr´e un de fa¸on implicite, e c sans param`tre. Mais attention, si la classe a au moins un constructeur avec e param`tre(s) et aucun sans param`tre, elle n’a alors plus de constructeur par e e d´faut. e – Si, la premi`re instruction du constructeur n’est pas un appel explicite d’un e constructeur de la classe de base (utilisation de super(...), voir plus loin), le constructeur par d´faut de la classe de base est appel´. e e – Si la classe de base n’a pas de constructeur par d´faut (ou de constructeur sans e param`tre), on a une erreur de compilation (j’ai repris l’exemple des dates, et e enlev´ l’appel explicite au constructeur de la classe Date dans celui de la classe e DateAnniversaire) : Date2.java:20: No constructor matching Date2() found in class Date2 public DateAnniversaire(int j,int m,int a,String n,String p) { ^ 1 error4.3.2 Enchaˆ ınement des constructeurs Rappelons que la classe Object est la m`re de toutes les classes : toute classe eest d´riv´e directement ou non de la classe Object. Pour tout objet instanci´, le e e econstructeur de sa classe est invoqu´, lequel,` son tour, invoque le constructeur de sa e aclasse de base et ainsi de suite. Cette cascade d’appels s’arrˆte ´videmment lorsqu’on e eatteint le constructeur de la classe Object.4.4 Red´finition et surcharge e4.4.1 Red´finition des champs e Les champs d´clar´s dans la classe d´riv´e sont toujours des champs suppl´- e e e e ementaires. Si l’on d´finit un champ ayant le mˆme nom qu’un champ de la classe e ede base, il existera alors deux champs de mˆme nom. Le nom de champ d´signera e ecelui d´clar´ dans la classe d´riv´e. Pour avoir acc`s ` celui de la classe de base, il e e e e e afaudra changer le type de la r´f´rence pointant sur l’objet, ou utiliser super. Voici eeun exemple :class A { public int i; ...}class B extends A { public int i;Support de cours programmation Java - GBM2 - 33-
    • ´ 4.4. REDEFINITION ET SURCHARGE ... public void uneMethode(){ i=0; // champ defini dans la classe B this.i=0; // champ defini dans B super.i=1; // champ defini dans A ((A) this).i=1; // champ defini dans A ... }}class C extends B { public int i; ... public void uneMethode(){ i=0; // champ defini dans la classe C this.i=0; // champ defini dans C super.i=1; // champ defini dans B ((B) this).i=1; // champ defini dans B ((A) this).i=1; // champ defini dans A ... }} Mais attention l’instruction suivante est incorrecte ! super.super.i=1 ; De plus, souvenez-vous que comme l’utilisation du mot-cl´ this, le mot-cl´ super e ene peut pas ˆtre utilis´ dans les m´thodes qualifi´es de static. e e e e4.4.2 Red´finition des m´thodes e e On n’est bien sˆr pas tenu de d´clarer de nouveaux champs dans une classe u ed´riv´e, il se peut que seuls les comportements (m´thodes) changent avec de nouvelles e e em´thodes ou des m´thodes red´finies. e e e La red´finition d’une m´thode consiste ` fournir une impl´mentation diff´rente e e a e ede la m´thode de mˆme signature fournie par la classe m`re. e e eExemple :class Fruit{ public String nom; public Fruit(String n) { nom=n; } public void imprimer() { System.out.println("je suis un(e) "+nom); } public String getNom(){ return nom; }}class Pomme extends Fruit{ public Pomme(){Support de cours programmation Java - GBM2 - 34-
    • ´ 4.5. METHODES ET CLASSES FINALES super("pomme"); } public void imprimer() { System.out.println("je suis une "+nom); }}class Test{ public static void main(String[] arg){ Fruit f=new Fruit("ananas"); Pomme p=new Pomme(); f.imprimer(); System.out.println(f.getNom()); p.imprimer(); f=(Fruit)p; f.imprimer(); System.out.println(p.getNom()); System.out.println(f.getNom()); }}/*** exemple d’execution :je suis un(e) ananasananasje suis une pommeje suis une pommepommepomme*/ Quelques pr´cisions suppl´mentaires : e e 1. Pour avoir acc`s ` une m´thode red´finie de la classe de base, il faudra utiliser e a e e le mot cl´ super. e 2. Une m´thode static peut aussi ˆtre red´finie par une autre m´thode static e e e e (mais pas par une m´thode non static). e 3. Les destructeurs (cf. 3.1.5) ne sont pas invoqu´s en chaˆ comme les construc- e ıne teurs, c’est au programmeur, s’il le juge utile de r´aliser cette chaˆ de des- e ıne tructeurs (` l’aide du mot cl´ super). a e4.5 M´thodes et classes finales e Une m´thode est final si elle ne peut ˆtre red´finie par des classes d´riv´es. e e e e eAinsi, on peut figer l’impl´mentation d’une m´thode. On peut aussi d´cider de figer e e ela d´finition d’une classe en la d´clarant final. Cela signifie qu’il ne sera pas possible e ed’en d´river une nouvelle classe. eSupport de cours programmation Java - GBM2 - 35-
    • 4.6. CONVERSIONS ENTRE CLASSES ET SOUS-CLASSES4.6 Conversions entre classes et sous-classes Une op´ration de cast permet de modifier le type d’une r´f´rence. Ces modifica- e eetions ne sont permises que dans des cas pr´cis. On peut ainsi affiner le type d’une er´f´rence. Par exemple une r´f´rence vers un objet de type Date peut ˆtre chang´e en ee ee e eune r´f´rence vers un objet de type DateAnniversaire. L’objet r´f´renc´ est toujours ee ee ele mˆme, on essaie juste de faire croire ` la JVM que l’objet r´f´renc´ est d’une autre e a ee enature. En aucun cas, l’objet r´f´renc´ n’est modifi´ par le cast. On ne peut changer ee e ele type d’une r´f´rence en une r´f´rence vers un objet d’une classe d´riv´e que si cet ee ee e eobjet est effectivement du type pr´tendu. Une r´f´rence vers un objet de type Date e eepeut ˆtre chang´ en une r´f´rence vers un objet de type DateAnniversaire que si e e eel’on s’est assur´ que l’objet r´f´renc´ est r´ellement de la classe DateAnniversaire. e ee e eSinon, l’exception ClassCastException est g´n´r´e. e eeExemple :Date d;DateAnniversaire da;...da=d; // erreur compilation !d=da; // OKda=(DateAnniversaire) d // OK4.7 Classes et m´thodes abstraites e Une m´thode est qualifi´e abstract lorsqu’on la d´clare sans donner son impl´- e e e ementation (on n’a que son prototype). Une classe doit ˆtre d´clar´e abstract d`s e e e elors qu’elle contient une m´thode abstraite. Il est interdit de cr´er une instance e ed’une classe abstraite (souvenez-vous que son impl´mentation n’est pas compl`te). e ePuisqu’une classe abstraite ne peut pas ˆtre instanci´e, il faudra ´videmment la e e ed´river pour pouvoir l’utiliser. Une sous-classe d’une classe abstraite sera encore eabstraite si elle ne d´finit pas toutes les m´thodes abstraites de la classe m`re. e e e Une m´thode final ne peut ˆtre d´clar´e abstraite, puisqu’on ne peut pas red´finir e e e e eune telle m´thode. e Une classe abstraite peut ˆtre utilis´e pour regrouper des classes. C’est l’exemple e ede la classe abstraite Polygone que l’on verra en TD.4.8 Interfaces Java ne permet pas l’h´ritage multiple. Il pallie ce manque par l’introduction des einterfaces. Les interfaces peuvent ˆtre vues comme des mod`les, sortes de classes e ene poss´dant que des champs static final (c’est-`-dire des constantes) et des e am´thodes abstraites. On pourrait dire que les interfaces sont des classes abstraites edont toutes les m´thodes sont abstraites et publiques et tous les champs sont publics eet constants.Support de cours programmation Java - GBM2 - 36-
    • 4.8. INTERFACES Les interfaces servent ` : a – garantir aux clients d’une classe que ses instances peuvent assurer certains services – faire du polymorphisme avec des objets dont les classes n’appartiennent pas ` a la mˆme hi´rarchie d’h´ritage. e e e4.8.1 D´clarer des interfaces e Comme les classes, les interfaces sont constitu´es de champs (ou attributs) et ede m´thodes. Il existe n´anmoins de tr`s fortes contraintes dans la d´finition d’une e e e einterface : – toutes les m´thodes qui sont d´clar´es sont abstraites : aucune impl´mentation e e e e n’est donn´ee. Toutes les m´thodes ´tant publiques et abstraites, les mots cl´s e e e e public et abstract sont implicites et n’apparaissent pas, – aucune m´thode n’est static, e – tous les champs sont public, static et final, il d´finissent des constantes. e Les mots cl´s static et final sont implicites. eQualificatifs pour une interface : Une interface peut ˆtre qualifi´e de public, e eauquel cas elle sera utilisable par n’importe quelle classe. En l’absence de ce qualifi-catif, elle ne peut ˆtre utilis´e que par les classes du mˆme paquetage. Contrairement e e eaux classes, on ne peut qualifier une interface de private ni protected.Attributs d’une interface : Il sont static et donc les r`gles d’initialisation de etels attributs s’appliquent ici. On ne peut pas qualifier les attributs d’une interfacede transient, volatile, synchronized, private ni protected.D´river une interface : Comme pour les classes, on peut organiser les interfaces ede fa¸on hi´rarchique.Mais contrairement aux classes, une interface peut d´river plu- c e esieurs autres interfaces.4.8.2 Impl´menter des interfaces e Les interfaces d´finissent des promesses de services. Mais seule une classe peut erendre effectivement ces services. Une interface seule ne sert ` rien ! Il faut une classe aqui impl´mente l’interface. Une telle classe d´clare dans son entˆte qu’elle impl´mente e e e eune interface :interface Service { ...}class X implements Service { ...}Support de cours programmation Java - GBM2 - 37-
    • 4.8. INTERFACESPar l’utilisation du mot cl´ implements, la classe promet d’impl´menter toutes les e em´thodes d´clar´es dans l’interface. La signature d’une m´thode impl´ment´e doit e e e e e e´videmment ˆtre identique ` celle qui apparait dans l’interface, sinon la m´thode este e a econsid´r´e comme une m´thode de la classe et non de l’interface. ee e4.8.3 Utiliser des interfaces Comme pour des classes, on peut d´finir des r´f´rences ayant le type d’une inter- e eeface. Par contre, il ne sera pas possible de d´finir un objet de ce type ! Si l’on d´clare e epar exemple Service s, s est une r´f´rence qui contient soit la valeur null, soit une eeref´rence ` un objet d’une classe impl´mentant l’interface Service. e a eSupport de cours programmation Java - GBM2 - 38-
    • Chapitre 5 39
    • Chapitre 6Tableaux et chaˆ ınes de caract`res e6.1 Tableaux Ce sont des suites d’objets de mˆme type. Le nombre d’´l´ments est fixe et est e eeappel´ taille du tableau. Les tableaux sont des objets et leurs ´l´ments sont soit de e eetype primitif, soit des r´f´rences. Pour utiliser un objet de type tableau, il faut donc eed´finir une variable de type r´f´rence : e eeint [] tab1;int tab2[];Ces variables sont des r´f´rences ; l’espace m´moire n´cessaire pour coder la suite des ee e eobjets est r´serv´ avec le mot cl´ new et l’op´rateur [] : e e e etab1 = new int[5];tab2 = new int[2 * nbre +5];Contrairement au langage C, il n’est pas n´cessaire que la taille du tableau soit etextuellement une constante. Comme il s’agit d’une allocation dynamique, la taillepeut ˆtre une expression dont la valeur est un entier positif ou nul. e6.1.1 Type des ´l´ments ee Les ´l´ments d’un tableau peuvent ˆtre de n’importe quel type : primitif ou ee er´f´rence. On peut tout ` fait d´finir un tableau de r´f´rences vers une classe abstraite, ee a e eeou vers des objets impl´mentant une interface : eDirigeable [] tab=new Dirigeable[10];VehiculeARoues tab2=new VehiculesARoues[10];Voiture [] tab3 = new Voiture[4];On initialisera le premier tableau avec tout objet impl´mentant l’interface Dirigeable e(cf. chapitre 8), le deuxi`me tableau avec des objets de classe d´riv´e de la classe e e eabstraite VehiculeARoues, enfin le troisi`me tableau avec des objets de la classe eVoiture. 40
    • 6.1. TABLEAUX6.1.2 Acc`s aux ´l´ments e ee On acc`de aux ´l´ments d’un tableau grˆce ` l’op´rateur []. On notera tab[0], e ee a a etab[1],...,tab[n-1] les n premiers ´l´ments du tableau (notez l’indice du premier ee´l´ment).ee Les indices peuvent ˆtre de type int, short, byte ou char. e Lors de l’acc`s ` un ´l´ment d’un tableau, Java v´rifie s’il y a d´bordement. Si l’in- e a ee e edice est en dehors des limites du tableau l’exception IndexOutOfBoundsExceptionest lanc´e. e6.1.3 Taille des tableaux A chaque tableau est associ´e sa taille length qui est un champ public final ede la classe des tableaux. On connait donc la taille du tableau par ce champ.for (int i=0;i<tab1.length;i++) tab1[i]=i;6.1.4 Initialisation Lors de la cr´ation d’un tableau, ses ´l´ments sont initialis´s ` une valeur par e ee e ad´faut. Pour les tableaux de nombres (entiers et flottants), la valeur initiale est z´ro, e epour les tableaux de r´f´rences, la valeur initiale est null. eeAttention ! D´finir un tableau d’objets ne d´finit qu’un tableau de r´f´rences. Les e e eeobjets devront ˆtre allou´s ult´rieurement. e e eDate[] tabDate = new Date[3];tabDate[0] = new Date(15,9,59);tabDate[1] = new Date(1,1,0);tabDate[2] = new Date(31,3,94); L’initialisation d’un tableau peut se faire au moment de sa d´finition, comme en eC, ` l’aide d’accolades : aint [] tab ={1,2,3,4,5,6,7,8,9,0};Date [] tabDate = {new Date(15,9,59),new Date(1,1,0),new Date(31,3,94))};6.1.5 Tableaux multidimensions Les tableaux multidimensions sont des tableaux de tableaux. La syntaxe pourd´finir une matrice 5x5 d’entiers est eint[][]mat = new int[5][5 ];Comme pour les tableaux ` une dimension, on peut initialiser les tableaux multidi- amensions au moment de leur d´finition : eSupport de cours programmation Java - GBM2 - 41-
    • 6.2. CHAˆ ` INES DE CARACTERESint[][]mat = {{1,0,0,{0,1,0},{0,0,1}};int [][]pascal ={{1},{1,1},{1,2,1},{1,3,3,1}{1,4,6,4,1}};Notez que dans le cas du tableau pascal, les sous-tableaux sont tous de taillediff´rente. Les noms de ces sous-tableaux sont pascal[0], pascal[1], .... On edoit toujours sp´cifier la premi`re dimension quand on cr´e le tableau, on peut ne e e esp´cifier les dimensions suivantes qu’au moment de la cr´ation des sous-tableaux. e epublic class TableauDeTableau { public static void main(String[] arg) { int [][] uneMatrice=new int[4][]; // remplir la matrice for (int i=0;i<uneMatrice.length;i++) { uneMatrice[i] = new int[5]; // creation d’un sous-tableau for (int j=0;j<uneMatrice[i].length;j++) { uneMatrice[i][j]=i+j; } } // imprimer la matrice for (int i=0;i<uneMatrice.length;i++) { for (int j=0;j<uneMatrice[i].length;j++) { System.out.print(uneMatrice[i][j]+" "); } System.out.println(); } }}6.2 Chaˆ ınes de caract`res e En Java, les chaˆınes de caract`res sont des objets d’une classe sp´cifique. Il ne e es’agit pas de tableaux de caract`res. Le paquetage java.lang contient deux classes ede chaˆınes de caract`res : String et StringBuffer. On a d´j` rencontr´ la classe e ee eString. On l’a utilis´e quand on avait besoin de chaˆ e ınes de caract`res qui n’´taient e epas modifi´es (chaˆ constantes). La classe StringBuffer est utilis´e pour travailler e ınes eavec des chaˆınes dont le contenu est modifi´. e6.2.1 Classe String Dans beaucoup de cas, les chaˆ ınes de caract`res qu’on utilise ne sont pas des- etin´es ` ˆtre modifi´es, il s’agit d’objets constants. Le compilateur Java transforme e ae eautomatiquement les constantes de type chaˆ ınes en objets de type String. On peutaussi cr´er explicitement un objet de type String avec un des constructeurs de la eclasse.Support de cours programmation Java - GBM2 - 42-
    • 6.2. CHAˆ ` INES DE CARACTERES En plus de ses constructeurs (il y en a 11 !), la classe fournit des m´thodes de ecomparaisons, de recherches, d’extractions et de copies. Voici celles qui me paraissentles plus utilis´es. Pour les autres, n’h´sitez pas ` consulter la documentation. e e a Prototype Rˆle o public String() constructeur public String(String str) constructeur public int length() longueur de la chaˆ ıne public char charAt(int index) caract`re ` la position index e a public String substring(int dbt,int fin) extrait la chaˆ entre les positions dbt et fin ıne public boolean equals(Object o) test d’´galit´ e e public boolean startsWith(String pref) test si le d´but de la chaˆ est ´gal ` pref e ıne e a public boolean endsWith(String suf) test si la fin de la chaˆ est ´gal ` suf ıne e a public int compareTo(String str) comparaison des 2 chaˆ ınes,(0 si str est ´gale, e n´gatif si elle est inf´rieure, positif sinon) e e public int indexOf(int ch) position du caract`re ch e public int lastIndexOf(int ch) derni`re position du caract`re ch e e public int indexOf(int ch, int i) position de ch ` partir de i a public int indexOf(String str) position de la ss-chaˆ str ıne public String replace(char c,char d) remplace toute occurrence de c par d public String toLowerCase() conversion en minuscules public String toUpperCase() conversion en majuscules public char[] toCharArray() conversion en tableau de caract`res e public String trim() suppression des espace en d´but et fin e public static String valueOf(char t[]) conversion d’un tableau de caract`res en String eExemple :class chaines{ public static void main(String [] arg){ String a="Coucou"; String b=new String(", c’est moi !n"); String c=a+b; System.out.println(c); System.out.println("longueur de a : "+a.length()); //6 System.out.println("caractere en position 2 : "+a.charAt(2)); //u System.out.println("a est Coucou : "+a.equals("Coucou")); //true System.out.println("a est b : "+a.equals(b)); //false System.out.println("position de o dans a? "+a.indexOf(’o’)); //1 System.out.println("position du dernier o dans a? "+a.lastIndexOf(’o’)); //4 System.out.println("position de "cou" dans a? "+a.indexOf("cou")); //3 System.out.println("position de "moi" dans a? "+a.indexOf("moi")); //-1 System.out.println("a en majuscules : "+a.toUpperCase()); //COUCOU System.out.println("a en minuscules : "+a.toLowerCase()); //coucou System.out.println("a > b ? "+a.compareTo(b)); //23Support de cours programmation Java - GBM2 - 43-
    • 6.2. CHAˆ ` INES DE CARACTERES System.out.println("a < b ? "+b.compareTo(a)); //-23 }}6.2.2 Classe StringBuffer On a vu que l’on avait recours ` la classe String pour les chaˆ a ınes que l’on n’estpas amen´ ` modifier. Mais dans les programmes, certaines chaˆ e a ınes sont amen´es eae` ˆtre modifi´es, dans ce cas, il faut utiliser des objets de la classe StringBuffer. eTypiquement, on utilise des Strings pour les arguments et les r´sultats des m´thodes. e ePour construire une chaˆ on utilisera le type StringBuffers. Notez que, justement ıne,parce qu’il s’agit de constantes, les Strings sont moins on´reuses (en m´moire) que e eles StringBuffers. L’exemple qui suit est typique de l’utilisation de ces deux classes1 .Exemple :class ReverseString{ public static String reverseIt(String source) { int i, len=source.length(); StringBuffer dest=new StringBuffer(len); for (i=(len-1);i>=0;i--) { dest.append(source.charAt(i)); } return dest.toString(); }} Un objet de type StringBuffer a un espace de stockage ` la cr´ation, automati- a equement redimensionn´ en fonction des besoins. Pour cr´er un objet de cette classe, e eon peut utiliser un des 3 constructeurs : – StringBuffer() : construit un string buffer ne contenant pas de caract`res et e avec une capacit´ initiale de 16 caract`res. e e – StringBuffer(int) : construit un string buffer ne contenant pas de caract`res e et avec une capacit´ initiale sp´cifi´e par l’argument. e e e – StringBuffer(String) : construit un string buffer contenant la mˆme s´quence e e de caract`res que la chaˆ constante pass´e en argument, avec une capacit´ de e ıne e e 16 caract`res plus la longueur de la chaˆ pass´e en argument. e ıne eComme pour la classe String il existe un certain nombre de m´thodes pour les eStringBuffer. En voici quelques unes : 1 tir´ du tutorial Java Sun eSupport de cours programmation Java - GBM2 - 44-
    • 6.2. CHAˆ ` INES DE CARACTERES Prototype Rˆle o public int length() longueur de la chaˆ ıne public char charAt(int index) caract`re ` la position index e a public void getChars(int dbt, int fin, recopie la ss-chaˆ entre les positions dbt et fin, ıne char dst[],int index) dans le tableau dst, ` partir de l’indice index a public int capacity() capacit´ courante e public void setCharAt(int index, char c) met le caract`re c ` l’indice index e a public StringBuffer append(Object obj) concat`ne la repr´sentation textuelle de l’obj. obj e eSupport de cours programmation Java - GBM2 - 45-
    • Chapitre 7Exceptions7.1 Introduction Dans un programme, il faut soigner la gestion des erreurs. Ce n’est pas toujoursfacile avec les langages classiques. Java propose une approche tr`s diff´rente des e eapproches traditionnelles, ` travers le m´canisme des exceptions. Une exception est a eune sorte de signal indiquant qu’une erreur ou une situation anormale a eu lieu. Ondit qu’une m´thode ayant d´tect´ une situation anormale d´clenche (throws) une e e e eexception. Cette exception pourra ˆtre captur´e (catch) par le code. e e On peut distinguer deux types de situations anormales : les exceptions et leserreurs. Les erreurs sont en principe des erreurs fatales et le programme s’arrˆte ` e ala suite de ce type de situation (classe java.lang.Error). Les exceptions ne sontpas uniquement des erreurs syst`me. Le programmeur peut d´finir des erreurs (non e efatales) pour assurer que son programme est robuste (classe java.lang.Exception).Par exemple, le d´bordement d’un tableau est une exception. e Lorsqu’une m´thode d´clenche une exception la JVM remonte la suite des invo- e ecations des m´thodes jusqu’` atteindre une m´thode qui capture cette exception. Si e a eune telle m´thode n’est pas rencontr´e, l’ex´cution est arrˆt´e. e e e ee L’uilisation des exceptions permet de : – s´parer le code correspondant au fonctionnement normal d’un programme, du e code concernant la gestion des erreurs, – propager de proche en proche les exceptions d’une m´thode ` la m´thode appe- e a e lante jusqu’` atteindre une m´thode capable de g´rer l’exception. Il n’est donc a e e pas n´cessaire que la gestion d’une exception figure dans la m´thode qui est e e susceptible de d´clencher cette exception. Une m´thode peut ignorer la ges- e e tion d’une exception ` condition qu’elle transmette l’exception ` la m´thode a a e appelante, – regrouper par types la gestion des exceptions. 46
    • 7.2. QU’EST-CE QU’UNE EXCEPTION7.2 Qu’est-ce qu’une exception C’est un objet de la classe java.lang.Throwable qui est la classe m`re de toutes eles erreurs et exceptions du langage Java. Seuls les objets qui sont des instances decette classe (ou d’une classe d´riv´e) sont d´clench´s par la JVM et apparaissent e e e ecomme arguments d’une clause catch. Nous allons voir ci-apr`s les sous-classes prin- ecipales de la classe java.lang.Throwable. – java.lang.Error est la classe des erreurs, qui indiquent un probl`me grave e qui doit conduire ` l’arrˆt de l’application en cours. On ne demande pas aux a e m´thodes de d´clarer une telle erreur dans la clause throws, puisqu’elle n’est e e pas susceptible d’ˆtre captur´e. Un certain nombre d’erreurs d´rivent de cette e e e classe, par exemple OutOfMemoryError, et d’autres... – java.lang.Exception est la classe des exceptions qui indiquent qu’une appli- cation devrait raisonnablement les capturer, c’est-`-dire traiter ces cas de si- a tuations anormales, sans arrˆter le programme. Voici des exceptions classiques e qui d´rivent de cette classe : java.io.IOException, FileNotFoundException, e et bien d’autres... A chaque objet de la classe java.lang.Exception (ou d’une classe d´riv´e) est associ´ un message que l’on peut r´cup´rer avec la m´thode e e e e e e getMessage() de la classe java.lang.Throwable – RuntimeException est une classe d´riv´e de la pr´c´dente, et c’est la classe e e e e m`re des exceptions qui peuvent ˆtre d´clench´es au cours de l’ex´cution d’un e e e e e programme. Supposons qu’une m´thode soit susceptible de lever une excep- e tion de type RuntimeException, il n’est pas obligatoire de le signaler dans sa clause throws. En effet, les exceptions de type RuntimeException peuvent ˆtre e lev´es mais ne pas ˆtre captur´es, g´n´rant ainsi un arrˆt du programme. Voici e e e e e e quelques exemples de sous-classes de la classe RuntimeException : – ArrayStoreException, – ArithmeticException, – NullPointerException, – NumberFormatException...7.2.1 Capturer une exception On l’a dit pr´c´demment, lorsqu’une exception est lanc´e, elle se propage dans la e e epile des m´thodes jusqu’` ˆtre captur´e. Si elle ne l’est pas, elle provoque la fin du e ae eprogramme, et la pile des m´thodes travers´es est indiqu´e ` l’utilisateur. e e e a Supposons qu’une instruction instr d’une m´thode uneMethode lance une ex- eception, alors : – si instr se trouve dans un bloc try, suivi d’un bloc catch alors, 1. les instructions du bloc try suivant instr ne sont pas ex´cut´es, e e 2. les instructions du bloc catch sont ex´cut´es, e e 3. le programme reprend son cours normalement avec l’instruction suivant le bloc catch.Support de cours programmation Java - GBM2 - 47-
    • 7.2. QU’EST-CE QU’UNE EXCEPTION – si instr ne se trouve pas dans un bloc try comme d´crit pr´c´demment, alors e e e la m´thode uneMethode est termin´ee. Si uneMethode est la m´thode main, le e e e programme se termine, et l’exception n’a pas ´t´ captur´e. Sinon, on se retrouve ee e dans une m´thode qui a appel´ la m´thode uneMethode via une instruction e e e instr2 qui lance ` son tour l’exception. a Une m´thode susceptible de lancer une exception sans la capturer doit l’indiquer edans son entˆte avec la clause throws. Cependant, comme pr´cis´ pr´c´demment, e e e e eon est dispens´ de d´clarer le lancement des erreurs les plus courantes, comme par e eexemple : – ArrayOutOfBoundsException, – ArrayStoreException, – ArithmeticException, – NullPointerException, – NumberFormatException...Exemple :1class AttrapExcep{ static int moyenne(String[] liste) { int somme=0, entier, nbNotes=0; for (int i=0;i<liste.length;i++) { try{ entier=Integer.parseInt(liste[i]); somme+=entier; nbNotes++; } catch(NumberFormatException e) { System.out.println("La "+(i+1)+"i`me note pas enti`re"); e e } } return somme/nbNotes; } public static void main(String [] arg) { System.out.println("La moyenne est :"+moyenne(arg)); }}Voici quelques exemples d’ex´cution du programme pr´c´dent : e e echaouiya/GBM2/coursJava/Notes_cours$ java AttrapExcep 5 b 10La 2i`me note n’est pas un entier eLa moyenne est :7chaouiya@pccc:~/GBM2/coursJava/Notes_cours$ java AttrapExcep 5 10 15 1 emprunt´ ` I.Charon eaSupport de cours programmation Java - GBM2 - 48-
    • 7.2. QU’EST-CE QU’UNE EXCEPTIONLa moyenne est :10chaouiya@pccc:~/GBM2/coursJava/Notes_cours$ java AttrapExcep 5 10 15 nLa 4i`me note n’est pas un entier eLa moyenne est :10chaouiya@pccc:~/GBM2/coursJava/Notes_cours$ java AttrapExcep 10.5 xxLa 1i`me note n’est pas un entier eLa 2i`me note n’est pas un entier ejava.lang.ArithmeticException: / by zero at AttrapExcep.moyenne(AttrapExcep.java:14) at AttrapExcep.main(AttrapExcep.java:17)7.2.2 D´finir de nouveaux types d’exceptions e Les exceptions sont des objets d’une classe d´riv´e de java.lang.Exception. e eSi l’on veut signaler un ´v´nement inattendu, non pr´vu par l’API de Java, il e e efaut d´river la classe Exception et d´finir une nouvelle classe qui ne contient en e eg´n´ral pas d’autre champ qu’un ou plusieurs constructeur(s) et ´ventuellement une e e ered´finition de la m´thode toString. Lors du lancement d’une telle exception, on e ecr´e une instance de cette nouvelle classe. eExemple :class ExceptionRien extends Exception { public String toString() { return("Aucune note n’est valide’n"); }}7.2.3 Lancer et capturer une exception Rien ne vaut un exemple, reprenons celui de I.Charon2 :class ExceptionThrow { static int moyenne(String[] liste) throws ExceptionRien { int somme=0,entier, nbNotes=0; int i; for (i=0;i < liste.length;i++) { try{ entier=Integer.parseInt(liste[i]); somme+=entier; nbNotes++; } catch (NumberFormatException e){ System.out.println("La "+(i+1)+" eme note n’est "+ 2 http ://www.infres.enst.fr/ charon/coursJavaSupport de cours programmation Java - GBM2 - 49-
    • 7.2. QU’EST-CE QU’UNE EXCEPTION "pas entiere"); } } if (nbNotes==0) throw new ExceptionRien(); return somme/nbNotes; } public static void main(String[] argv) { try { System.out.println("La moyenne est "+moyenne(argv)); } catch (ExceptionRien e) { System.out.println(e); } }7.2.4 Blocs finally La clause finally est en g´n´ral utilis´e pour “faire le m´nage” (par exemple e e e efermer les fichiers, lib´rer les ressources, ...). Un bloc finally est utilis´e en associa- e etion avec un bloc try. On sort d’un bloc try par une instruction break ou returnou continue ou par une propagation d’exception. Un bloc finally suit un bloc trysuivi, en g´n´ral, d’un bloc catch. Dans tous les cas, quelque soit la fa¸on dont on e e cest sorti du bloc try, les instructions du bloc finally sont ex´cut´es. e e Voici un exemple, toujours tir´ du support de cours d’Ir`ne Charon, qui n’a e ed’autre objectif que d’illustrer l’effet du bloc finally :class MonException extends Exception { MonException() { System.out.println("me voila"); }}class Propagation { static boolean probleme=true; static void methodeBasse() throws MonException { try { if (probleme) throw new MonException(); System.out.println("et moi ?"); } finally { System.out.println("hauteur basse : il faudrait etre ici"); } System.out.println("pas mieux"); } static void methodeMoyenne() throws MonException {Support de cours programmation Java - GBM2 - 50-
    • 7.2. QU’EST-CE QU’UNE EXCEPTION try { methodeBasse(); System.out.println("et ici ?"); } finally { System.out.println("moyenne hauteur : ou bien etre la"); } } static void methodeHaute() { try { methodeMoyenne(); } catch(MonException e) { System.out.println("attrape..."); } } static public void main(String[] argv) { methodeHaute(); }}Support de cours programmation Java - GBM2 - 51-
    • Chapitre 8Un exemple : des v´hicules e Dans ce chapitre, nous allons d´tailler une application qui utilise des classes ed´crivant diff´rents types de v´hicules. e e e8.1 Une classe Direction Elle d´finit les 4 directions et est utilis´e dans la suite. e eclass Direction { int valeur; String nom; public Direction(int b,String s) { valeur=b; nom=s; }}8.2 Une interface : Dirigeable Cette interface annonce les caract´ristiques et services communs ` tout syst`me e a ede “dirigeable”, c’est-`-dire que l’on peut conduire... Elle d´finit aussi 4 constantes a ede la classe Direction.interface Dirigeable { Direction Sud=new Direction(1,"Sud"); Direction Est=new Direction(2,"Est"); Direction Nord=new Direction(3,"Nord"); Direction Ouest=new Direction(4,"Ouest"); void accelerer(int facteur)throws VitesseExcessive; //pour acc´lerer d’un facteur donn´ e e void ralentir(int facteur); // pour ralentir int quelleVitesseCourante(); // vitesse courante void tournerDroite(); // pour tourner ` droite a 52
    • 8.3. UNE CLASSE ABSTRAITE :VEHICULEAROUES void tournerGauche(); // pour tourner ` gauche a void faireDemiTour(); // pour faire demi-tour Direction quelleDirectionCourante();}8.3 Une classe abstraite :VehiculeARoues Cette classe d´finit ce qu’est un v´hicule ` roues (en opposition aux autres e e av´hicules que l’on ´crira en TD). Elle impl´mente (quand cela est possible) l’in- e e eterface Dirigeable. Elle reste abstraite car les vitesses excessives, le nombre rouessont (notamment) diff´rentes selon les v´hicules ` roues consid´r´s. e e a eeabstract class VehiculeARoues implements Dirigeable { protected String couleur; protected int nbRoues; protected int vitesseCourante; protected Direction directionCourante; protected boolean etat; // marche ou panne public int quelleVitesseCourante(){ return vitesseCourante; } public Direction quelleDirectionCourante(){ return directionCourante; } public void tournerDroite(){ switch (directionCourante.valeur) { case 1 : //sud directionCourante=Ouest; break; case 2 ://est directionCourante=Sud; break; case 3 : //nord directionCourante=Est; break; case 4 : // ouest directionCourante=Nord; break; } } public void tournerGauche(){ switch (directionCourante.valeur) { case 1 : //sud directionCourante=Est; break; case 2 ://est directionCourante=Nord;Support de cours programmation Java - GBM2 - 53-
    • 8.4. DES CLASSES VOITURE, CAMION ET VELO break; case 3 : //nord directionCourante=Ouest; break; case 4 : //ouest directionCourante=Sud; break; } } public void faireDemiTour(){ switch (directionCourante.valeur) { case 1 : //sud directionCourante=Nord; break; case 2 ://est directionCourante=Ouest; break; case 3 ://nord directionCourante=Sud; break; case 4://ouest directionCourante=Est; break; } } public boolean getEtat(){ return etat; } abstract public void accelerer(int param) throws VitesseExcessive; public void ralentir(int param) { vitesseCourante-=param; if (vitesseCourante<0) vitesseCourante=0; } public void changerEtat(){ if (etat) vitesseCourante=0; etat=!etat; } abstract public void afficher(); public int combienDeRoues(){return nbRoues;}}8.4 Des classes Voiture, Camion et Veloclass Voiture extends VehiculeARoues{Support de cours programmation Java - GBM2 - 54-
    • 8.4. DES CLASSES VOITURE, CAMION ET VELO private static final int vitesseMax=130; private static final int nbRoues=4; public Voiture(int v,boolean e, String c) throws VitesseExcessive { if (v>vitesseMax) throw new VitesseExcessive(vitesseMax); else vitesseCourante=v; etat=e; if (!etat) vitesseCourante=0; couleur=c; directionCourante=Sud; // par d´faut e } public Voiture(int v,boolean e, String c,String d) throws VitesseExcessive{ if (v>vitesseMax) throw new VitesseExcessive(vitesseMax); else vitesseCourante=v; etat=e; if (!etat) vitesseCourante=0; couleur=c; if (d.equalsIgnoreCase("Nord")) directionCourante=Nord; else if (d.equalsIgnoreCase("Est")) directionCourante=Est; else if (d.equalsIgnoreCase("Ouest")) directionCourante=Ouest; else directionCourante=Sud; } public void accelerer(int param) throws VitesseExcessive{ int nouvelleVitesse = vitesseCourante+param; if (nouvelleVitesse <0 ) vitesseCourante=0; else if (nouvelleVitesse >vitesseMax) throw new VitesseExcessive(this.vitesseMax); else vitesseCourante=nouvelleVitesse; } public void afficher() { if (etat) System.out.println("Voiture "+couleur +" en ´tat de marche roulant e a ` "+vitesseCourante+"km/h plein "+directionCourante.nom); else System.out.println("Voiture "+couleur +" en panne"); }}class Camion extends VehiculeARoues{ private static final int vitesseMax=90; private int nbRoues; public Camion(int r,int v,boolean e,String c) throws VitesseExcessive,NbRouesImpossible { if (r!=4 && r!=6 && r!=8) throw new NbRouesImpossible(r); else nbRoues=r; if (v>vitesseMax) throw new VitesseExcessive(vitesseMax);Support de cours programmation Java - GBM2 - 55-
    • 8.4. DES CLASSES VOITURE, CAMION ET VELO else vitesseCourante=v; etat=e; if (!etat) vitesseCourante=0; couleur=c; directionCourante=Sud; } public void accelerer(int param) throws VitesseExcessive{ int nouvelleVitesse = vitesseCourante+param; if (nouvelleVitesse <0 ) vitesseCourante=0; else if (nouvelleVitesse >vitesseMax) throw new VitesseExcessive(this.vitesseMax); else vitesseCourante=nouvelleVitesse; } public void afficher() { if (etat) System.out.println("Camion "+couleur +" en ´tat de marche, roulant e a ` "+vitesseCourante+"km/h, sur "+nbRoues+" roues, plein "+directionCourante.nom); else System.out.println("Camion "+couleur +" en panne"); }}class Velo extends VehiculeARoues{ private static final int vitesseMax=20; private static final int nbRoues=2; public Velo(int v,boolean e,String c) throws VitesseExcessive{ if (v>vitesseMax) throw new VitesseExcessive(vitesseMax); else vitesseCourante=v; etat=e; if (!etat) vitesseCourante=0; couleur=c; directionCourante=Sud; } public void accelerer(int param) throws VitesseExcessive{ int nouvelleVitesse = vitesseCourante+param; if (nouvelleVitesse <0 ) vitesseCourante=0; else if (nouvelleVitesse >vitesseMax) throw new VitesseExcessive(this.vitesseMax); else vitesseCourante=nouvelleVitesse; } public void afficher() { if (etat) System.out.println("V´lo "+couleur +" en ´tat de marche, roulant ` " e e a +vitesseCourante +"km/h, plein "+directionCourante.nom); else System.out.println("V´lo "+couleur +" en panne"); eSupport de cours programmation Java - GBM2 - 56-
    • 8.5. DES EXCEPTIONS : VITESSEEXCESSIVE ET NBROUESIMPOSSIBLE }}8.5 Des exceptions : VitesseExcessive et NbRouesImpossibleclass NbRouesImpossible extends Exception { private String msg; public NbRouesImpossible(int r) {msg="pas de camion ` "+r+" roues !"; a } public String toString(){return msg;}}class VitesseExcessive extends Exception { private String msg; public VitesseExcessive(int r) { msg="interdit de d´passer "+r+"km/h !"; e } public String toString(){return msg;}}8.6 L’application : AppliVehiculespublic class AppliVehicules{ public static void main(String arg[]) throws NbRouesImpossible,VitesseExcessive {Voiture maVoiture=new Voiture(0,true,"verte");Voiture taVoiture=new Voiture(30,true,"bleue","est");Velo monVelo=new Velo(10,false,"rouge");Camion monCamion=new Camion(8,50,true,"jaune");try {Camion tonCamion=new Camion(7,50,true,"jaune");}catch(NbRouesImpossible e){ System.out.println(e);}try{ maVoiture.accelerer(140);}catch (VitesseExcessive e){ System.out.println(e);}maVoiture.afficher();maVoiture.faireDemiTour();maVoiture.accelerer(40);maVoiture.afficher();maVoiture.changerEtat();maVoiture.afficher();monVelo.changerEtat();Support de cours programmation Java - GBM2 - 57-
    • 8.6. L’APPLICATION : APPLIVEHICULEStaVoiture.afficher();taVoiture.faireDemiTour();monCamion.accelerer(-10);monCamion.afficher();monCamion.changerEtat();monCamion.afficher(); }} Vous pouvez r´cup´rer le fichier complet avec toutes les classes : e e http ://www.esil.univ-mrs.fr/ chaouiya/Java/cours/AppliVehiculesSupport de cours programmation Java - GBM2 - 58-
    • Chapitre 9Paquetage java.lang Ce paquetage d´finit un ensemble de classes et exceptions (voir le tableau ` la e afin du chapitre, le paquetage d´finit aussi des erreurs qui ne sont pas list´es dans e ece tableau) qui constituent le noyau du langage Java. On y retrouve surtout ce quel’on appelle les enveloppes (wrappers en anglais) qui d´finissent des classes sp´ciales e ecorrespondant ` un certain nombre de types primitifs. Encore une fois, n’h´sitez pas a ea` consulter la documentation de l’API !9.1 Enveloppes9.1.1 Classe java.lang.Number C’est une classe abstraite m`re des classes Byte, Short, Integer, Long, Float, eDouble.public abstract class Numberpublic Number() // constructeurpublic abstract int intValue()public abstract long longValue()public abstract float floatValue()public abstract double doubleValue()public short shortValue()9.1.2 Classe java.lang.Integer Elle permet de repr´senter un entier sous la forme d’un objet. Ce qui me parait ele plus utilis´ (pour le reste se r´f´rer ` la documentation) : e ee apublic final class Integer extends Number public static final int MAX_VALUE // la valeur max d’un int public static final int MIN_VALUE public static final Class TYPE // l’objet classe repr´sentant le type int e public Integer(int value) // constructeur public Integer(String s) throws NumberFormatException 59
    • 9.1. ENVELOPPES public static String toString(int i, int radix) //radix est la base ......... public static String toString(int i) public static int parseInt(String s) throws NumberFormatException ........ public static Integer valueOf(String s) throws NumberFormatException ........ public int intValue()9.1.3 Classe java.lang.Boolean Elle permet de repr´senter un bool´en sous la forme d’un objet. Voici ce qui me e eparait le plus utilis´ (pour le reste se r´f´rer ` la documentation) : e ee apublic final class Boolean extends Objectpublic static final Boolean TRUEpublic static final Boolean FALSEpublic static final Class TYPEpublic Boolean(boolean value)........public boolean booleanValue()........public String toString()........9.1.4 Classe java.lang.Character Elle permet de repr´senter un caract`re sous forme d’objet. Voici ce qui me parait e ele plus utilis´ (pour le reste se r´f´rer ` la documentation) : e ee apublic final class Character extends Object.........public static final Class TYPE.........public static final byte SPACE_SEPARATORpublic static final byte LINE_SEPARATORpublic static final byte PARAGRAPH_SEPARATORpublic static final byte CONTROL.........public Character(char value)public char charValue()public String toString()public static boolean isLowerCase(char ch)public static boolean isUpperCase(char ch)public static boolean isDigit(char ch)public static boolean isLetter(char ch)public static boolean isLetterOrDigit(char ch)public static char toLowerCase(char ch)Support de cours programmation Java - GBM2 - 60-
    • 9.2. CLASSE JAVA.LANG.MATHpublic static char toUpperCase(char ch)public static boolean isSpace(char ch)...........public static int getNumericValue(char ch)..........9.2 Classe java.lang.Math C’est la biblioth`que math´matique de Java.Toutes ses m´thodes sont publiques e e eet statiques. Voici ce qui me parait le plus utilis´ (pour le reste se r´f´rer ` la docu- e ee amentation) :public final class Math extends Objectpublic static final double Epublic static final double PIpublic static native double sin(double a)public static native double cos(double a)public static native double tan(double a)public static native double asin(double a)public static native double acos(double a)public static native double atan(double a)public static native double exp(double a)public static native double log(double a)public static native double sqrt(double a)public static native double ceil(double a) // partie entiere suppublic static native double floor(double a) // partie entiere infpublic static native double pow(double a,double b) Throws: ArithmeticException // a puissance bpublic static int round(float a)public static synchronized double random()public static int abs(int a)....... et les surcharges de abs .......public static int max(int a,int b)....... et les surcharges de max .......public static int min(int a,int b)....... et les surcharges de min .......Support de cours programmation Java - GBM2 - 61-
    • 9.2. CLASSE JAVA.LANG.MATH Nom Descriptif Interfaces : Clonable indique qu’un objet peut ˆtre clon´ e e Runnable cf chapitre sur les processus l´gers e Classes : Boolean cf. ce chapitre Byte pour le type primitif byte Character cf. ce chapitre Class les classes et interfaces d’une application Java ClassLoader Compiler Double pour le type primitif double Float pour le type primitif float Integer cf ce chapitre Long pour le type primitif float Math cf ce chapitre Number cf ce chapitre Object m`re de toutes les classes ! e Process Runtime SecurityManager hline Short pour le type primitif short String cf chapitre 6 StringBuffer cf chapitre 6 System voir chapitre 11 Thread voir chapitre sur les processus l´gers e ThreadGroup Throwable cf chapitre 7 Void pour le type primitif void Liste des exceptions : ArithmeticException,ArrayIndexOutOfBoundsException ArrayStoreException, ClassCastException ClassNotFoundException, CloneNotSupportedException Exception, IllegalAccessException IllegalArgumentException, IllegalMonitorStateException IllegalStateException, IllegalThreadStateException IndexOutOfBoundsException, InstantiationException InterruptedException, NegativeArraySizeException NoSuchFieldException, NoSuchMethodException NullPointerException, NumberFormatException RuntimeException, SecurityException StringIndexOutOfBoundsExceptionSupport de cours programmation Java - GBM2 - 62-
    • Chapitre 10Le paquetage java.util Le paquetage java.util contient des classes utilitaires telles que Vector, Stack (pourstocker un nombre variable d’objets), Dictionnary et HashTable (pour associer deuxobjets, cl´/valeur), StringTokenizer (pour d´couper des chaˆ e e ınes de caract`res), et bien ed’autres... que je vous liste ci-dessous avec un bref descriptif (pour certains seulement !).Pour plus d”information, n’h´sitez pas ` consulter la documentation de l’API ! Nous ne e ad´taillerons ici que les classes Vector et Stack. La classe StringTokenizer, utile pour el’analyse de chaˆ de caract`res, sera d´crite dans le chapitre sur les entr´es sorties. ıne e e e10.1 Classe java.util.VectorRappel sur les tableaux : – d´claration : int [] tab ou int tab[], on indique quil s’agit d’un tableau qui e contiendra ici des entiers, le type des ´l´ments d’un tableau est unique, ee – instanciation : tab = new int[dimension], la taille du tableau est fixe, mais l’allo- cation est dynamique. La classe java.util.Vector permet d’avoir : – une taille dynamique, – la possiblit´ de stocker des objets (Object) h´t´rog`nes. Pour les types primitifs, on e ee e devra utiliser les enveloppes (wrappers) du paquetage java.lang (Integer, Double, ...).Constructeurs – public Vector() – public Vector(int capaciteInitiale), il est conseill´ d’indiquer une taille ini- e tiale – public Vector(int capaciteInitiale,int incrementCapacite), par d´faut, le e vecteur double sa taille ` chaque d´passement. a eAjout d’un ´l´ment ee 1. ` la fin : a public final synchronized void addElement(Object nvElt) ; 63
    • 10.1. CLASSE JAVA.UTIL.VECTOR 2. entre 2 ´l´lements : ee public final synchronized void insertElement(Object nvElt,int indice) throws ArrayIndexOutOfBoundsException ; Nom Descriptif Interfaces Enumeration g´n`re une s´rie d’´l´ments, l’un apr`s l’autre (cf.plus loin) e e e ee e EventListener cf. chapitre java.awt Observer pour ˆtre informer du changement d’objets Observable e Classes BitSet vecteurs redimensionnables de bits Calendar Date Dictionary (abstraite) pour des tableaux associatifs EventObject GregorianCalendar Hashtable (h´rite de Dictionary) pour des tables de hachage e ListResourceBundle Locale Observable objets observables par des Observer Properties PropertyResourceBundle Random pour g´n´rer un flot de nombres pseudo-al´atoires e e e ResourceBundle SimpleTimeZone Stack pile d´crite plus loin e StringTokenizer p/la d´composition de chaˆ e ınes de caract`res en unit´s lexicales e e TimeZone Vector vecteurs redimensionnables, d´crite ci-apr`s e e Exceptions EmptyStackException MissingResourceException NoSuchElementException TooManyListenersExceptionRemplacer un ´l´ment Il s’agit de remplacer un objet situ´ ` la position indice par ee eaun autre :public final synchronized void setElementAt(Object nvElt,int indice) throws ArrayIndexOutOfBoundsException ;Acc´der ` un ´l´ment Attention, contrairement aux tableaux, il n’y a pas de m´canisme e a ee ed’indexation pour les Vector, il faut passer par les m´thodes suivantes : e 1. ´l´ment ` la position indice : ee a public final synchronized Object elementAt(int indice) throws ArrayIndexOutOfBoundsException ;Support de cours programmation Java - GBM2 - 64-
    • 10.1. CLASSE JAVA.UTIL.VECTOR 2. premier ´l´ment : ee public final synchronized Object firstElement() throws NoSuchElementException ; 3. dernier ´l´ment : ee public final synchronized Object LastElement() throws NoSuchElementException ;V´rifier si la liste est vide public final boolean isEmpty() ; eD´terminer la taille public final int size() ; eChanger la taille Si la nouvelle taille est sup´rieure ` la taille courante, le vecteur est e acompl´t´ par null, sinon, le vecteur est tronqu´ : ee e public final synchronized void setSize(int taille) ;Recopier un vecteur dans un tableau public final synchronized void copyInto(Object[] tab) ;Obtenir une liste des ´l´ments La m´thode elements() renvoie un objet de type ee eEnumeration qui permet d’acc´der aux ´l´ment de mani`re s´quentielle (mais dans un e ee e eordre ` priori ind´termin´). C’est l’interface Enumeration du paquetage java.util qui a e epermet d’´num´rer une liste d’objets (qui peuvent ˆtre h´t´rog`nes). Cette interfaces a e e e ee edeux m´thodes : e 1. pour savoir s’il reste des ´l´ments` ´num´rer, ee ae e public abstract booleman hasMoreElements() 2. pour obtenir le prochain objet et avancer d’un cran, public abstract Object nextElement() throws NoSuchElementExceptionExemple :Enumeration e = monVecteur.elements() ;while (e.hasMoreElements())Object objSuivant = e.nextElement() ;// faire ce qu’il y a lieu de faire sur objSuivantNote : attention, objSuivant est de type Object. Il est souvent n´cessaire de faire un cast equand le vecteur contient des objets de classe sp´cifique. eRechercher un ´l´ment On pourrait utiliser une Enumeration et parcourir tous les ee´l´ments. Mais c’est fastidieux et peu efficace, on a des m´thodes sp´cifiques !ee e e 1. tester la pr´sence d’un objet : e public final boolean contains(Object obf) ; 2. trouver la premi`re position : e public final synchronized int indexOf(Object obj) throws ArrayIndexOutOfBoundsException ;Support de cours programmation Java - GBM2 - 65-
    • 10.2. CLASSE JAVA.UTIL.STACK 3. trouver la premi`re position ` partir de index : e a public final synchronized int indexOf(Object obj,int index) throws ArrayIndexOutOfBoundsException ; 4. trouver la derni`re position : e public final synchronized int lastIndexOf(Object obj) throws ArrayIndexOutOfBoundsException ; 5. public final synchronized int lastIndexOf(Object obj) throws ArrayIndexOutOfBoundsException ;Supprimer un ´l´ment ee 1. supprimer tous les ´l´ments : ee public final synchronized void removeAllElements() ; 2. supprimer la premi`re occurrence d’un objet : e public final synchronized boolean removeElement(Object obj) ; 3. supprimer un ´l´ment ` une position donn´e : ee a e public final synchronized boolean removeElementAt(int index) throws ArrayIndexOutOfBoundsException ;10.2 Classe java.util.Stack L’image traditionnelle de la pile est celle de la pile d’assiettes, on parle aussi de listeLIFO (Last In First Out). L’insertion et la suppression d’´l´ments se fait par la mˆme ee eextrˆmit´. Les op´rations classiques sur les piles sont PileVide, Empiler, Depiler. e e eLa classe java.util.Stack h´rite de la classe java.util.Vector, et impl´mente les piles. e eVoici les m´thodes de cette classe : e 1. un constructeur sans argument : public Stack() ; 2. pour empiler : public Object push(Object item) ; 3. pour d´piler : e public synchronized Object pop() ; 4. pour acc´der au sommet de la pile (sans le supprimer) : e public synchronized Object peek() ; 5. pour tester si la pile est vide : public boolean empty() ; 6. pour rechercher un objet dans la pile : public synchronized int search(Object o) ;10.3 Classe java.util.StringTokenizer Elle permet le d´coupage de chaˆ e ınes de caract`res en tokens ou unit´s lexicales. La e eclasse java.io.StreamTokenizer est similaire, mais plus sophistiqu´e.eVoici l’essentiel de ce qu’on trouve dans la classe java.util.StringTokenizer :Support de cours programmation Java - GBM2 - 66-
    • 10.3. CLASSE JAVA.UTIL.STRINGTOKENIZERpublic StringTokenizer(String) // constructeur (delimiteurs tnr)public StringTokenizer(String str, String delim, boolean renvDelim) // avec la specification des caracteres de separation,// renvDelim==true les delimiteurs sont consideres comme des tokenspublic StringTokenizer(String str, String delim)public boolean hasMoreTokens()public String nextToken() throws NoSuchElementExceptionpublic boolean hasMoreElements() // equivalent hasMoreTokenspublic Object nextElement() // equivalent nextTokenpublic int countTokens()Support de cours programmation Java - GBM2 - 67-
    • Chapitre 11Entr´es-sorties, paquetage java.io e Le paquetage java.io contient un grand nombre de classes, chacune pourvue d’attri-buts et m´thodes, dont l’objectif est de vous permettre de r´aliser des entr´es et sorties de e e edonn´es. Le tableau ` la fin du chapitre donne les interfaces, classes et exceptions d´finies e a edans ce paquetage. Nous ne d´taillerons que les classes et m´thodes qui me paraissent e eessentielles, pour le reste, vous r´f´rer ` la documentation... ee a11.1 Paquetage java.io Le principe des entr´es/sorties est bas´ sur le concept des flots de donn´es (streams). e e eUn flot est un canal de communication dans lequel les donn´es sont ´crites ou lues de e emani`re s´quentielle. Deux groupes de classes manipulent des flots : e e – les classes qui manipulent des octets (InputStream, OutputStream et leurs classes d´riv´es) e e – celles qui manipulent des caract`res (depuis la version 1.1) (Reader, Write et leurs e classes d´riv´es). e eLe paquetage java.io contient ´galement : e – la classe File qui permet de g´rer tous les acc`s aux informations relatives au syst`me e e e de fichiers, – la classe RandomAccessFile qui permet la lecture et l’´criture dans des fichiers, e – la classe StreamTokenizer qui permet de faire de l’analyse syntaxique de base, – des interfaces comme DataInput et DataOutput (e/s de types primitifs), ObjectInput et ObjectOuput (e/s d’objets), Serialisable... – des exceptions, dont la plus classique IOException.11.2 Classe File Un objet de cette classe repr´sente le nom d’un fichier ou r´pertoire de la machine e ehˆte. Un fichier ou r´pertoire est sp´cifi´ par un chemin relatif (au r´pertoire courant). o e e e eCette classe tend ` s’affranchir des particularit´s des diff´rentes plateformes. La classe a e eRandomAccessFile permet des manipulations plus complexes, mais ce n’est pas l’objet dece cours. 1. Les variables les plus utiles : 68
    • 11.2. CLASSE FILE – separator : chaˆ de s´paration entre r´pertoires d’un chemin (d´pend de la ıne e e e plateforme) 2. Les m´thodes les plus utiles : e – File(File, String) constructeur qui cr´e une instance de File repr´sentant le e e fichier ayant le nom (pr´c´d´ du chemin) donn´ par la chaˆ e e e e ıne, dans le r´pertoire e donn´ par l’argument de type File, e – File(String) constructeur qui cr´e une instance de File qui repr´sente le fichier e e dont le chemin est sp´cifi´ par la chaˆ e e ıne, – File(String, String) constructeur qui cr´e une instance de File qui repr´sente e e le fichier dont le chemin est sp´cifi´ par le premier argument et le nom est sp´cifi´ e e e e par le second, – boolean canRead() teste si l’application peut lire le fichier correspondant ` l’objet a courant, – boolean canWrite() teste si l’application peut ´crire dans le fichier correspon- e dant ` l’objet courant, a – boolean delete() supprime le fichier correspondant ` l’objet courant, a – boolean exists() teste l’existence du fichier correspondant ` l’objet courant, a – String getAbsolutePath() retourne le nom absolu du fichier correspondant ` a l’objet courant, – String getName() retourne le nom du fichier correspondant ` l’objet courant, a – String getPath() retourne le chemin du fichier correspondant ` l’objet courant, a – boolean isDirectory() teste si le fichier correspondant ` l’objet courant est un a r´pertoire, e – boolean isFile() teste si le fichier correspondant ` l’objet courant est un fichier, a – long lastModified() retourne la date de derni`re modification du fichier (peut e servir ` comparer deux fichiers et dire lequel est le plus r´cent), a e – long length() retourne la taille (en nombre d’octets) du fichier correspondant ` a l’objet courant, – String[] list() retourne une liste des fichiers du r´pertoire correspondant ` e a l’objet courant.Exemple 1 : lister le contenu des r´pertoires donn´s sur la ligne de commande : e eimport java.io.File;public class Ls { public static void main(String arg[]){ File dir; for (int i=0;i<arg.length;i++) { dir = new File(arg[i]); System.out.println(dir.getAbsolutePath()+":"); String [] r=dir.list(); for (int j=0;j<r.length;j++) System.out.println("t"+r[j]); } }}Exemple 2 : lister les attributs d’un fichier donn´ sur la ligne de commande (type e(r´pertoire/fichier), taille, droits d’acc`s) : e eSupport de cours programmation Java - GBM2 - 69-
    • 11.3. CLASSES INPUTSTREAM, READER, OUTPUTSTREAM, WRITERimport java.io.File;public class AttributsFichier { public static void main(String arg[]){ File dir; if (arg.length!=1) { System.out.println("usage : java AttributsFichier <nom_fichier>"); } else { dir = new File(arg[0]); if (dir.isFile()) { System.out.println(dir.getAbsolutePath()+" est un fichier"); } else { System.out.println(dir.getAbsolutePath()+" est un repertoire"); } System.out.println("taille : "+dir.length()+" octets"); System.out.println("lecture autorisee : "+(dir.canRed()?"oui":"non")); System.out.println("ecriture autorisee : "+(dir.canWrite()?"oui":"non")); } }}11.3 Classes InputStream, Reader, OutputStream, Writer Il s’agit de classes abstraites qui servent de classes de base pour toutes les autres autresclasses de flots d’entr´es et de sorties. InputStream et OutputStream permettent la lecture e a`et l’´criture de flots d’octets (fichiers binaires).Reader et Writer correspondent ` des flots ede caract`res. Le tableau suivant donne les principales classes d´riv´es, et une description e e esuccincte :Support de cours programmation Java - GBM2 - 70-
    • 11.3. CLASSES INPUTSTREAM, READER, OUTPUTSTREAM, WRITER Flot d’octets Flot de caract`res e Description InputStream Reader Classe abstraite avec les m´thodes de base e BufferedInputStream BufferedReader buff´rise les entr´es (utilisa- e e tion d’une m´moire-tampon) e FileInputStream FileReader lit dans un fichier LineNumberInputStream LineNumberReader garde la trace du nombre de lignes lues ByteArrayInputStream CharArrayReader lit un tableau FilterInputStream FilterReader (classe abstraite) filtre l’entr´e e DataInputStream pas d’´quivalent e lit des donn´es de types primi- e tifs StringInputReader StringReader lit depuis une chaˆ ıde ca- ract`res e pas d’´quivalent e InputStreamReader transforme un flot d’octets en caract`res e OutputStream Writer Classe abtraite avec les m´thodes de base e PrintStream PrintWriter ´crit des valeurs et objets dans e un flot de sortie BufferedOutputStream BufferedReader buff´rise les sorties e FileOutputStream FileWriter ´crit dans un fichier de sortie e DataOutputStream pas d’´quivalence e ´crit des donn´es de types pri- e e mitifs pas d’´quivalent e OutputStreamWrite transforme un flot d’octets en un flot de caract`res e11.3.1 M´thodes des classes InputStream, Reader, OutputStream, e Writer 1. les m´thodes de lecture : e – int read() lit simplement un octet dans le flot et le retourne sous forme d’entier (-1 si on a atteint la fin du flot), – int read(byte b[])lit plusieurs octets ` la fois et les stocke dans le tableau a (lance une exception IOException si le tableau n’est pas assez grand), retourne le nombre d’octets lus (-1 si on a atteint la fin du flot), – int read(byte b[],int off, int len) est la mˆme que la pr´c´dente mais on e e e pr´cise ici o` placer les octets dans le tableau (` partir de l’indice off et sur une e u a longueur len). 2. les autres m´thodes de InputStream e – long skip(long n) est utilis´ pour sauter n octets dans le flot, retourne le nombre e d’octets r´ellement saut´s (-1 si on a atteint la fin du flot), e e – int available() indique le nombre d’octets pr´sents dans le flot d’entr´e, cette e e m´thode permet d’´viter le blocage r´sultant d’un ordre de lecture dans un flot o` e e e u il n’y a pas de donn´es disponibles, e – synchronized void mark(int limit) place une marque ` la position courante a dans le flot (on peut ensuite revenir ` cette marque avec la m´thode reset() qui a eSupport de cours programmation Java - GBM2 - 71-
    • 11.4. CLASSE JAVA.LANG.SYSTEM suit), l’entier limit sp´cifie le nombre maximum d’octets que l’on peut lire avant e que la marque devienne invalide, – synchronized void reset() retourne dans le flot ` la derni`re position marqu´e a e e (par la m´thodemark()), e – boolean markSupported indique si le flot peut ˆtre marqu´ ou non, e e – void close() ferme un flot d’entr´e et lib`re toutes les ressources associ´es, mˆme e e e e si cela n’est pas vraiment n´cessaire, c’est une bonne habitude de faire appel e explicitement ` cette m´thode. a e 3. Les m´thodes d’´criture : e e – void write(int b) ´crit l’octet donn´ sur le flot de sortie, e e – void write(byte b[]) ´crit les octets du tableau donn´ sur le flot de sortie, e e – public void write(byte b[],int off,int len) ´crit len octets du tableau e donn´ ` partir de la position off. ea 4. Les autres m´thodes de OutputStream : e – void flush(), sert plutˆt pour les flots buff´ris´s et force l’´criture du contenu o e e e du buffer, – void close() ferme un flot de sortie et lib`re les ressources associ´es. e e Les m´thodes des classes Reader et Writer sont similaires ` celles de leur correspon- e adantes InputStream et OutputStream. Nous ne les d´crivons donc pas en d´tail. e e11.4 Classe java.lang.System Vous la connaissez d´j`, elle vous permet de r´aliser des entr´es-sorties standards. ea e eCette classe constitue une interface avec le syst`me d’exploitation. Trois flots standards : eSystem.in, System.out et System.err. Voici l’essentiel de cette classe :public static final InputStream in // l’entree standardpublic static final PrintStream out // la sortie standardpublic static final PrintStream err // la sorite standard (erreur)public static void setIn(InputStream in) // pour rediriger l’entree stdpublic static void setOut(PrintStream out) // pour rediriger la sortie stdpublic static void setErr(PrintStream err).......public static Properties getProperties() Throws: SecurityException // les proprietes courantes du systeme : // java.version, java.home,..., os.name,file.separator ("/" sur UNIX) // path.separator(":" sur UNIX), line.separator("n" sur UNIX), // user.name,user.home,........public static String getProperty(String key) Throws: SecurityException // recupere les prop selon la cle (cf ci-dessus)........public static void exit(int status)public static void gc() // lance le ramasse miettes......... La classe java.lang.System a trois attributs : in le flot d’entr´e standard, out le eflot de sortie standard et err le flot d’erreur standard (la plupart du temps identique ` aSystem.out). System.in est une instance de InputStream et correspond (la plupart duSupport de cours programmation Java - GBM2 - 72-
    • 11.4. CLASSE JAVA.LANG.SYSTEMtemps) au clavier. On peut donc utiliser les m´thodes de cette classe. On peut aussi le econvertir en un Reader. Pour System.out, qui est une instance de PrintStream, vousl’avez d´j` utilis´, avec ses deux m´thodes print et println. Nous n’y reviendrons pas. ea e eL’exemple ci-dessous illustre la lecture au clavier de caract`res : eimport java.io.*;class Lecture { public static void main(String arg[]){ char c; try { System.out.print("Saisie :"); c=(char)System.in.read(); System.out.println(" c= "+c); } catch (IOException e) { System.out.println(e.toString()); } try { Reader in = new InputStreamReader(System.in); c=(char)in.read(); System.out.println(" c= "+c); } catch (IOException e) { System.out.println(e.toString()); } }}/*** exemple d’execution ***Saisie :abcdef c= a c= bVoici un exemple de lecture au clavier d’une chaˆ de caract`res, utilisant la classe Reader. ıne eimport java.io.*;class Lecture2 { public static void main(String arg[]){ char buf[]=new char[10]; try { Reader in = new InputStreamReader(System.in); in.read(buf,0,5); String s = new String(buf); System.out.println("chaine lue :"+s); } catch (IOException e) { System.out.println(e.toString()); } }}/*** exemple d’execution ***gbm-server:~/coursJava/Td/ES> java Lecture2abcdefghijkchaine lue :abcde*/Support de cours programmation Java - GBM2 - 73-
    • 11.4. CLASSE JAVA.LANG.SYSTEM11.4.1 Classes PrintStream et PrintWriter Elles sont bien utiles puisqu’elles permettent d’´crire des valeurs ou des objets sur des eflots de sortie. En fait, on conseille d’utiliser la seule classe PrintWriter (PrintStreamn’est encore l` que pour des raisons de compatibilit´ entre versions). Le constructeur de a ePrintWriter attend un OutputStream, ou bien un Writer. Ensuite, vous l’utilisez commevous utilisiez System.out, avec essentiellement les m´thodes print et println ! e11.4.2 Classes BufferedInputStream (BufferedReader) et BufferedOutputStream (BufferedWriter) Comme leur nom l’indique, ces classes fournissent un tampon (ou buffer) d’entr´e (ou ede sortie). Cela implique une meilleure performance car les acc`s disque sont plus lents que eles acc`s m´moire. e e 1. Quelques m´thodes de la classe BufferedInputStream : e – le constructeur attend un param`tre de type InputStream, e – on utilise principalement les m´thodes read() et read(byte[],int,int), simi- e laires ` celles de la classe m`re. a e 2. Quelques m´thodes de la classe BufferedOutputStream : e – le constructeur attend un param`tre de type OutputStream et,´ventuellement une e e taille de buffer, – on utilise les m´thodes write(int), write(byte[],int,int) et flush() simi- e laires ` celles de la classe m`re. a e 3. Quelques m´thodes de la classe BufferedReader : e – le constructeur attend un param`tre de type Reader, e – on utilise les m´thodes read() et read(char[],int,int), similaires ` celles de e a la classe m`re et surtout la m´thode readLine()qui permet la lecture d’une ligne e e de texte. 4. Quelques m´thodes de la classe BufferedWriter : e – le constructeur attend un param`tre de type Writer, e – on utilise les m´thodes flush(), write(int), write(char[],int,int) similaires e a ` celles de la classe m`re et la m´thode newLine()qui ´crit un “retour chariot”. e e eExemple de lecture d’une ligne de texte :import java.io.*;class Lecture3 { public static void main(String arg[]){ String s; BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); try { s=in.readLine(); System.out.println("chaine lue :"+s); } catch (IOException e) { System.out.println(e.toString()); } }}Support de cours programmation Java - GBM2 - 74-
    • 11.4. CLASSE JAVA.LANG.SYSTEM/*** exemple d’execution ***gbm-server:~/coursJava/Td/ES> java Lecture3bonjour, comment va ?chaine lue :bonjour, comment va ?11.4.3 Classes FileInputStream (FileReader) et FileOutputStream (FileWriter) Ce sont les classes pour l’´criture et la lecture dans un fichier. On instancie un objet de ela classe FileInputStream avec un nom ou avec un objet de la classe File, mais attentionil s’agit de fichiers binaires. De mˆme on instancie un FileReader. Les m´thodes sont les e emˆmes que celles des classes m`res. De mˆme pour les flots de sortie FileOutputStream e e eet FileWriter.Dans l’exemple qui suit, on cr´e un fichier binaire dans lequel sont ´crits les entiers de 0 ` 9. e e aEssayez d’ex´cuter ce programme et de visualiser le fichier obtenu (il n’est gu`re lisible !). e eimport java.io.*;class EcritureBinaire { public static void main(String arg[]){ try { FileOutputStream fichier = new FileOutputStream(new File("fichier.dat")); for (int i=1;i<10;i++) fichier.write(i); } catch (IOException e) { System.out.println(e.toString()); } }}11.4.4 Classes DataInputStream et DataOutputStream Elle est utile pour lire des donn´es de types primitifs dans des fichiers binaires. Voici eles m´thodes que vous serez le plus susceptibles d’utiliser : e boolean readBoolean() lit un bool´en e byte readByte() lit un octet int readInt() lit un entier char readChar() lit un caract`re e float readFloat() lit un float double readDouble() lit un double ... Bien sˆr, la classe DataInputStream a sa classe correspondante DataOutpuStream pour u´crire des donn´es de types primitifs. Les m´thodes sont similaires, mais se nommente e ewriteBoolean, writeInt, etc.L’exemple qui suit illustre l’´criture de donn´es typ´es dans un fichier binaire, puis leur e e electure.import java.io.*;class LectEcriture {Support de cours programmation Java - GBM2 - 75-
    • 11.5. CLASSE STREAMTOKENIZER public static void main(String arg[]){ try{ DataOutputStream out= new DataOutputStream(new FileOutputStream(arg[0])); out.writeInt(3); out.writeDouble(3.2); out.writeChar(’c’); out.writeUTF("bye"); out.close(); } catch (IOException e) { System.out.println(e.toString()); } try { DataInputStream in=new DataInputStream(new FileInputStream(arg[0])); System.out.println("contenu du fichier :"); System.out.println(in.readInt()+" "+in.readDouble()+" "+in.readChar()+" "+in.readUTF()); in.close(); } catch (IOException e) { System.out.println(e.toString()); } }}/*** exemple d’execution ***gbm-server:~/coursJava/Td/ES> java LectEcriture sortiecontenu du fichier :3 3.2 c bye11.5 Classe StreamTokenizer Cette classe fournit les m´thodes permettant de faire de l’analyse syntaxique rudimen- etaire sur les donn´es en entr´e. La lecture se fait d’unit´ lexicale (token) en unit´ lexicale. Le e e e econstructeur d’un StreamTokenizer prend en argument un objet StreamInput ou ReaderVoici les variables et m´thodes les plus utiles : e double nval si le token est un nombre, c’est sa valeur String sval si le token est un mot, c’est la chaˆ correspon- ıne dante int TT EOF constante indiquant la fin du flot int TT EOL constante indiquant la fin d’une ligne int TT NUMBER constante indiquant un nombre int TT WORD constante indiquant un mot int ttype contient le type du token et prend une des va- leurs constantes d´finies pr´c´demment e e e int nextToken() lit le token suivant, son type est rang´ dans e ttype et sa valeur ´ventuellement dans nval ou e sval int lineno() est une m´thode qui retourne le num´ro de ligne, e e void parseNumbers() sp´cifie que ce sont des nombres qui sont ana- e lys´s eSupport de cours programmation Java - GBM2 - 76-
    • 11.6. AUTRES EXEMPLES UTILESExemple d’analyse de l’entr´e lue au clavier : eimport java.io.*;class Analyse { public static void main (String[] argv) throws IOException { int somme=0,nb=0; int type; String stop=new String("fin"); System.out.println("Donnez le nom de l’etudiant, et ses notes, terminez avec fin"); StreamTokenizer entree= new StreamTokenizer (new InputStreamReader(System.in)); type=entree.nextToken(); if ((type!=StreamTokenizer.TT_WORD)) { System.out.println("donnez d’abord le nom !"); } else { String nom=entree.sval; while(true) { type=entree.nextToken(); if (type==StreamTokenizer.TT_NUMBER) { somme+=(int)entree.nval; nb++; } else if ((type==StreamTokenizer.TT_WORD)&&(stop.equals(entree.sval))) break; } System.out.println("La moyenne de "+nom+" est "+((double)somme/nb)); } }}/******** exemple d’executionDonnez le nom de l’etudiant, et ses notes, terminez avec finmachin 10 1210sgdb12finLa moyenne de machin est 11.011.6 Autres exemples utiles Vous pourrez consulter le site de I.Charon pour d’autres exemples (http ://www.infres.enst.fr/ cha-ron/coursJava/fichiersEtSaisies/index.html) La classe java.net.URL repr´sente une URL (i.e. une adresse de ressource sur le Web). eOn peut, ` partir d’un tel objet, ouvrir une connection et obtenir un flot ` partir de l’URL. a aL’exemple ci-dessous vous donne une illustration :import java.net.*;import java.io.*;Support de cours programmation Java - GBM2 - 77-
    • 11.6. AUTRES EXEMPLES UTILESclass LectURL { public static void main(String arg[]) throws MalformedURLException{ String s; URL monUrl = new URL("http://www.esil.univ-mrs.fr/~chaouiya/Java/Individu.java"); try { InputStream in1=monUrl.openStream(); BufferedReader in2 = new BufferedReader(new InputStreamReader(in1)); s=in2.readLine(); in2.close(); System.out.println("chaine lue :"+s); } catch (IOException e) { System.out.println(e.toString()); } }}/*** exemple d’execution ***gbm-server:~/coursJava/Td/ES> java LectURLchaine lue :class Individu {*/ Les exemples qui suivent montrent l’utilisation de StringTokenizer et des m´thodes ede conversion de chaˆ ınes en objets enveloppes comme Integer, Double...import java.io.*;import java.util.*;class SaisieClavier { public static void main (String[] argv) throws IOException, NumberFormatException { int somme=0; String ligne; StringTokenizer st; BufferedReader entree =new BufferedReader(new InputStreamReader(System.in); ligne=entree.readLine(); while(ligne.length() > 0) { st=new StringTokenizer(ligne); while(st.hasMoreTokens()) somme+=Integer.parseInt(st.nextToken()); ligne=entree.readLine(); } System.out.println("La somme vaut : "+somme); }}/******* exemple d’executiongbm-server:~/coursJava/Td/ES> java SaisieClavier1 234La somme vaut : 10Autre exemple :import java.io.*;import java.util.*;class SaisieClavier {Support de cours programmation Java - GBM2 - 78-
    • 11.6. AUTRES EXEMPLES UTILES public static void main (String[] argv) throws IOException, NumberFormatException { int entier;; BufferedReader entree =new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(entree.readLine()); entier=Integer.valueOf(st.nextToken()).intValue(); }}Support de cours programmation Java - GBM2 - 79-
    • 11.6. AUTRES EXEMPLES UTILES Nom Descriptif Interfaces : DataInput lecture de types primitifs Java DataOutput ´criture de types primitifs Java e Externalizable, FilenameFilter ObjectInput (h´rite de DataInput lecture d’objets e ObjectInputValidation ObjectOutput (h´rite de DataOutput) ´criture d’objets e e Serializable pour la sauvegarde d’objets Classes : BufferedInputStream,BufferedOutputStream dans ce chapitre BufferedReader,BufferedWriter dans ce chapitre ByteArrayInputStream,ByteArrayOutputStream CharArrayReader,CharArrayWriter DataInputStream, DataOutputStream dans ce chapitre File dans ce chapitre FileDescriptor dans ce chapitre FileInputStream, FileOutputStream dans ce chapitre FileReader, FileWriter dans ce chapitre FilterInputStream, FilterOutputStream FilterReader, FilterWriter InputStream InputStreamReader LineNumberInputStream, LineNumberReader ObjectInputStream ,ObjectOutputStream ObjectStreamClass OutputStream, ObjectOutputStream OutputStreamWriter PipedInputStream,PipedOutputStream PipedReader, PipedWriter PrintStream, PrintWriter PushbackInputStream,PushbackReader RandomAccessFile Reader cf plus loin SequenceInputStream StreamTokenizer dans ce chapitre StringBufferInputStream StringReader, StringWriter Writer dans ce chapitre Exceptions : CharConversionException,EOFException FileNotFoundException,IOException InterruptedIOException, InvalidClassException InvalidObjectException, NotActiveException NotSerializableException, ObjectStreamException OptionalDataException, StreamCorruptedException SyncFailedException, UTFDataFormatException UnsupportedEncodingException WriteAbortedExceptionSupport de cours programmation Java - GBM2 - 80-
    • Chapitre 12Applets, les bases On pr´sente dans ce chapitre l’essentiel de ce qu’il faut savoir pour d´velopper des e eapplets qui sont des applications Java qui tournent dans un navigateur. Nous verrons ensuitecomment composer une interface graphique, puis comment la faire fonctionner.12.1 Introduction Jusque l`, nous avons travaill´ avec des applications ind´pendantes. Il s’agit de pro- a e egrammes, comparables ` ceux ´crits dans d’autres langages, dont le point d’entr´e est la a e em´thode main de la classe donn´e en argument de la commande java (une application e eind´pendante est ex´cut´e directement par la JVM) et d´clar´e comme suit : e e e e epublic static void main(String [] arg) Les applets1 sont des applications Java tr`s particuli`res : e e – elles s’ex´cutent dans un browser (navigateur) ou un appletviewer et non pas sous le e contrˆle direct de la JVM, o – elles ne peuvent acc´der ` toutes les ressources du syst`me, pour des raisons ´videntes e a e e de s´curit´, e e – elles poss`dent diff´rents points d’entr´e, en fonction de leur cycle de vie (init, e e e start, stop,...), – elles sont des applications graphiques particuli`res qui d´rivent de la classe Applet. e e Une applet est donc un composant graphique (Component), qui peut contenir d’autrescomposants (Component) que l’on pourra placer (Panel). Nous reverrons les composantsgraphiques plus loin dans ce chapitre. La figure 12.1 donne l’arbre d’h´ritage de la classe ejava.applet.Applet.12.2 Cr´er une applet e Pour cr´er une applet, vous devez cr´er une sous-classe de la classe Applet qui fait e epartie du paquetage java.applet. Cette classe fournit l’essentiel du comportement requis 1 la terminologie fran¸aise serait appliquette ou encore appelette, mais ne semble pas souvent cadopt´e e 81
    • ´ 12.2. CREER UNE APPLET £   java.lang.Object ¢ ¡ £   java.awt.Component ¢ ¡ £   java.awt.Container ¢ ¡ £   java.awt.Panel ¢ ¡ £   java.applet.Applet ¢ ¡ Fig. 12.1 – arbre h´ritage de la classe Applet e pour une applet pour qu’elle puisse ˆtre ex´cut´e dans un navigateur supportant Java. Elle e e e permet aussi d’utiliser toutes les fonctionnalit´s d’un composant du paquetage awt. e Bien sˆr, votre applet peut faire appel ` d’autres classes d´crites par ailleurs, mais la u a e classe initiale de l’applet doit avoir une signature comme suit : public class monApplet extends java.applet.Applet ... Notez que le mot cl´ public est ici indispensable pour la classe principale de votre applet, e par contre les classes utilis´es que vous cr´ez ne sont pas n´cessairement d´clar´es publiques. e e e e e Quand un navigateur rencontre votre applet dans une page Web, il va charger votre classe initiale ` travers le r´seau, ainsi que les autres classes utilis´es au fur et ` mesure des a e e a besoins. Cela peut entraˆ ıner des pertes de performances (pour ´viter cette perte de temps e en chargement ` travers le r´seau, une solution consiste ` utiliser des archives...) a e a Cycle de vie d’une applet :initialisation phase o` le navigateur charge l’applet et lui demande d’effectuer les initialisations u n´cessaires (m´thode public void init()), cette phase n’a lieu qu’une seule fois, e e visible chaque fois que l’applet devient ou redevient visible ` l’utilisateur, il est demand´ ` a ea l’applet de se redessiner (m´thode public void start()), e invisible chaque fois que l’applet devient ou redevient invisible ` l’utilisateur, il lui est demand´ a e de proc´der ` la lib´ration ´ventuelle des ressources utilis´es, ou ` l’interruption de e a e e e a certaines de ses activit´s comme la suspension d’une animation graphique (m´thode e e public void stop()), cette phase est li´e ` la pr´c´dente, e a e earrˆt d´finitif lorsque l’applet doit s’arrˆter, il lui est demand´ de se terminer proprement (m´thode e e e e e public void destroy()), dessiner est la phase durant laquelle l’applet dessine effectivement quelque chose (texte, lignes, figures,...) cette phase peut avoir lieu des centaines de fois durant le cycle de vie de l’applet (m´thode public void paint(Graphics g), d´finie dans la classe e e Container du paquetage java.awt). Notez que l’argument de la m´thode paint est e une instance de la classe Graphics (du paquetage java.awt), nous y reviendrons. C’est la classe Applet qui donne les prototypes des m´thodes init, start, stop, e Support de cours programmation Java - GBM2 - 82-
    • 12.3. INTRODUCTION D’UNE APPLET DANS UNE PAGE WEBdestroy.Exemple : fichier Bonjour.javaimport java.applet.*;import java.awt.*;public class Bonjour extends Applet { public void paint(Graphics g) { g.setFont(new Font("TimesRomman",Font.BOLD,30)); g.setColor(Color.blue); g.drawString("Bonjour !",50,50); }}12.3 Introduction d’une applet dans une page Web Pour ex´cuter une applet, comme cela se fait dans un navigateur, il faut cr´er une page e eHTML qui contiendra le nom de la classe principale, la taille et les param`tres de l’applet. eCela se fait par la balise (forme minimale) :<APPLET CODE="MonApplet.class" WIDTH = taille_en_pixels HEIGHT = taille_en_pixels</APPLET> – l’attribut CODE donne le nom du fichier (extension .class) contenant l’applet. S’il ne se trouve pas dans le mˆme r´pertoire que le fichier HTML, il faudra utiliser e e l’attribut CODEBASE d´crit plus loin, e – les attributs WIDTH et HEIGHT sont n´cessaires et donnent la taille de la boˆ r´serv´e e ıte e e a ` l’affichage de votre applet sur la page Web, – le texte entre les balises <APPLET> et </APPLET> est affich´ par les navigateurs qui e ne comprennent pas ces balises (notamment ceux qui ne supportent pas les applets), il est donc bon de pr´voir un petit message pour que vos lecteurs qui n’ont pas de e navigateurs supportant Java, voient autre chose qu’une ligne blanche muette...La balise <APPLET> a ´t´ pr´sent´e ci-dessus dans sa forme minimale. Ellea en fait plus de ee e efonctionnalit´s (pour beaucoup, identiques ` celles de la balise <IMG>) : e a<APPLET ... liste d’attributs ..>[<PARAM NAME={it nomparam1} VALUE={it valeurparam1}>][<PARAM NAME={it nomparam1} VALUE={it valeurparam1}>]...[texte pour les navigateurs ne comprenant pas Java]</APPLET> – l’attribut ALIGN d´finit comment l’applet doit ˆtre align´e dans la page, il peut e e e prendre une des valeurs suivantes : LEFT, RIGHT, TOP, TEXTTOP, MIDDLE, ABSMIDDLE, BASELINE, BOTTOM, ABSBOTTOM,Support de cours programmation Java - GBM2 - 83-
    • 12.3. INTRODUCTION D’UNE APPLET DANS UNE PAGE WEB – les attributs HSPACE et VSPACE sont utilis´s pour d´finir un espace entre l’applet et e e le texte qui l’entoure, – l’attribut CODEBASE permet de sp´cifier le r´pertoire ou l’URL o` trouver l’applet, si e e u elle n’est pas au mˆme endroit que le fichier HTML de la page la contenant. e Enfin, il est possible de passer des param`tres ` l’applet. Cela se fait avec la balise e a<PARAM NAME=nom parametre VALUE=valeur parametre> plac´e dans le champ de la ba- elise >APPLET>.Exemple : une applet qui affiche le texte qu’on lui passe en param`tre (fichier Texte.java), eet le fichier HTML permettant de charger cette applet – fichier Texte.java : import java.applet.*; import java.awt.*; public class Texte extends Applet { String leTexte; public void init(){ leTexte=getParameter("le_texte"); } public void paint(Graphics g) { g.setFont(new Font("mafonte",Font.ITALIC,30)); g.setColor(Color.blue); g.drawString(leTexte,50,50); } } – fichier Texte.html <HTML> <HEAD> <TITLE>Applet simple qui affiche un texte</title> </HEAD> <BODY> <h1>Applet simple qui affiche un texte</h1> <APPLET CODE = "Texte.class" WIDTH=300 HEIGHT = 200> <PARAM NAME=le_texte VALUE="Bonjour !"> Votre navigateur ne supporte pas Java ?! Bonjour quand meme ! </APPLET> </BODY> </HTML>Autres exemples : – L’exemple ci-dessous illustre le cycle de vie d’une applet : /******* le fichier java *******/ import java.awt.*; import java.applet.*; import java.util.*; public class Affiche extends Applet { public Vector lesAppels; public void init() { lesAppels=new Vector(); lesAppels.addElement("init");Support de cours programmation Java - GBM2 - 84-
    • 12.3. INTRODUCTION D’UNE APPLET DANS UNE PAGE WEB } public void start(){ lesAppels.addElement("start"); } public void stop(){ lesAppels.addElement("stop"); } public void paint(Graphics g) { lesAppels.addElement("paint"); Enumeration e=lesAppels.elements(); int y=15; while(e.hasMoreElements()) { g.drawString((String)e.nextElement(),20,y); y+=10; } } } /******* le fichier HTML ******/ <html> <head> <title>Premi&eacute;re Applet</title> </head> <body> <h1>Premi&eacute;re Applet</h1> <applet code = "Affiche.class" width=300 height = 200> </applet> </body> </html> – un petit exemple qui illustre quelques unes des m´thodes de la classe java.awt.Graphics : e import java.awt.*; import java.applet.*; public class ParamGraphic extends Applet { public void init() { String couleur = getParameter("couleur"); } public Color rendCouleur(String s) { if (s==null)return Color.black; else if (s.equals("rouge")) return Color.red; else if (s.equals("vert")) return Color.green; else if (s.equals("bleu")) return Color.blue; else if (s.equals("magenta")) return Color.magenta; else if (s.equals("pink")) return Color.pink; else if (s.equals("orange")) return Color.orange; else if (s.equals("cyan")) return Color.cyan; else if (s.equals("yellow")) return Color.yellow; return Color.black; } public void paint(Graphics g) { g.drawString((String)getParameter("titre"),20,10); g.setColor(rendCouleur((String)getParameter("couleur")));Support de cours programmation Java - GBM2 - 85-
    • 12.4. INTERFACE APPLETCONTEXT g.fillRect(30,30,100,100); g.fillOval(130,130,40,40); } } /******* le fichier HTML *********/ <html> <head> <title>Un exemple tout simple</title> </head> <body> <h1>Un exemple tout simple</h1> <applet code = "ParamGraphic.class" width=400 height = 300> <PARAM NAME=couleur VALUE="bleu"> <PARAM NAME=titre VALUE="comment passer des param`tres"> e </applet> </body> </html>12.3.1 Classe Applet, plus de d´tails e Comme il a ´t´ dit pr´c´demment, la classe Applet h´rite de la classe Panel qui ee e e eelle mˆme h´rite de la classe Container. Ainsi beaucoup de m´thodes sont d´crites dans e e e eles classes m`res (comme les m´thodes que vous utiliserez beaucoup, add, setLayout, e esetBackground, et bien d’autres). Ici on ne donne que les m´thodes propres ` la classe e aApplet qui sont tr`s utilis´es : e e – void destroy() : appel´e par le browser pour informer l’applet qu’elle doit se e d´truire et lib´rer toutes les ressources utilis´es, e e e – AppletContext getAppletContext() : d´termine l’AppletContext (cf. 12.4), e – URL getCodeBase() : r´cup`re l’URL de base de l’applet (o` se trouve son code) e e u – URL getDocumentBase() : c’est l’adresse pr´c´dente suivie du nom du fichier e e – String getParameter(String name) : retourne la valeur du param`tre ayant le e nom pass´ en param`tre et qui est d´fini dans la balise HTML, e e e – void init() : appel´e par le browser pour charger l’applet, e – boolean isActive() : d´termine si l’applet est active, e – void resize(Dimension d) : demande que l’aplet soit redimensionn´e (cf.classe e java.awt.Dimension dans la documentation) – void resize(int width, int height) : mˆme chose que pr´c´demment, e e e – void start() : appel´e par le browser pour que l’applet d´marre son ex´cution e e e – void stop() : appel´e par le browser pour que l’applet stoppe son ex´cution, e e12.4 Interface AppletContext Elle permet d’obtenir des informations sur l’environnement dans lequel l’applet estex´cut´e (Navigateur, visualisateur d’applet...). Les m´thodes de cette interface peuvent e e eˆtre utilis´es par une applet pour obtenir ces informations. Voici les deux plus utilis´ese e e(pour le reste, consulter la documentation) : – Enumeration getApplets() : trouve toutes les applets contenues dans le document correspondant ` cet AppletContext, aSupport de cours programmation Java - GBM2 - 86-
    • 12.4. INTERFACE APPLETCONTEXT – void showDocument(URL url) : remplace la page Web par celle r´f´renc´e par l’URL ee e donn´e en param`tre. e eSupport de cours programmation Java - GBM2 - 87-
    • Chapitre 13Paquetage java.awt et lesinterfaces graphiques Vous avez franchi la premi`re ´tape qui consiste ` comprendre comment fonctionnent e e ales applets. Il faut maintenant se familiariser avec les outils fournis par Java pour dessinersur la page, actualiser le contenu de la page, g´rer les ´v´nements souris et clavier, cr´er e e e edes ´l´ments d’interface utilisateur. ee Attention, toutes les interfaces que vous serez amen´s ` ´crire ne seront pas n´cessairement e ae eincluses dans une applet, elles peuvent tr`s bien ˆtre li´es ` une application ind´pendante. e e e a eOn pourra consulter dans l’annexe ?? des diagrammes repr´sentant la hi´rarchie des classes e edu paquetage java.awt.13.1 Classe java.awt.Graphics Elle d´finit la plupart des m´thodes graphiques de Java. On n’a pas ` cr´er explicitement e e a eune instance de Graphics (c’est de toute fa¸on une classe abstraite). Dans la m´thode paint c evue pour les applets, on re¸oit un objet de cette classe. Dessiner sur cet objet revient ` c adessiner sur la portion de fenˆtre graphique allou´e ` l’applet. Le syst`me des coordonn´es e e a e eplace l’origine dans le coin sup´rieur gauche du composant graphique. Le tableau ci-apr`s e edonne l’essentiel des m´thodes trouv´es dans la classe Graphics. e e 88
    • 13.1. CLASSE JAVA.AWT.GRAPHICS (0,0) X E Component (width-1,height-1) Y c Fig. 13.1 – Syst`me de coordonn´es dans un composant graphique e e l 5  £ E2 T h Thg 4¡ c ¢ E3 c lg Fig. 13.2 – Param`tres d’un rectangle arrondi e M´thode e Description drawLine(x1,y1,x2,y2) ligne droite de (x1,y1)` (x2,y2) a drawRect(x,y,l,h) rectangle vide, (x,y) coin sup.gauche, largeur l, hauteur h fillRect(x,y,l,h) rectangle plein, (x,y) coin sup.gauche, largeur l, hauteur h drawRoundRect(x,y,l,h,lg,hg) rectangle vide ` coins arrondis,(x,y) coin sup.gauche, a largeur l, hauteur h, angle largeur lg, hauteur hg fillRoundRect(x,y,l,h,lg,hg) rectangle plein ` coins arrondis, ... a draw3DRect(x,y,l,h,bool) rectangle vide effet 3D en relief (bool=true) ou enfonc´ (bool=false) e draw3DRect(x,y,l,h,bool) rectangle plein effet 3D... drawPolygon(tabX,tabY,n) polygone vide ` n sommets, tabX tableau abscisses, tabY ordonn´es a e fillPolygon(tabX,tabY,n) polygone plein ` n sommets, tabX, tableau abscisses, tabY ordonn´es a e drawPolygon(polyg) polygone vide d´fini par l’instance de Polygon e fillPolygon(polyg) polygone plein d´fini par l’instance de Polygon e drawOval(x,y,l,h) ovale vide d´limit´ par le rectangle d´fini par x,y,l et h e e e fillOval(x,y,l,h) ovale plein d´limit´ par le rectangle d´fini par x,y,l et h e e e On dispose de deux m´thodes pour l’affichage de texte : e – drawString(chaine, x, y) – drawChars(tabChar,dbt,fin,x,y) (tableau de caract`res, indice du permier ca- e ract`re, indice du dernier, position d’affichage du premier). e Pour afficher du texte, il faut cr´er une instance de la classe Font d´finie par son nom, e eson style (bold, italic) et sa taille. Des noms de polices classques : ‘‘TimesRoman’’,‘‘Courrier’’, Helvetica’’. Les styles sont des constantes enti`res d´finies dans la classe e eFont : Font.PLAIN, Font.BOLD, Font.ITALIC. C’est la m´thode setFont(laPolice) qui epermet de sp´cifier la police ` utiliser. Vous consulterez avec profit la documentation sur e ala classe java.awt.Font. Pour dessiner un objet ou du texte, on utilise la couleur courante du contexte graphique.Cette couleur peut ´videmment ˆtre chang´e avec la m´thode setColor(laCouleur) qui e e e eprend en param`tre une instance de la classe java.awt.Color. eSupport de cours programmation Java - GBM2 - 89-
    • ´ 13.2. ELEMENTS D’INTERFACES Bien sˆr, on peut aussi sp´cifier la couleur de fond du composant graphique grˆce ` u e a ala m´thode setBackground(laCouleur) de la classe java.awt.Component (dont h´rite la e eclasse Applet). Le dernier exemple du chapitre 12 vous donne un exemple illustrant l’utilisation descouleurs.13.2 El´ments d’interfaces e Il y a deux types d’´l´ments dans une interface, des conteneurs (containers) et des eecomposants (components). Les premiers, comme leur nom l’indique sont susceptibles decontenir des ´l´ments, ils constituent la base de l’interface (Panel, Frame, Window...). Les eeseconds sont ajout´s ` un conteneur, il s’agit de boutons, cases ` cocher, ascenseurs... e a a(Button, Checkbox, Scrollbar, ...). En plus de ces ´l´ments, le paquetage java.awt fournit eedes gestionnaires de mise en page (FlowLayout, BorderLayout, ...), la classe Event quipermet de d´tecter tous les ´v´nements externes (entr´es clavier, clic de souris, ...), des e e e eexceptions. Il n’est pas question ici de faire une pr´sentation exhaustive de la programmation gra- ephique en Java, mais plutˆt de donner les ´l´ments essentiels, ` travers quelques exemples o ee asignificatifs.13.2.1 Conteneurs Pour pouvoir placer les composants il faut un conteneur. Tous les conteneurs h´ritent ede la classe java.awt.Container. Les deux principaux sont : – la classe Window qui cr´e une nouvelle fenˆtre, ses classes d´riv´es Frame (fenˆtre e e e e e avec un bord et une barre de menu) et Dialog (fenˆtre pour le choix d’une fichier e par exemple) sont ´galement tr`s utiles, e e – la classe Panel est la classe m`re de la classe Applet. Elle propose un espace dans e lequel une application peut placer des composants mais aussi d’autres panneaux. Par d´faut les composants sont ajout´s de gauche ` droite et de haut en bas. Il existe e e ades gestionnaires pour g´rer le placement des composants, ce sont les LayoutManager(cf. e13.3).13.2.2 Composants On les appelle aussi des widgets(pour WInDows gadGET), ce sont des composantsgraphiques que l’on peut ajouter dans des conteneurs. 1. Label pour afficher du texte qui ne doit pas changer, 2. TextField pour une zone de saisie d’une ligne de texte, 3. TextArea pour une zone de saisie d’un paragraphe, 4. Button pour un bouton, 5. Checkbox pour une case ` cocher, a 6. CheckboxGroup pour un groupe de cases ` cocher, a 7. Choice pour une liste de choix, List pour une liste d´filante, e 8. Scrollbar pour un ascenseur,Support de cours programmation Java - GBM2 - 90-
    • ´ 13.2. ELEMENTS D’INTERFACES Composant Constructeurs M´thodes e Label Label(), Label(String) setText(String), getText() TextField TextField(), h´rite de TextComponent, getText() e TextField(int), TextField(String) TextArea TextArea(), h´rite de TextComponent, getText() e TextArea(int,int),TextArea(String) Button Button(), Button(String) getLabel(), setLabel(String)(cf.13.6) Checkbox Checkbox(), Checkbox(String), getLabel(), getState(), setLabel(String) Checkbox(String, boolean), setState(boolean) Checkbox(String, boolean, CheckboxGroup) CheckboxGroup CheckboxGroup() getSelectedCheckbox(), setSelectedCheckbox(Checkbox) Choice Choice() add(String), addItem(String),getItem(int) getSelectedIndex(), getSelectedItem(), remove(int), remove(String) Scrollbar Scrollbar() (vertical),Scrollbar(int) setOrientation(int), setMinimum(int) setMaximum(),setValues(int,int,int,int) getValue(), getMinimum(), getMaximum() Tab. 13.1 – Composants et quelques unes de leurs m´thodes e 9. Canvas pour une zone graphique. Chacun de ces composants h´rite bien sˆr des attributs et m´thodes de la classe e u ecomponent mais a aussi ses attributs et m´thodes sp´cifiques. Le tableau 13.1 donne les e em´thodes essentielles associ´es ` chacun de ses composants, mais le mieux est, encore une e e afois, de consulter la documentation ! Nous ne donnons pas ici les m´thodes de gestion ed’´v´nements, souvent communes ` beaucoup de composants, qui seront d´crites plus loin e e a e(cf. 13.4).Exemple :import java.applet.Applet;import java.awt.*;public class AjoutComposants extends Applet { private Label l=new Label("Titre"); private TextField t1=new TextField("Entrez ici votre nom"); private Button b = new Button("appuyer ici"); private Checkbox c1= new Checkbox("oui"); private Checkbox c2= new Checkbox("non"); private CheckboxGroup grp= new CheckboxGroup(); private List liste = new List(3,false); private Scrollbar sb = new Scrollbar(Scrollbar.HORIZONTAL,30,500,0,1000); public void init(){ add(l); add(t1); add(b); c1.setState(true); c1.setCheckboxGroup(grp);Support de cours programmation Java - GBM2 - 91-
    • 13.3. ORGANISER L’INTERFACE add(c1); c2.setState(false); c2.setCheckboxGroup(grp); add(c2); liste.addItem("d’accord"); liste.addItem("pas d’accord"); liste.addItem("ne sais pas"); add(liste); add(sb); }}13.3 Organiser l’interface Nous savons comment ajouter des composants ` un conteneur, mais on aimerait bien apouvoir organiser nos composants de fa¸on un peu claire ! Pour cela, on dispose des cLayoutManagers ou gestionnaires de disposition. Il en existe cinq : – le FlowLayout est choisi par d´faut pour les Applet et Panel, et place les composants e comme indiqu´ pr´c´demment (de gauche ` droite et de haut en bas), e e e a la m´thode setLayout(new FlowLayout()) indique que le conteneur courant utilise e un FlowLayout gestionnaire, et la m´thode add(nom du composant) indique que l’on e rajoute le composant cit´, e – le BorderLayout est choisi par d´faut pour les Window, Dialog et Frame et dispose les e composants selon cinq attributs (North, South, West, East et Center). La m´thode e add() a deux param`tres : la position et le composant ` rajouter, e a – le GridLayout met chaque composant sur une case d’une grille dont on donne la dimension ` la cr´ation du gestionnaire. Cela se passe de la mˆme mani`re que pour a e e e un FlowLayout, mais les composants disposent d’un espace de mˆme taille, e – CardLayout permet de g´rer des panneaux comme des cartes, une seule ´tant visible e e a ` la fois (cf. le fameux jeu du solitaire), – GridBagLayout est le plus flexible et le plus compliqu´ des gestionnaires !... eDeux petits exemples :import java.applet.Applet;import java.awt.*;public class Disposition extends Applet { private Button b1 = new Button("bouton1"); private Button b2 = new Button("bouton2"); private Button b3 = new Button("bouton3"); private Button b4 = new Button("bouton4"); private Panel p = new Panel(); public void init(){ setLayout(new BorderLayout(2,2)); add("North",b1); add("West",b2); add("East",b3); add("South",b4); add("Center",p); } public void paint(Graphics g) { Graphics g2=p.getGraphics(); g2.setColor(Color.blue);Support de cours programmation Java - GBM2 - 92-
    • ´ ´ 13.4. GESTION D’EVENEMENTS g2.drawOval(10,10,30,30); }}==============================================import java.applet.Applet;import java.awt.*;public class Disposition2 extends Applet { private Button b1 = new Button("bouton1"); private Button b2 = new Button("bouton2"); private Button b3 = new Button("bouton3"); private Button b4 = new Button("bouton4"); public void init(){ setLayout(new BorderLayout(2,2)); add("North",b1); add("West",b2); add("East",b3); add("South",b4); }}13.4 Gestion d’´v´nements e e Il s’agit maintenant de pouvoir r´agir aux ´v´nements ext´rieurs (entr´e de texte, clic e e e e ede souris, ...). Les r´actions aux ´v´nements sont g´r´es par un ou plusieurs adaptateurs e e e ee(instances de classes h´ritant de l’interface eventListener du paquetage java.awt.event. eIl y a des adaptateurs diff´rents selon les types d’´v´nements pouvant survenir. Tout com- e e eposant graphique peut, en s’inscrivant aupr`s de l’adaptateur ad´quat, signifier qu’il r´agit e e ea` un certain type d’´v´nements. Il y a donc trois points dans la gestion d’´v´nements : e e e e – la d´claration d’une classe Reaction qui impl´mente une des onze interfaces du e e paquetage java.awt.event, par exemple : public class Reaction implements ActionListener ... – dans la classe Reaction, la d´finition de la ou des m´thode(s) de l’interface, par e e exemple ActionListener d´clare une seule m´thode) : public void actionPerfor- e e med(ActionEvent e) – l’inscription d’un composant aupr`s de l’adaptateur Reaction, par exemple (b est e un bouton, et X une instance de la classe Reaction) : b.addActionListener(X) ; On appelle classe adaptateur d’une interface, une classe qui impl´mente ses m´thodes, e eavec un corps vide (pour qu’elles n’accomplissent aucune action). Cela peut ˆtre tr`s utile e edans le cas o` une interface a plusieurs m´thodes (on doit toutes les d´finir) et qu’il n’y en u e ea qu’une que l’on veut d´finir. Nous y reviendrons dans les exemples. e Le tableau 13.2 qui suit donne les principales interfaces, avec le nom de l’interface, laclasse d’´v´nement, le type de composants g´n´rant ce type d’´v´nement, les m´thodes e e e e e e eet, ´ventuellement la classe adaptateur. Ce tableau n’est pas exhaustif, et ne recense que eles ´l´ments les plus courants. Reportez vous ` la documentation pour une information ee acompl`te. eSupport de cours programmation Java - GBM2 - 93-
    • ´ 13.5. ESSENTIEL DES METHODES DE JAVA.AWT.COMPONENT Interface Ev´nement e Composants M´thode(s) e Adaptateur ActionListener ActionEvent Button, Textfield actionPerformed – List ItemListener ItemEvent List, Choice itemStateChanged – Checkbox KeyListener KeyEvent Component keyPressed KeyAdapter keyReleased keyTyped MouseListener MouseEvent Component mouseClicked MouseAdapter mouseEntered mouseExited mousePressed mouseReleased MouseMotionListener MouseEvent Component mouseDragged MouseMotionAdapter mouseMoved WindowListener WindowEvent Window windowActivated WindowAdapter windowClosed windowClosing windowDeactivated windowDeiconified windowIconified windowOpenedTab. 13.2 – Interfaces de java.awt.event, ´v´nements, composants et classes adap- e etateurs associ´s, e13.5 Essentiel des m´thodes de java.awt.Component e Il n’est pas question de donner ici toutes les m´thodes de cette classe, elles sont trop enombreuses ! Mais vous en retrouverez certaines presque syst´matiquement, et tous les ecomposants que vous utilisez en h´ritent. En voici donc un catalogue r´duit, pour plus de e ed´tail, vous savez o` aller prospecter ! ! e u – addKeyListener(KeyListener) : inscrit le composant aupr`s d’un ´couteur de touches, e e – addMouseListener(MouseListener) : inscrit le composant aupr`s d’un ´couteur de e e souris, – addMouseMotionListener(MouseMotionListener) : inscrit le composant aupr`s d’un e ´couteur de d´placement de souris, e e – contains(int, int) : v´rifie si le composant contient le point dont les coordonn´es e e sont pass´es en param`tre, e e – getBackground() : donne la couleur (classe Color) de fond du composant, – getFont() : donne la police de caract`res du composant, e – getForeground() donne la couleur de premier plan, – getGraphics() : cr´e un objet de la classe Graphics pour ce composant e – getMaximumSize() : taille maximale – getMinimumSize() : taille minimale – getName() : nom – paint(Graphics) : dessine le composant, – paintAll(Graphics) :dessine le composant, et tous les sous-composants, – removeKeyListener(KeyListener) : retire l’inscription du composant, qui ne re¸oit c plus les ´v´nements de touches, e eSupport de cours programmation Java - GBM2 - 94-
    • ´ ´ 13.6. UN COMPOSANT DETAILLE : LE BOUTON – removeMouseListener(MouseListener) : idem pour les ´v´ments souris, e e – removeMouseMotionListener(MouseMotionListener) : idem pour les ´v´ments mou- e e vements de souris, – repaint() : redessine le composant, – setBackground(Color) : sp´cifie la couleur de fond, e – setFont(Font) : sp´cifie la police, e – setForeground(Color) : sp´cifie la couleur de premier plan, e – setVisible(boolean) : cache ou affiche le composant selon la valeur du bool´en e pass´ en param`tre, e e13.6 Un composant d´taill´ : le bouton e e Voici le d´tail de la classe Button et ce que vous pouvez en faire. D’abord, n’oubliez pas eque cette classe h´rite de java.awt.Component, et ` ce titre dispose des m´thodes d´finies e a e epour tous les composants. – public Button() : constructeur – public Button(String label) : constructeur d’un bouton avec un label, – public String getLabel() : le label du bouton (null si le bouton n’a pas de label), – public synchronized void setLabel(String label) : sp´cifie le label du bou- e ton, – public void setActionCommand(String command) : donne le nom de la commande a e ` ex´cuter pour l’´v´nement de type ActionEvent d´clench´ par le bouton, par d´faut e e e e e cette commende est le label du bouton, – public String getActionCommand() : retourne le nom de la commande associ´ee e a e e ` l’´v´nement de tupe ActionEvent d´clench´ par le bouton, e e – public synchronized void addActionListener(ActionListener l) : inscrit le bouton aupr`s d’un ´couteur de ActionEvent, e e – public synchronized void removeActionListener(ActionListener l) : supprime l’inscription du bouton.Support de cours programmation Java - GBM2 - 95-
    • Chapitre 14Programmation concurrente : lesthreads14.1 Introduction Nous avons l’habitude d’´crire des programmes s´quentiels : ` partir d’un point de e e ad´part(la m´thode main pour une application autonome), la machine ex´cute des instruc- e e etions, les unes apr`s les autres. Dans ce chapitre, les applications qui nous int´ressent e esont d’une autre nature, elles n’ont pas un unique fil d’ex´cution mais plusieurs, qui se ed´roulent en parall`le (ou du moins semblent le faire). On appelle thread un fil d’ex´cution, e e eon parle aussi de processus l´ger. Les processus l´gers sont internes ` une mˆme appli- e e a ecation et partagent donc le mˆme espace d’adressage, alors que les processus lourds (ou eprocessus) sont g´r´s par le syst`me d’exploitation qui leur alloue ` chacun un espace de ee e atravail. La programmation concurrente suppose des m´canismes de synchronisation et ed’exclusion mutuelle. Ces m´canismes sont pr´sents dans le langage Java qui permet e edonc de programmer facilement l’ex´cution concurrente de plusieurs threads. Ce n’est pas ele cas des langages classiques pour lesquels la programmation concurrente est une affairede sp´cialistes ! e Les threads se trouvent, ` tout instant, dans un ´tat particulier : a e – instanci´ (New Thread), e – actif (running) – endormi (not running), – mort (dead).14.2 Classe Thread et l’interface Runnable14.2.1 Code L’interface java.lang.Runnable doit ˆtre impl´ment´e par toute classe dont les ins- e e etances sont destin´es ` ˆtre ex´cut´es par un thread. La classe doit alors d´finir la m´thode e ae e e e epublic abstract void run(). Cette interface a ´t´ d´velopp´e pour fournir un protocole ee e ecommun pour les objets qui doivent ex´cuter du code pendant qu’ils sont actifs. C’est la em´thode run qui contient les instructions ` ex´cuter. e a e 96
    • 14.2. CLASSE THREAD ET L’INTERFACE RUNNABLE § ¤ running 9 6 yield E ¢ Not Runnable New Thread start E c Runnable ¦ ¥ fin de la m´thode run e c Dead Fig. 14.1 – Cycle de vie d’un Thread La cr´ation du filet d’ex´cution en parall`le consiste ` ex´cuter la m´thode run sur un e e e a e eobjet particulier.14.2.2 Cr´ation et ex´cution d’un thread sur un objet Runnable e e Une fois d´finies les instructions ` ex´cuter, il faut cr´er le filet d’ex´cution. Pour ce e a e e efaire il faut cr´er un objet de la classe java.lang.Thread. Nous verrons la description ede cette classe en d´tails un peu plus loin. Contentons nous pour l’instant de dire qu’elle edispose de plusieurs constructeurs, en particulier un constructeur prenant en argumentun objet d’une classe impl´mentant l’interface Runnable. Attention, l’instanciation d’un ethread n’implique pas le d´marrage de son ex´cution (de l’ex´cution des instructions qui e e elui sont associ´es) : il existe mais n’est pas actif (cf figures 14.1 et 14.4). eclass TesThread implements Runnable { ... public run(){ ... }}...TesThread test1 = new TesThread();Thread leThread = new Thread(test1);... Pour rendre le thread actif, il faut le faire explicitement en invoquant la m´thode estart() de la classe java.lang.Thread :leThread.start();La m´thode start() alloue les ressources n´cessaires ` l’ex´cution d’un thread et invoque e e a ela m´thode run() de l’objet pass´ en param`tre lors de l’instanciation du thread. Rendre e e eun thread actif ne signifie pas qu’il va s’ex´cuter en continu jusqu’` la fin. Il rejoint le e agroupe des threads actifs et le syst`me se charge d’allouer r´guli`rement une tranche de e e etemps pour qu’il puisse ex´cuter ses instructions. ePremier exemple :Support de cours programmation Java - GBM2 - 97-
    • 14.2. CLASSE THREAD ET L’INTERFACE RUNNABLEclass ThreadTest implements Runnable{ String s; public ThreadTest(String s){this.s=s;} public void run() { while (true) System.out.println(s); }}public class TicTac { public static void main(String arg[]){ ThreadTest tic=new ThreadTest("TIC"); ThreadTest tac=new ThreadTest("TAC"); Thread t1=new Thread(tic); Thread t2=new Thread(tac); t1.start(); t2.start(); }} On peut remarquer que, chaque fois que l’on instancie un objet ThreadTest, il fautcr´er un thread et le d´marrer. Ceci peut donc faire partie du constructeur de la classe e eThreadTest :class ThreadTest implements Runnable{ String s; Thread t; public ThreadTest(String s){ this.s=s; t=new Thread(this); t.start(); } public void run() { while (true) System.out.println(s); }}public class TicTac { public static void main(String arg[]){ ThreadTest tic=new ThreadTest("TIC"); ThreadTest tac=new ThreadTest("TAC"); }} Ce programme est suppos´ afficher alternativement les chaˆ e ınes TIC et TAC. Si vousl’ex´cutez, vous constaterez, selon le syst`me d’exploitation, que seule la chaˆ TIC est e e ıneaffich´e, ou bien que la chaˆ TAC n’est affich´e qu’au bout d’un certain temps. e ıne e Les diff´rentes JVM ne partagent pas toujours correctement le temps CPU allou´ ` e e achaque thread (cela d´pend de la plateforme). Il faut donc faire cette gestion “` la main” e aen c´dant le contrˆle r´guli`rement dans les threads avec les m´thodes sleep() ou yield(), e o e e epermettant ainsi aux autres threads de s’ex´cuter. e14.2.3 Suspendre et red´marrer un thread e Il existe diverses situations o` il est n´cessaire de suspendre l’ex´cution d’un thread. u e eLa remarque de la section pr´c´dente est un premier cas o` l’entrela¸age des diff´rents e e u c eSupport de cours programmation Java - GBM2 - 98-
    • 14.2. CLASSE THREAD ET L’INTERFACE RUNNABLEprocessus doit ˆtre sp´cifi´ “` la main”. Dans le cas d’applets qui d´finissent des animations e e e a egraphiques, celles-ci n’ont pas lieu d’ˆtre ex´cut´es si la page HTML qui contient l’applet e e en’est temporairement pas visible.Les m´thodes suspend et resume : La m´thode suspend() doit ˆtre utilis´e avec e e e epr´caution, car il faut s’assurer que l’application invoque la m´thode resume() ou la e em´thode stop() pour rendre le thread actif ou pour le tuer. Ces m´thodes sont depre- e ecated.La m´thode sleep : Une solution pour suspendre l’ex´cution d’un thread consiste ` e e al’endormir pendant un certain temps. Dans le cas d’une animation graphique, pour ´vitereun affichage trop rapide, on utilise la m´thode sleep(tps) pour suspendre l’ex´cution pen- e edants un laps de temps pass´ en param`tre et exprim´ en millisecondes. La m´thode sleep e e e elance l’exception InterruptedException si le thread est stopp´ pendant son sommeil. eL’invocation de cette m´thode doit donc g´rer cette exception. e e L’exemple tic-tac est modifi´ ci-dessous pour forcer chacun des threads ` s’endormir e ar´guli`rement de fa¸on que l’autre puisse s’ex´cuter : e e c eclass TestThread2 implements Runnable{ String s; Thread t; public TestThread2(String s){ this.s=s; t=new Thread(this); t.start(); } public void run() { while (true) { System.out.println(s); try { t.sleep(100);} catch(InterruptedException e){} } }}public class TicTac3 { public static void main(String arg[]){ TestThread2 tic=new TestThread2("TIC"); TestThread2 tac=new TestThread2("TAC"); }}14.2.4 Autre m´thode : h´riter de la classe Thread e e L’interface Runnable permet ` tout objet d’une classe qui l’impl´mente d’ˆtre la cible a e ed’un thread. Une autre fa¸on de faire est de d´finir une classe qui h´rite de la classe c e eThread. La classe java.lang.Thread impl´mente l’interface Runnable avec une m´thode e erun() vide. En red´finissant la m´thode run() dans la sous-classe, il est possible de d´finir e e eles actions que l’on veut faire ex´cuter au thread. eclass TestThread extends Thread{ String s; public TestThread(String s){Support de cours programmation Java - GBM2 - 99-
    • 14.3. GESTION DES THREADS : SYNCHRONISATION ET COMMUNICATION this.s=s; } public void run() { while (true) { System.out.println(s); try { sleep(100);} catch(InterruptedException e){} } }}public class TicTac4 { public static void main(String arg[]){ TestThread tic=new TestThread("TIC"); TestThread tac=new TestThread("TAC"); tic.start(); tac.start(); }} La m´thode start() de la classe Thread invoque imm´diatement, apr`s initialisation e e edu thread, la m´thode run(). e14.3 Gestion des threads : synchronisation et com- munication Nous l’avons dit, les threads partagent les donn´es entre eux. Il faut donc ˆtre tr`s e e evigilant dans l’utilisation de ces objets partag´s. C’est le programmeur qui doit g´rer la e esynchronisation des diff´rents threads. e14.3.1 Exclusion mutuelle : synchronized Java permet de verrouiller un objet (pas une variable de type primitif) pour empˆchereles acc`s concurrents. Lorsqu’une m´thode d’instance qualifi´e de synchronized est in- e e evoqu´e sur un objet par un thread, elle pose un verrou sur l’objet. Ainsi, si un autre thread einvoque une m´thode synchronized, elle devra attendre que le verrou soit relˆch´. Le e a everrou est relˆch´ si : a e – le code synchronis´ a fini de s’effectuer, e – la m´thode wait est invoqu´e, que nous verrons plus loin. e e L’exemple ci-dessous d´crit l’utilisation d’un mˆme m´gaphone par trois orateurs. e e eChaque orateur attendra la fin de l’utilisation du m´gaphone par le pr´c´dent. L’objet e e ede la classe Megaphone est v´rouill´ d`s qu’il est pris par un thread Orateur, mˆme si e e e ecelui-ci n’utilise pas le m´gaphone ` plein temps (voir l’instruction t.sleep(100)). e aclass Megaphone { // classe qui d´crit un m´gaphone e e synchronized void parler(String qui, String quoi, Thread t) { // m´thode synchronized car si un orateur utilise le m´gaphone e e // ce dernier n’est pas disponible pour un autre orateur for (int i=0; i<10; i++){Support de cours programmation Java - GBM2 - 100-
    • 14.3. GESTION DES THREADS : SYNCHRONISATION ET COMMUNICATION System.out.println(qui+" affirme : "+quoi +i+"`me fois "); e try{t.sleep(100);} catch(InterruptedException e){} } }}class Orateur extends Thread { // classe qui d´crit un orateur e String nom, discours; Megaphone m; public Orateur(String s, String d, Megaphone m){ nom=s; discours=d; this.m=m; } public void run(){ m.parler(nom,discours,this); }}class Reunion { public static void main(String[] arg){ Megaphone m=new Megaphone(); Orateur o1=new Orateur("Orateur 1","je suis le premier !",m); Orateur o2=new Orateur("Orateur 2","je suis le deuxi`me !",m); e Orateur o3=new Orateur("Orateur 3","je suis le troisi`me !",m); e o1.start();o2.start();o3.start(); }} Une m´thode d’instance synchronized pose un verrou sur l’objet par lequel elle a e´t´ invoqu´e. Une m´thode statique (de classe) peut ˆtre qualifi´e de synchronized.ee e e e eElle pose alors un verrou sur la classe et ainsi, deux m´thodes statiques synchronized ene peuvent ˆtre ex´cut´es en mˆme temps. Mais attention, il n’y a aucun lien entre les e e e everrous de classes et les verrous d’instances. Une classe verrouill´e (par une m´thode sta- e etique synchronized) n’empˆche pas l’ex´cution d’une m´thode d’instance synchronized e e eet inversement. Avec le mot cl´ synchronized on a vu comment verrouiller une instance sur toute une em´thode. En fait, il est possible de ne verrouiller qu’une partie du code d’une m´thode. e eL’instruction comporte alors deux parties : l’objet ` verrouiller et la ou les instructions ` a aex´cuter : esynchronized(objet) instruction-simple-ou-bloc-d’instructions L’exemple qui suit reprend le cas du m´gaphone, qui signale quand un orateur a de- emand´ ` l’utiliser : eaclass Megaphone { // classe qui d´crit un m´gaphone e e void parler(String qui, String quoi, Thread t) { System.out.println("m´gaphone demand´ par orateur "+qui); e e synchronized(this){Support de cours programmation Java - GBM2 - 101-
    • 14.3. GESTION DES THREADS : SYNCHRONISATION ET COMMUNICATION // c’est seulement pour parler que le m´gaphone est verrouill´ e e for (int i=1; i<=10; i++){ System.out.println(qui+" affirme : "+quoi); try{ t.sleep(100);} catch(InterruptedException e){ } } } }}class Orateur extends Thread { // classe qui d´crit un orateur e String nom, discours; Megaphone m; int sommeil; public Orateur(String s, String d, Megaphone m){ nom=s; discours=d; this.m=m; } public void run(){ m.parler(nom,discours,this); }}class Reunion { public static void main(String[] arg){ Megaphone m=new Megaphone(); Orateur o1=new Orateur("Orateur 1","je suis le premier ! ",m); Orateur o2=new Orateur("Orateur 2","je suis le deuxi`me ! ",m); e Orateur o3=new Orateur("Orateur 3","je suis le troisi`me ! ",m); e o1.start();o2.start();o3.start(); }}14.3.2 Synchronisation entre threads : wait, notify, notifyAll Il s’agit de faire coop´rer des threads. La m´thode wait suspend l’ex´cution d’un thread, e e een attendant qu’une certaine condition soit r´alis´e. La r´alisation de cette condition est e e esignal´e par un autre thread par les m´thodes notify ou notifyAll. Ces trois m´thodes, e e edont les prototypes sont donn´s ci-apr`s, sont d´finies dans la classe java.lang.Object et e e esont donc h´rit´es par toute classe. e epublic final void wait() throws InterruptedExceptionpublic final native void notify()public final native void notifyAll() Lorsque la m´thode wait est invoqu´e ` partir d’une m´thode synchronized, en mˆme e e a e etemps que l’ex´cution est suspendue, le verrou pos´ sur l’objet par lequel la m´thode a ´t´ e e e eeinvoqu´e est relˆch´. D`s que la condition de r´veil survient, le thread attend de pouvoir e a e e ereprendre le verrou et continuer l’ex´cution. Notez qu’une autre version de wait prend en eargument un entier de type long qui d´finit la dur´e d’attente maximale (en millisecondes). e eSi ce temps est d´pass´, le thread est r´veill´. e e e e La m´thode notify r´veille un seul thread. Si plusieurs threads sont en attente, c’est e ecelui qui a ´t´ suspendu le plus longtemps qui est r´veill´. Lorque plusieurs threads sont ee e eSupport de cours programmation Java - GBM2 - 102-
    • 14.3. GESTION DES THREADS : SYNCHRONISATION ET COMMUNICATIONen attente et qu’on veut tous les r´veiller, il faut utiliser la m´thode notifyAll. L’exemple e equi suit est une adaptation du pr´c´dent avec des orateurs qui interrompent leur discours e ede temps en temps et lib`rent le m´gaphone pour les orateurs en attente. Voil` une r´union e e a eplus conviviale ! !class Megaphone { synchronized void parler(String qui, String quoi, Thread t) { System.out.println("m´gaphone demand´ par orateur "+qui); e e for (int i=1; i<=10; i++){ System.out.println(qui+" affirme : "+quoi); notifyAll(); // lib`re le m´gaphone e e try{wait();} // se met en attente catch(InterruptedException e){ } } }} L’exemple qui suit est celui classique du producteur et du consommateur qui produisentet consomment dans un mˆme buffer : eimport java.util.*;class Buffer extends Stack { public synchronized void poser(char donnee) { // attendre tant que le buffer est plein while (full()) { try { wait(); // mise en attente } catch(Exception e) {} } // au moins une place libre push(new Character(donnee)); notify(); // fin de mise en attente } public synchronized char prendre(){ // attendre tant que le buffer est vide while (empty()){ try{ wait(); // mise en attente } catch(Exception e){} } notify(); return ((Character)pop()).charValue(); } public boolean full() {return (size()==2);} public boolean empty() {return (size()==0);}}class Producteur extends Thread { private Buffer buffer; private String donnee; public Producteur(Buffer buffer, String donnee) {Support de cours programmation Java - GBM2 - 103-
    • 14.3. GESTION DES THREADS : SYNCHRONISATION ET COMMUNICATION this.buffer=buffer; this.donnee=donnee; } public void run(){ for (int i=0;i<donnee.length();i++) { // produire les donnees buffer.poser(donnee.charAt(i)); try { // rythme de production aleatoire sleep((int) (Math.random()*25)); } catch(Exception e){} } System.out.println("nProduction terminee"); }}class Consommateur extends Thread { private Buffer buffer; private int nombre; public Consommateur(Buffer buffer, int nombre) { this.buffer=buffer; this.nombre=nombre; } public void run(){ for (int i=0;i<nombre;i++) { // consommer les donnees char car= buffer.prendre(); System.out.print(car); try { // rythme de consommation aleatoire sleep((int) (Math.random()*100)); } catch(Exception e){} } System.out.println("nConsommation terminee"); }}public class ProdCons { public static void main(String arg[]) { String donnee="Java est un langage merveilleux !"; Buffer buffer=new Buffer(); Producteur producteur = new Producteur(buffer,donnee); Consommateur consommateur=new Consommateur(buffer,donnee.length()); producteur.start(); consommateur.start(); }}/***** exemples d’execution *****gbm-server:~/coursJava/Thread> java ProdConsJaa est un langage merveilleuxProduction terminee!vConsommation termineeSupport de cours programmation Java - GBM2 - 104-
    • 14.3. GESTION DES THREADS : SYNCHRONISATION ET COMMUNICATIONgbm-server:~/coursJava/Thread> java ProdConsJva est un langage merveilleuxProduction terminee!aConsommation terminee14.3.3 Stopper un thread Lorsqu’une application Java d´marre, un premier thread s’ex´cute ; c’est le thread e eprincipal, qui d´marre l’ex´cution de la m´thode main dans le cas d’applications autonomes. e e eLorsque la m´thode main est termin´e, et si aucun autre thread n’a ´t´ cr´´, l’application e e e e ees’arrˆte. Mais si d’autres threads ont ´t´ cr´´s, l’application attend la fin de leur ex´cution e e e ee epour s’arrˆter(sauf pour les threads d´mons, dont nous ne parlerons pas ici). e e Un thread termine son ex´cution lorsque toutes les instructions de sa m´thode run ont e e´t´ ex´cut´es. Mais, souvent, cette m´thode est con¸ue pour tourner ind´finiment (c’estee e e e c ele cas par exemple dans les applications graphiques). Pour arrˆter des threads (actifs ou eendormis) : – utiliser une variable bool´enne (c’est la m´thode conseill´e) : e e e void run(){ while (! stopperThreads) {...} } – invoquer la m´thode stop de la classe Thread, cette m´thode public final void e e stop() force le thread ` arrˆter son ex´cution. Attention, cette m´thode est peu a e e e sˆre, elle a donc ´t´ supprim´e des nouvelles versions de Java (` partir de 1.2). Il est u ee e a permis de stopper un thread qui n’a pas encore d´marr´. La m´thode lance une erreur e e e ThreadDeath (d´riv´e de java.lang.Error), mais en g´n´ral on ne la rattrape pas. e e e e Notez qu’il est important d’arrˆter les threads en cours d’ex´cution, car ils consomment e edes ressources syst`me. e14.3.4 Un exemple de gestion de threads L’exemple ci-dessous est tir´ du support de cours de I.Charon (http ://www.infres.enst.fr/ echaron/coursJava/). Notez que les m´thodes suspend (suspension d’un thread permettant eune reprise au point d’arrˆt), resume (reprise d’un thread arrˆt´ par suspend) et stop sont e eedeprecated (c’est-`-dire qu’elles ne sont conserv´es que par soucis de compatibilit´, mais a e eelles ne font plus partie des nouvelles versions) depuis la version 1.2 du langage. La m´thode isAlive retourne true si le thread a ´t´ d´marr´ et n’est pas arrˆt´. Si e ee e e eeelle retourne false, le thread est soit un New Thread soit il est Dead.import java.awt.*;import java.awt.event.*;import java.util.*;class Ecouteur extends WindowAdapter { // pour les evenements window private Component fenetre; public Ecouteur(Component f) { fenetre = f; } public void windowClosing(WindowEvent e) {Support de cours programmation Java - GBM2 - 105-
    • 14.3. GESTION DES THREADS : SYNCHRONISATION ET COMMUNICATION if (e.getSource()==fenetre){ System.exit(0); } }}class RondsConcentriques extends Thread { int r=10; int debut; Component fenetre; boolean continuer; boolean finir; RondsConcentriques(int debut, Component fenetre) { this.debut = debut; this.fenetre = fenetre; } void suspendre() { continuer = false; } synchronized void reprendre() { continuer = true; notify(); } synchronized void stopper() { finir = true; notify(); } public void run() { Graphics g = fenetre.getGraphics(); continuer = true; finir = false; for (int i = 0; i < 50; i++) { try { sleep(200); synchronized(this) { while (!continuer && !finir) wait(); } } catch (InterruptedException exc) {} if (finir) break; g.setColor(new Color((debut+528424*i)%Integer.MAX_VALUE)); g.drawOval(250-r, 250-r,2*r,2*r); r += 2; } }}class EssaiGestionThread extends Panel implements ActionListener { RondsConcentriques thread = null; Random alea; Button tracer = new Button("tracer"); Button pauser = new Button("pauser"); Button stopper = new Button("stopper"); Button effacer = new Button("effacer");Support de cours programmation Java - GBM2 - 106-
    • ´ 14.4. GROUPER DES THREADS ET PRIORITES EssaiGestionThread() { tracer.addActionListener(this); pauser.addActionListener(this); stopper.addActionListener(this); effacer.addActionListener(this); add(tracer); add(pauser); add(stopper); add(effacer); alea = new Random((new Date()).getTime()); setVisible(true); } public void actionPerformed(ActionEvent evt) { Object source = evt.getSource(); if (source == tracer) { int debut= (int)Math.abs(alea.nextLong()); if ((thread == null)||(!thread.isAlive())) { thread = new RondsConcentriques(debut, this); thread.start(); } else thread.reprendre(); } else if ((source == pauser) && (thread != null)) thread.suspendre(); else if (source == stopper) { if (thread != null) thread.stopper(); thread = null; } else if (source == effacer) repaint(); } public static void main(String[] argv) { Frame f = new Frame(); f.addWindowListener(new Ecouteur(f)); f.setSize(500,500); f.add(new EssaiGestionThread()); f.setVisible(true); }}14.4 Grouper des threads et priorit´s e Chaque thread appartient ` un groupe. Par d´faut, les threads font partie du mˆme a e egroupe que le thread qui les ont cr´´s. La classe ThreadGroup permet d’organiser les threads eeen groupes. Lors de la cr´ation d’un thread, on peut sp´cifier ` quel groupe il appartient e e a(cf. constructeur de la classe Thread). A chaque thread est associ´e une priorit´ (entier compris entre les valeurs MIN PRIORITY e eet MAX PRIORITY de la classe Thread. Lorsque plusieurs threads sont d´marr´s, celui de e eplus forte priorit´ s’ex´cute d’abord. S’il existe deux threads de mˆme priorit´ en attente e e e ed’ex´cution, Java choisit l’un d’entre eux et l’ex´cute jusqu’` ce que : e e a – un thread de plus grande priorit´ est en attente, e – le thread en cours d’ex´cution se termine, eSupport de cours programmation Java - GBM2 - 107-
    • ´ 14.4. GROUPER DES THREADS ET PRIORITES $ˆ $ ˆˆ $$$ ˆˆˆ $ $ ˆˆ stop() $$$ $ z $$ Cr´´ ee Mort . & % 44 & E % 4 4 4 4 notifyAll() start() 4 r r notify() r 4  rr d´lai wait ´coul´ e e e stop() 4  4 $ # 4  r c  r T resume() En attente Ex´cutable e  & % d´lai sleep ´coul´ " $ . !   e e e X $  obj.d´verrouill´ $$ wait() e e$   $$ yield() T c $ $$$$  $  $  $ $$  Thread courant Bloqu´e $$ X $ & % $$$ & %  e suspend() sleep() e stop() e e fin de run() obj.verrouill´ e e e VIVANT Fig. 14.2 – Etats d’un Thread – le thread en cours d’ex´cution demande un partage du temps d’ex´cution (sleep ou e e encore yield()). Lorsque l’on cr´e un nouveau thread, il h´rite par d´faut de la priorit´ du thread qui e e e ele cr´e. Cette priorit´ peut ˆtre modifi´e en utilisant la m´thode setPriority. e e e e eSupport de cours programmation Java - GBM2 - 108-