Thinking in Java, 2nd edition, Revision 12
Table des matires
2000 by Bruce Eckel
Prface........................................................................3
Prface la 2me dition....................................................................3
Java 2.............................................................................................3
Le CD ROM..........................................................................................4
Introduction................................................................4
Prrequis.............................................................................................4
Apprendre Java...................................................................................5
Buts.....................................................................................................5
Documentation en ligne......................................................................6
Les chapitres.......................................................................................6
Penser
Exercices.............................................................................................8
Le CD ROM Multimdia........................................................................9
Le Code Source....................................................................................9
Typographie et style de code..............................................................9
Les versions de Java..........................................................................10
en
Seminars and mentoring...................................................................10
Errors................................................................................................10
propos de la conception de la couverture du livre..........................10
Remerciements.................................................................................11
Collaborateurs Internet....................................................................12
1) Introduction sur les Objets...................................13
Java Les bienfaits de l'abstraction.............................................................13
Un objet dispose d'une interface.......................................................14
L'implmentation cache...................................................................15
Rutilisation de l'implmentation......................................................16
Hritage : rutilisation de l'interface.................................................16
Seconde dition Les relations est-un vs. est-comme-un ..............................................18
Polymorphisme : des objets interchangeables...................................19
Classes de base abstraites et interfaces..............................................21
Environnement et dure de vie des objets.........................................21
Bruce Eckel Collections et itrateurs...................................................................22
La hirarchie de classes unique.........................................................23
President, MindView, Inc. Bibliothques de collections et support pour l'utilisation aise des
collections......................................................................................23
Transtypages descendants vs. patrons gnriques.......................................23
Traducteurs pour cette version franaise : Le dilemme du nettoyage : qui en est responsable ?............................24
Ramasse-miettes vs. efficacit et flexibilit.................................................24
Cdric BABAULT, Phillipe BOITE, Yannis CHICHA, Traitement des exceptions : grer les erreurs...................................25
Nate CULWELL-KANAREK, Jrome DANNOVILLE, Multithreading...................................................................................25
Florence DEFAIX, Armel FORTUN, Daniel LE BERRE, Persistance........................................................................................26
Anthony PRAUD, Jrome QUELIN, RACZY, Java et l'Internet...............................................................................26
Olivier THOMANN, Jean-Pierre VIDAL. Qu'est-ce que le Web ?....................................................................26
Le concept Client/Serveur.........................................................................26
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 1/459
Le Web en tant que serveur gant.............................................................27 Tableaux en Java............................................................................46
La programmation ct client............................................................27 Vous n'avez jamais besoin de dtruire un objet................................46
Les plugins (modules d'extension)..............................................................28 Notion de porte.............................................................................46
Les langages de script..............................................................................28 Porte des objets............................................................................47
Java.......................................................................................................28
Crer de nouveaux types de donnes : class.....................................47
ActiveX...................................................................................................29
La scurit..............................................................................................29 Champs et mthodes.......................................................................48
Internet vs. intranet.................................................................................30 Valeurs par dfaut des membres primitifs...................................................48
La programmation ct serveur.........................................................30 Mthodes, paramtres et valeurs de retour.......................................49
Une scne spare : les applications..................................................30 La liste de paramtres.....................................................................49
Analyse et conception.......................................................................31 Construction d'un programme Java...................................................50
Phase 0 : Faire un plan....................................................................32 Visibilit des noms..........................................................................50
L'expos de la mission..............................................................................32 Utilisation d'autres composantes.......................................................50
Phase 1 : Que construit-on ?.............................................................32 Le mot-clef static............................................................................51
Phase 2 : Comment allons-nous le construire ?....................................34 Votre premier programme Java.........................................................52
Les cinq tapes de la conception d'un objet.................................................35 Compilation et excution..................................................................52
Indications quant au dveloppement des objets...........................................36 Commentaires et documentation intgre.........................................53
Phase 3 : Construire le coeur du systme...........................................36 Commentaires de documentation......................................................53
Phase 4 : Itrer sur les cas d'utilisation..............................................36 Syntaxe.........................................................................................53
Phase 5 : Evolution.........................................................................37 HTML intgr..................................................................................54
Les plans sont payants.....................................................................37 @see : faire rfrence aux autres classes...........................................54
Programmation Extrme...................................................................38 Class documentation tags.................................................................54
Commencer par crire les tests.........................................................38 @version................................................................................................54
Programmation en binme...............................................................38 @author.................................................................................................55
Les raisons du succs de Java...........................................................39 @since...................................................................................................55
Les systmes sont plus faciles exprimer et comprendre......................39 Les onglets de documentation de variables.........................................55
Puissance maximale grce aux bibliothques.......................................39 Les onglets de documentation de mthodes........................................55
@param.................................................................................................55
Traitement des erreurs....................................................................39
@return..................................................................................................55
Mise en oeuvre de gros projets.........................................................39 @throws.................................................................................................55
Stratgies de transition.....................................................................40 @deprecated...........................................................................................55
Rgles de base...............................................................................40 Exemple de documentation...............................................................55
1. Cours.................................................................................................40 Style de programmation....................................................................56
2. Projet faible risque............................................................................40
Sommaire..........................................................................................56
3. S'inspirer de bonnes conceptions...........................................................40
4. Utiliser les bibliothques de classes existantes.........................................40 Exercices...........................................................................................56
5. Ne pas traduire du code existant en Java................................................41 3 : Contrle du Flux de Programme...........................57
Les obstacles au niveau du management............................................41 Utilisation des oprateurs Java.........................................................58
Cots de mise en oeuvre..........................................................................41 Priorit..........................................................................................58
Problmes de performances......................................................................41
L'affectation...................................................................................58
Erreurs classiques de conception...............................................................41
L'aliasing pendant l'appel des mthodes.....................................................59
Java vs. C++ ?...................................................................................42 Les oprateurs mathmatiques.........................................................59
Rsum.............................................................................................42 Les oprateurs unaires ( un oprande) moins et plus..................................60
2 : Tout est Objet.......................................................44 Incrmentation et dcrmentation automatique...................................60
Les objets sont manipuls avec des rfrences.................................44 Les oprateurs relationnels...............................................................61
Vous devez crer tous les objets.......................................................44 Tester l'quivalence des objets..................................................................61
O rside la mmoire ?....................................................................45 Les oprateurs logiques...................................................................62
Cas particulier : les types primitifs.....................................................45 Court-circuit .....................................................................................62
Nombres de grande prcision....................................................................46 Les oprateurs bit bit....................................................................63
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 2/459
Les oprateurs de dcalage..............................................................64 Initialisation des tableaux.................................................................98
Oprateur ternaire if-else.................................................................65 Tableaux multidimensionels............................................................100
L'oprateur virgule..........................................................................66 Rsum...........................................................................................101
L'oprateur + pour les String............................................................66 Exercices.........................................................................................101
Les piges classiques dans l'utilisation des oprateurs..........................66 5 : Cacher l'Implmentation....................................103
Les oprateurs de transtypage..........................................................67 package : l'unit de bibliothque.....................................................103
Les littraux............................................................................................67
Crer des noms de packages uniques...............................................104
La promotion...........................................................................................68
Collisions..............................................................................................106
Java n'a pas de sizeof .................................................................68
Une bibliothque d'outils personnalise............................................106
Retour sur la priorit des oprateurs..................................................68
Utilisation des imports pour modifier le comportement........................107
Rsum sur les oprateurs...............................................................68
Avertissement sur les packages.......................................................108
Le Contrle d'excution.....................................................................73
Les spcificateurs d'accs Java.......................................................108
true et false...................................................................................73
Friendly .................................................................................108
if-else............................................................................................73
public : accs d'interface................................................................108
return....................................................................................................74
Le package par dfaut............................................................................109
Itration........................................................................................74
private : ne pas toucher !...............................................................109
do-while........................................................................................74
protected : sorte d'amical ........................................................110
for................................................................................................75
Interface et implmentation............................................................111
L'oprateur virgule...................................................................................75
L'accs aux classes..........................................................................111
break et continue............................................................................75
L'infme goto ....................................................................................76 Rsum...........................................................................................113
switch...........................................................................................78 Exercices.........................................................................................113
Dtails de calcul :....................................................................................79 6 : Rutiliser les classes..........................................114
Rsum.............................................................................................80 Syntaxe de composition..................................................................115
Exercices...........................................................................................81 La syntaxe de l'hritage..................................................................116
4: Initialisation & Nettoyage.....................................81 Initialiser la classe de base.............................................................117
Garantie d'initialisation grce au constructeur..................................82 Constructeurs avec paramtres................................................................118
Attraper les exceptions du constructeur de base........................................118
Surcharge de mthodes.....................................................................83
Combiner composition et hritage...................................................119
Diffrencier les mthodes surcharges...............................................84
Garantir un nettoyage propre..........................................................119
Surcharge avec types de base...........................................................84
L'ordre du ramasse-miettes.....................................................................121
Surcharge sur la valeur de retour......................................................86
Cacher les noms............................................................................121
Constructeurs par dfaut..................................................................86
Choisir la composition la place de l'hritage.................................121
Le mot-cl this...............................................................................86
protected.........................................................................................122
Appeler un constructeur depuis un autre constructeur..................................87
La signification de static............................................................................88 Dveloppement incrmental............................................................122
Nettoyage : finalisation et ramasse-miettes......................................88 Transtypage ascendant...................................................................123
A quoi sert finalize( ) ?.....................................................................89 Pourquoi le transtypage ascendant ? ...............................................123
Composition la place de l'hritage revisit..............................................123
Le nettoyage est impratif................................................................89
Le mot cl final................................................................................124
La death condition.......................................................................91
Donnes finales.............................................................................124
Comment fonctionne un ramasse-miettes ?.........................................91
Finals sans initialisation...........................................................................125
Initialisation de membre...................................................................93 Arguments final.....................................................................................125
Spcifier une initialisation.................................................................94 Mthodes final..............................................................................126
Initialisation par constructeur...........................................................95 final et private.......................................................................................126
Ordre d'initialisation.................................................................................95 Classes final.................................................................................127
Initialisation de donnes statiques..............................................................95
Attention finale.............................................................................127
Initialisation statique explicite....................................................................97
Initialisation d'instance non statique...........................................................97 Initialisation et chargement de classes...........................................128
Initialisation avec hritage..............................................................128
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 3/459
Rsum...........................................................................................129 Les tableaux....................................................................................169
Exercices.........................................................................................129 Les tableaux sont des objets...........................................................169
7: Polymorphisme....................................................130 Conteneurs de scalaires..........................................................................171
Renvoyer un tableau......................................................................171
Upcasting........................................................................................130
La classe Arrays............................................................................172
Pourquoi utiliser l'upcast?...............................................................131
Remplir un tableau........................................................................177
The twist.........................................................................................132
Copier un tableau..........................................................................177
Liaison de l'appel de mthode.........................................................132
Comparer des tableaux..................................................................178
Produire le bon comportement........................................................132
Comparaison d'lments de tableau.................................................178
Extensibilit..................................................................................134
Trier un tableau............................................................................179
Redfinition et Surcharge................................................................135
Effectuer une recherche sur un tableau tri.......................................180
Classes et mthodes abstraites.......................................................136
Rsum sur les tableaux.................................................................181
Constructeurs et polymorphisme.....................................................138
Introduction sur les conteneurs.....................................................181
Ordre d'appel des constructeurs......................................................138
Imprimer les conteneurs................................................................182
La mthode finalize() et l'hritage...................................................139
Remplir les conteneurs...................................................................183
Comportement des mthodes polymorphes dans les
L'inconvnient des conteneurs : le type est inconnu........................186
constructeursname="Index722">....................................................141
Quelquefois a marche quand mme................................................187
Concevoir avec l'hritage................................................................142
Crer une ArrayList consciente du type.............................................187
Hritage pur contre extensionname="Index739">..............................142
Types paramtrs..................................................................................188
Downcasting et identification du type l'excution.............................143
Itrateurs........................................................................................188
Rsum...........................................................................................144 Rcursion indsirable..............................................................................189
Exercices.........................................................................................145 Classification des conteneurs..........................................................190
8 : Interfaces & Classes Internes............................146 Fonctionnalits des Collections........................................................192
Interfaces.......................................................................................146 Fonctionnalits des Lists.................................................................193
Hritage multiple en Java..........................................................147 Raliser une pile partir d'une LinkedList.........................................195
Combinaison d'interfaces et collisions de noms .........................................149 Raliser une file partir d'une LinkedList..........................................195
Etendre une interface avec l'hritage................................................149 Fonctionnalits des Sets..................................................................196
Groupes de constantes...................................................................150 Sets tris : les SortedSets..............................................................197
Initialisation des donnes membres des interfaces.............................150 Fonctionnalits des Maps................................................................197
Interfaces imbriques....................................................................151 Maps tries : les SortedMaps..........................................................199
Classes internes..............................................................................152 Hachage et codes de hachage.........................................................200
Classes internes et transtypage ascendant........................................153 Comprendre hashCode().........................................................................201
Classes internes dfinies dans des mthodes et autres portes............154 Facteurs de performance d'un HashMap....................................................203
Classes internes anonymes.............................................................155 Redfinir hashCode().....................................................................204
Lien vers la classe externe..............................................................157 Stocker des rfrences....................................................................205
Classes internes static....................................................................158 Le WeakHashMap..........................................................................206
Se rfrer l'objet de la classe externe............................................159 Les itrateurs revisits....................................................................207
Classe interne plusieurs niveaux d'imbrication.................................159 Choisir une implmentation.............................................................207
Driver une classe interne..............................................................159 Choisir entre les Lists.....................................................................208
Les classes internes peuvent-elles redfinies ?...................................160 Choisir entre les Sets.....................................................................209
Identifiants des classes internes......................................................161 Choisir entre les Maps....................................................................210
Raison d'tre des classes internes....................................................161 Trier et rechercher dans les Lists....................................................211
Fermetures & callbacks...........................................................................162 Utilitaires........................................................................................212
Classes internes & structures de contrle..........................................163 Rendre une Collection ou une Map non-modifiable..............................212
Rsum...........................................................................................167 Synchroniser une Collection ou une Map...........................................213
Exercices.........................................................................................167 Echec rapide..........................................................................................213
9 : Stockage des objets...........................................168 Oprations non supportes..............................................................214
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 4/459
Les conteneurs Java 1.0 / 1.1.........................................................215 Flux d'Entre................................................................................247
Vector & Enumeration....................................................................215 1. Entre en tampon du fichier [Buffered input file]....................................247
Hashtable.....................................................................................215 2. Entre depuis la mmoire....................................................................247
Stack...........................................................................................216 3. Entre de mmoire formate...............................................................247
4. Sortie de Fichier.................................................................................247
BitSet..........................................................................................216
Flux de sortie................................................................................248
Rsum...........................................................................................217
5. Stocker et rcuprer des donnes........................................................248
Exercices.........................................................................................217 6. Accs alatoire en lecture et criture aux fichiers...................................248
Gestion des erreurs avec les exceptions .................220 Un bogue ?...................................................................................248
Les exceptions de base ...................................................................220 Flux Piped....................................................................................249
Les paramtres des Exceptions .......................................................221 Standard E/S...................................................................................249
Attraper une exception ...................................................................221 Lire depuis une entre standard......................................................249
Le bloc try ...................................................................................221 Modifier System.out en un PrintWriter..............................................249
Les gestionnaires d'exceptions .......................................................221 Rorienter l'E/S standard................................................................250
Terminaison contre Restauration .............................................................222 Compression....................................................................................250
Crez vos propres Exceptions .........................................................222 Compression simple avec GZIP........................................................251
Spcifier des Exceptions .................................................................224 Stockage de fichiers multiples avec Zip.............................................251
Attraper n'importe quelle exception .................................................225 ARchives Java (JARs).....................................................................252
Relancer une exception .................................................................225 La srialisation objet.......................................................................253
Les exceptions Java standard .........................................................227 Trouver la classe...........................................................................255
Le cas particulier RuntimeException ................................................228 Contrler la srialisation.................................................................256
Faire le mnage avec finally ...........................................................228 Le mot-cl transient .........................................................................258
Quoi sert le finally ? ...................................................................229 Une alternative Externalizable...............................................................259
Le dfaut : l'exception perdue ........................................................230 Versioning.............................................................................................260
Restriction d'Exceptions .................................................................231 Utiliser la persistence.....................................................................260
Les constructeurs ...........................................................................232 Tokenizer l'entre...........................................................................264
Indication d'Exception ....................................................................234 StreamTokenizer...........................................................................264
Recommandations pour les exceptions ............................................235 StringTokenizer.............................................................................265
Rsum ..........................................................................................235 Vrifier le style de capitalization......................................................266
Exercices ........................................................................................235 Rsum...........................................................................................270
Exercices.........................................................................................271
11: Le systme d'E/S de Java..................................237
La classe File...................................................................................237 12: Identification dynamique de type......................272
Lister un rpertoire........................................................................237 Le besoin de RTTI............................................................................272
Les classes internes anonymes................................................................238 L'objet Class.................................................................................273
Vrification et cration de rpertoires...............................................239 Les littraux Class..................................................................................274
Entre et sortie...............................................................................240 Vrifier avant de transtyper............................................................274
Utiliser les littraux de classe...................................................................276
Les types d'InputStream................................................................240
Un instanceof dynamique........................................................................277
Les types d'OutputStream..............................................................241 instanceof vs. quivalence de classe.........................................................277
Ajouter des attributs et des interfaces utiles...................................242 La syntaxe du RTTI..........................................................................278
Lire depuis un InputStream avec FilterInputStream............................242 Rflexion : information de classe dynamique .................................279
crire vers un OutputStream avec FilterOutputStream........................243 Un extracteur de mthodes de classe...............................................280
Lecteurs & crivains [ Loaders & Writers ]......................................244 Rsum...........................................................................................282
Les sources et les rceptacles de donnes.........................................244 Exercices.........................................................................................283
Modifier le comportement du flux.....................................................244
Les classes inchanges...................................................................245 13: Cration de Fentres et Applets........................284
Et bien sr : L'accs alatoire aux fichiers (RandomAccessFile)......245 L'applet de base..............................................................................285
L'usage typique des flux d'E/S........................................................246 Les restrictions des applets.............................................................285
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 5/459
Les avantages d'une applet.............................................................285 Tables.........................................................................................323
Les squelettes d'applications...........................................................286 Slection de l'aspect de l'interface [Look & Feel]................................324
Excuter des applets dans un navigateur Web...................................286 Le presse-papier [clipboard]...........................................................325
Utilisation de Appletviewer..............................................................287 Empaquetage d'une applet dans un fichier JAR ..............................326
Tester les applets..........................................................................288 Techniques de programmation........................................................326
Excuter des applets depuis la ligne de commande.........................288 Lier des vnements dynamiquement...............................................326
Un squelette d'affichage.................................................................289 Sparation entre la logique applicative [business logic] et la logique de
Utilisation de l'Explorateur Windows.................................................290 l'interface utilisateur [UI logic] .......................................................327
Cration d'un bouton.......................................................................291 Une forme canonique.....................................................................329
Capture d'un vnement.................................................................291 Programmation visuelle et Beans....................................................329
Zones de texte.................................................................................293 Qu'est-ce qu'un Bean ?..................................................................330
Contrle de la disposition................................................................293 Extraction des informations sur les Beans [BeanInfo] l'aide de
BorderLayout................................................................................294 l'introspecteur [Introspector]..........................................................331
FlowLayout...................................................................................294 Un Bean plus complexe..................................................................333
GridLayout...................................................................................294 Empaquetage d'un Bean.................................................................335
GridBagLayout..............................................................................295 Un support des Beans plus sophistiqu.............................................336
Positionnement absolu...................................................................295 Davantage sur les Beans................................................................336
BoxLayout....................................................................................295 Rsum...........................................................................................337
La meilleure approche ?.................................................................297 Exercices.........................................................................................337
Le modle d'vnements de Swing..................................................297 14) Les Threads multiples.......................................339
Evnements et types de listeners.....................................................298 Interfaces utilisateurs dynamiques [Responsive user interfaces]. . .339
Utilisation de listener adapters pour simplifier............................................300
Hritage de Thread........................................................................340
Surveiller plusieurs vnements......................................................301
Threading pour une une interface ractive........................................341
Un catalogue de composants Swing.................................................302
Combiner le thread avec la classe principale......................................342
Boutons.......................................................................................302
Crer plusieurs threads..................................................................343
Groupes de boutons...............................................................................303
Threads dmons............................................................................345
Icones.........................................................................................304
Partager des ressources limites.....................................................346
Infobulles [Tooltips].......................................................................305
Des ressources accdes improprement............................................346
Champs de texte [Text Fields].........................................................305
Comment Java partage les ressources..............................................348
Bordures......................................................................................306
Synchroniser les compteurs.....................................................................348
JScrollPanes.................................................................................306 Efficacit de la synchronisation................................................................350
Un mini-diteur.............................................................................307 JavaBeans revisits.......................................................................351
Botes cocher [Check boxes].........................................................308 Blocage [Blocking]..........................................................................353
Boutons radio...............................................................................309 Passer l'tat bloqu.....................................................................353
Botes combo (listes ouverture vers le bas) [combo boxes (drop-down Dormant (Sleeping)................................................................................354
lists)]..........................................................................................309 Suspension et reprise.............................................................................355
Listes [List boxes].........................................................................310 Attendre et notifier.................................................................................355
Panneaux tabulations [Tabbed panes]............................................311 Bloqu sur I/O.......................................................................................357
Botes de messages.......................................................................311 Tester...................................................................................................357
Menus.........................................................................................312 Interblocage [Deadlock].................................................................358
Menus pop-up...............................................................................315 La dprciation de stop(), suspend(), resume(), et destroy() en Java 2........358
Dessiner......................................................................................316 Priorits..........................................................................................360
Botes de dialogue.........................................................................317 Lire et changer les priorits............................................................360
Dialogues pour les fichiers [File dialogs] ..........................................319 Les groupes de threads..................................................................362
Controller les groupes de threads.............................................................363
HTML sur des composants Swing ....................................................320
Runnable revisit............................................................................366
Curseurs [sliders] et barres de progression [progress bars].................321
Trop de threads............................................................................367
Arbres [Trees]..............................................................................321
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 6/459
Rsum...........................................................................................369 Utilisation de l'objet distant............................................................402
Exercices.........................................................................................370 Introduction CORBA.....................................................................403
15 : Informatique Distribue...................................370 Principes de base de CORBA............................................................403
CORBA Interface Definition Language (IDL - Langage de Dfinition d'Interface)...
La programmation rseau...............................................................371
403
Identifier une machine...................................................................371 Le service de nommage (naming service)..................................................404
Serveurs et clients.................................................................................372
Un exemple..................................................................................404
Tester les programmes hors rseau..........................................................372
crire le source IDL................................................................................404
Les Ports : un emplacement unique dans la machine.................................373
Cration des stubs et des skeletons..........................................................404
Les sockets..................................................................................373 Implmentation du serveur et du client.....................................................404
Un serveur et un client vraiment simples...................................................374 Quelques services CORBA.......................................................................405
Servir des clients multiples.............................................................376 Activation du processus du service de nommage........................................406
Les Datagrammes.........................................................................379 Activation du serveur et du client.............................................................406
Utiliser des URLs depuis un applet...................................................379 Les Applets Java et CORBA.............................................................406
Lire un fichier depuis un serveur..............................................................380 CORBA face RMI.........................................................................407
En savoir plus sur le travail en rseau..............................................380 Enterprise Java Beans.....................................................................407
Se connecter aux bases de donnes : Java Database Connectivity JavaBeans contre EJBs...................................................................408
(JDBC).............................................................................................380 Que dfinit la spcification des EJBs ?...............................................408
Faire fonctionner l'exemple.............................................................382 Les rles...............................................................................................408
tape 1 : Trouver le Driver JDBC.............................................................382 Composants EJB....................................................................................408
tape 2 : Configurer la base de donnes...................................................382 Conteneur d'EJB................................................................................408
tape 3 : Tester la configuration..............................................................383 Serveur EJB......................................................................................409
tape 4 : Gnrer votre requte SQL.......................................................383 Java Naming and Directory Interface (JNDI).........................................409
tape 5 : Modifier et insrer votre requte................................................384 Java Transaction API / Java Transaction Service (JTA/JTS).....................409
Une version GUI du programme de recherche....................................384 CORBA et RMI/IIOP...........................................................................409
Pourquoi l'API JDBC parat si complexe.............................................385 Qu'est-ce qui compose un composant EJB ?......................................409
Un exemple plus sophistiqu...........................................................385 Enterprise Bean.....................................................................................409
Les Servlets.....................................................................................389 Interface Home......................................................................................409
Interface Remote...................................................................................409
Le servlet de base.........................................................................389
Descripteur de Dploiement....................................................................409
Les Servlets et le multithreading.....................................................391 Fichier EJB-Jar.......................................................................................410
Grer des sessions avec les servlets.................................................392 Comment travaille un EJB ?............................................................410
La classe Cookie....................................................................................392
Types d'EJBs.................................................................................410
La classe Session...................................................................................392
Session Beans.......................................................................................410
Faire fonctionner les exemples de servlet..........................................394 Les Session Beans non-persistants......................................................410
Les Pages Java Serveur - Java Server Pages...................................394 Les Session Beans persistants.............................................................410
Les objets implicites......................................................................395 Entity Beans..........................................................................................410
Les directives JSP..........................................................................395 Gestion de la persistance par le conteneur (CMP - Container Managed
Les lments de scripting JSP.........................................................396 Persistence).....................................................................................410
Extraire des champs et des valeurs..................................................397 Gestion de la persistence par le Bean (BMP - Bean Managed Persistence).411
Attributs et visibilit d'une page JSP.................................................397 Dvelopper un Enterprise Java Bean................................................411
Manipuler les sessions en JSP..........................................................398 En rsum....................................................................................413
Crer et modifier des cookies..........................................................399 Jini : services distribus..................................................................413
Rsum sur les JSP........................................................................399 Contexte de Jini............................................................................413
RMI (Remote Method Invocation) : Invocation de mthodes distantes. Qu'est-ce que Jini ?.......................................................................414
400 Comment fonctionne Jini................................................................414
Interfaces Remote.........................................................................400 Le processus de dcouverte............................................................414
Implmenter l'interface distante......................................................400 Le processus de jonction................................................................415
Mise en place du registre........................................................................401 Le processus de recherche..............................................................415
Cration des stubs et des skeletons.................................................402 Sparation de l'interface et de l'implmentation.................................415
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 7/459
Abstraction des systmes distribus.................................................416 C : Conseils pour une programmation style en Java. . . .
Rsum...........................................................................................416
Exercices.........................................................................................416 444
Conception......................................................................................444
A : Passage & et Retour d'Objets.............................418 Implmentation...............................................................................446
Passage de rfrences.....................................................................418
Aliasing........................................................................................418 D : Ressources.........................................................449
Cration de copies locales...............................................................419 Logicielles.......................................................................................449
Passage par valeur........................................................................420 Livres..............................................................................................450
Clonage d'objets...........................................................................420 Analyse & conception.....................................................................450
Rendre une classe cloneable...........................................................421 Python.........................................................................................451
Utilisation d'une astuce avec protected.....................................................421 La liste de mes livres.....................................................................451
Implmenter l'interface Cloneable............................................................421
Pour un clonage russi...................................................................421
#TIJ_PAGE01#
Le mcanisme de Object.clone( ).....................................................423
Cloner un objet compos................................................................424
Copie profonde d'une ArrayList........................................................424 25.04.2001 - Version 0.2 :
Copie profonde via la srialisation....................................................425 - Mise en forme du code html (armel).
19.08.2000 - Version 0.1 :
Supporter le clonage plus bas dans la hirarchie................................426
- Dernire mise jour de la version franaise
Pourquoi cet trange design ?.........................................................427 Traducteur :
Contrler la clonabilit....................................................................427 - Jean-Pierre VIDAL
Le constructeur de copie................................................................429 Texte original :
Pourquoi cela fonctionne-t-il en C++ et pas en Java ?................................431 - Thinking in Java, 2nd edition, Revision 10
Classes en lecture seule..................................................................431 2000 by Bruce Eckel
Crer des classes en lecture seule....................................................432
L'inconvnient de l'immuabilit........................................................432
Chanes immuables........................................................................433
Constantes implicites..............................................................................434
Surcharge de l'oprateur + et les StringBuffer.....................................434
Prface
Les classes String et StringBuffer.....................................................435
Les Strings sont spciales...............................................................437 J'ai suggr mon frre Todd, qui est en train de migrer du
Rsum...........................................................................................437
Exercises.........................................................................................437 hardware vers le software, que la prochaine grande
B: L'Interface Native Java [Java Native Interface] rvolution serait l'ingnierie gntique.
(JNI).......................................................................438 Nous crerons bientt des organismes ddis la fabrication de nourriture, de
Appeler une mthode native............................................................439 carburant, de plastique ; ils digreront la pollution et, de manire gnrale, nous
Le gnrateur d'entte [ header file generator] : javah.......................439 permettront de matriser la manipulation du monde rel, ceci pour un cot minime
Les conventions de nommage [name mangling]et les signatures de
compar celui d'aujourd'hui. J'ai prtendu que la rvolution informatique serait
fonctions......................................................................................440
vraiment peu de chose au regard de cela.
Implmenter votre DLL..................................................................440
Accder des fonctions JNI : l'argument JNIEnv............................441 Puis j'ai ralis que j'tais en train de commettre une erreur triviale chez les auteurs
Accder des chanes Java.............................................................441 de science-fiction : oublier le propos de la technologie (ce qui est videmment trs
Passer et utiliser des objets Java....................................................441 facile faire en science-fiction). Un crivain expriment sait qu'on ne raconte
JNI et les exceptions Java...............................................................442 jamais une histoire propos de choses, mais de gens. La gntique aura un trs
JNI et le threading..........................................................................443 grand impact sur nos vies, mais je ne suis pas persuad qu'elle clipsera la
Utiliser une base de code prexistantes..........................................443 rvolution informatique (qui d'ailleurs rend possible la rvolution gntique) ou
Information complmentaire...........................................................443
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 8/459
au moins la rvolution de l'information. L'information, c'est essentiellement se rsoudre, superpose la complexit de la machine sur laquelle il va tre rsolu.
parler les uns les autres : bien entendu, les voitures, les chaussures, et surtout les Bien des projets de programmation ont avort cause de cette complexit. Je
maladies gntiques sont importantes, mais en dfinitive ce ne sont que des faux- voudrais maintenant dire que, de tous les langages de programmation que je
semblants. La vrai question est notre relation au monde. Ainsi en est-il de la connaisse, aucun n'a t conu pour grer la complexit du dveloppement et de la
communication. maintenance de programmes [1]. Bien entendu, dans la conception des langages,
beaucoup de dcisions ont t prises en gardant la complexit prsente l'esprit,
Ce livre est un cas. Une majorit d'amis pensa que j'tais soit vraiment hardi soit
mais, dans chaque exemple et partir d'un certain moment, d'autres problmes ont
lgrement drang pour mettre tout cela sur le Web. Pourquoi quelqu'un
surgi qui furent considrs comme essentiels et par suite intgrs la mixture.
voudrait-il l'acheter ? me disaient-ils. Si j'avais eu un temprament plus
Fatalement, ces nouveaux problmes furent de ceux qui envoyrent finalement les
conservateur, je ne m'y serais pas pris de cette manire ; en ralit je ne voulais pas
programmeurs droit dans le mur avec ce langage. Par exemple, C++ se devait de
crire un livre supplmentaire de style traditionnel sur les ordinateurs. Je ne savais
possder une compatibilit ascendante avec C (afin de favoriser la migration des
ce qui en aurait rsult si je n'avais pas agi ainsi, mais en tout cas ce fut la meilleure
programmeurs C), ainsi qu'une certaine efficacit. Ces deux buts taient trs utiles et
chose que j'ai jamais ralise avec un livre.
ont grandement particip au succs de C++, mais dans le mme temps ils ont gnr
Tout d'abord, chacun commena m'envoyer des correctifs. Ce fut un processus trs une complexit supplmentaire qui a eu pour rsultat d'empcher certains projets
amusant, parce que mes amis avaient furet dans chaque coin et recoin et repr les d'arriver terme (bien entendu, vous pouvez toujours vous en prendre la
erreurs techniques aussi bien que grammaticales, ce qui me permit d'liminer les responsabilit des programmeurs et/ou de leur encadrement, mais, si un langage
fautes de toutes sortes que j'aurais laiss passer sans cela. Dans ce travail, ils ont t pouvait vous aider reprer vos erreurs, pourquoi ne le ferait-il pas ?). Autre
tout simplement formidables, commenant trs souvent par me dire bon, je ne dis exemple, Visual Basic (VB) tait li BASIC, lequel n'tait pas vraiment conu
pas a pour critiquer... pour me mettre ensuite sous le nez un ensemble d'erreurs comme un langage extensible, et par suite toutes les extensions superposes VB se
que je n'aurais jamais t capable de trouver par moi-mme. Je crois que ce fut une sont traduites par une syntaxe vraiment horrible et impossible maintenir. Perl a
espce de travail de groupe, et cela a rellement ajout quelque chose de spcial ce une compatibilit ascendante avec Awk, Sed, Grep ainsi que d'autres outils Unix
livre. qu'il tait cens remplacer, le rsultat est qu'il est souvent accus de produire du
code--crire-seulement (c'est dire qu'on est incapable de se relire quelques
Mais ensuite, j'ai commenc entendre ceci : OK, trs bien, c'est bien gentil vous mois plus tard). D'un autre ct, C++, VB, Perl, et d'autres langages comme
avez fait une version lectronique, mais moi j'aurais prfr une version complte
Smalltalk, de par leur conception, ont abord le problme de la complexit, et par l
imprime chez un vrai diteur . Alors j'ai beaucoup travaill afin que chacun puisse se rvlent remarquablement efficaces dans la rsolution de certains types de
l'imprimer dans un format adquat, mais cela n'a pas suffi rsorber la demande problmes.
d'un livre publi . La plupart des gens n'ont pas envie de lire le livre l'cran
dans son intgralit, et l'ide de transporter un paquet de feuilles volantes, mme Ce qui m'a le plus frapp alors que je commenais comprendre Java est quelque
impeccablement imprimes, ne leur conviendrait pas davantage (de plus, je pense chose qui s'apparente l'incroyable finalit de diminuer la complexit pour le
que ce n'est pas forcment conomique en terme de toner). Aprs tout il semblerait programmeur. Un peu comme si l'on disait rien n'est important, mis part
que la rvolution informatique ne risque pas de mettre les diteurs au chmage. Un rduire le temps et la difficult pour produire un code robuste . Dans les premires
tudiant suggra toutefois que cela pourrait servir de modle pour l'dition du versions de Java, cette finalit s'est traduite par un code qui ne tournait pas trs vite
futur : les livres seraient d'abord publis sur le Web, et, condition qu'ils (bien que l'on ait fait de nombreuses promesses concernant la vitesse de Java) mais
rencontrent un certain intrt, on les coucherait sur papier. Actuellement, une il n'empche que cela a rduit le temps de dveloppement de manire stupfiante :
grande majorit de livres reprsentent des dsastres financiers, et cette nouvelle la moiti, ou moins, du temps ncessaire la cration d'un programme quivalent
approche pourrait peut-tre rendre l'industrie de l'dition plus rentable. en C++. Ce seul rsultat pourrait dj se traduire par une incroyable conomie de
temps et d'argent, mais Java ne s'arrte pas l. Il s'attache encapsuler toutes les
Ce livre a t par ailleurs une exprience enrichissante pour moi. Ma premire tches complexes qui ont pris de l'importance, comme le multithreading et la
approche de Java fut juste un nouveau langage de programmation , ce qu'il est de programmation rseau, au moyen de fonctionnalits du langage ou de bibliothques
fait par ailleurs. Mais, le temps passant, et au fur et mesure que je l'tudiais plus
rendant parfois ces tches triviales. Et pour finir, il traite quelques problmes d'une
en profondeur, je commenais m'apercevoir que son propos fondamental tait relle complexit : programmes multi-plate-forme, changements dynamiques de
diffrent de celui de tous les langages que j'avais connu auparavant. code, sans oublier la scurit, chacun d'entre eux pouvant s'adapter votre gamme
Programmer, c'est grer la complexit : complexit du problme que l'on veut de difficults, depuis un obstacle jusqu' un point bloquant . Ainsi, malgr les
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 9/459
problmes de performance que nous avons vus, les promesses de Java sont dition du livre, librement tlchargeable (http://www.BruceEckel.com). Si c'est
normes : il est capable de faire de nous des programmeurs encore plus productifs. l'ancienne version qui vous intresse, elle existe encore, et ceci est un merveilleux
soulagement pour un auteur. Par exemple, vous pouvez remarquer que le dernier
Le Web est l'un des lieux o cela se rvle le plus. La programmation rseau a
chapitre de l'dition originale, Projects , a disparu ; deux des projets ont intgr
toujours t difficile, et Java la rend facile (et les concepteurs du langage Java
d'autres chapitres, et le reste n'avait plus d'intrt. Pareillement, le chapitre
travaillent la rendre encore plus facile). La programmation rseau, c'est ce qui fait
Design Patterns , devenu trop gros, a fait l'objet d'un livre spar (galement
que nous parlons entre nous de manire plus pertinente et meilleur march que
tlchargeable sur le site Web). Ainsi, logiquement, le livre devrait tre plus mince.
nous ne l'avons jamais fait avec le tlphone (l'email lui seul a rvolutionn bien
des entreprises). Alors que nous nous parlons de plus en plus, des choses Mais, hlas, il n'en sera pas ainsi.
sensationnelles commencent merger, peut-tre plus incroyables que celles
Le plus gros problme est le continuel dveloppement du langage Java lui-mme, et
promises par l'ingnierie gntique.
en particulier l'extension de l'API qui nous promet de nous procurer une interface
Dans tous les cas en crant des programmes, en travaillant en groupe pour crer standard pour tout ce que nous pourrions imaginer (et je ne serais pas surpris de
des programmes, en concevant des interfaces utilisateur permettant aux voir paratre une API JCafetiere pour couronner le tout). Le propos de ce livre
programmes de dialoguer avec l'utilisateur, en faisant tourner des programmes sur n'est certainement pas de parler de ces API, d'autres auteurs se chargeront de cette
diffrents types de machine, en crivant facilement des programmes qui tche, mais certaines questions ne peuvent tre ignores. Parmi les plus
communiquent au travers de l'Internet Java accrot la bande passante de la importantes, Java ct serveur (principalement les Servlets et les Java Server
communication entre les gens. Je pense que le but de la rvolution de la Pages, ou JSP), qui reprsentent rellement une excellente solution au problme du
communication n'est certainement pas de transmettre de grandes quantits de bits ; World Wide Web, pour lequel nous avons dcouvert que les divers navigateurs Web
la vraie rvolution sera l lorsque nous serons tous capables de nous parler plus ne sont pas suffisamment consistants pour traiter la programmation ct client. En
facilement : de personne personne, mais aussi en groupe, et, pourquoi pas, sur la outre, un problme reste entier, celui de crer facilement des applications qui se
plante entire. J'ai entendu dire que la prochaine rvolution verra l'mergence connectent des bases de donnes, qui supervisent des transactions, qui grent la
d'une espce d'esprit global associant un grand nombre de personnes un grand scurit, etc., ce que traitent les Enterprise Java Beans (EJBs). Ces sujets se
nombre d'interconnexions. Il se peut que Java soit, ou pas, l'outil de cette retrouvent dans le chapitre anciennement nomm Programmation Rseau ,
rvolution, mais en tout cas cette possibilit m'a fait comprendre qu'il n'tait pas appel maintenant Informatique Distribue , un sujet qui est en passe de devenir
insens de tenter d'enseigner ce langage. essentiel. Ce chapitre a galement grossi afin d'inclure une vue d'ensemble de Jini
(prononcez djini , ce n'est pas un acronyme, mais un nom), qui est une
technologie de pointe permettant de concevoir diffremment les interconnexions
Prface la 2me dition entre applications. Et, bien entendu, le livre a volu pour utiliser tout au long des
exemples la bibliothque de composants graphiques Swing (GUI, Graphics User
Les lecteurs de la premire dition de ce livre ont fait normment de commentaires Interface, Interface Graphique Utilisateur, NdT). Ici aussi, si vous vous intressez
logieux son propos, ce qui m'a t trs agrable. Toutefois de temps autres l'un aux anciennes versions Java 1.0/1.1, vous les trouverez dans le livre que vous pouvez
ou l'autre s'est plaint, et l'une des critiques rcurrentes est le livre est trop gros . tlcharger gratuitement http://www.BruceEckel.com (et qui est galement inclus
Dans mon esprit, je dois dire que si trop de pages est votre seule plainte, c'est dans le CD ROM fourni avec cette nouvelle dition ; vous en saurez davantage ce
une faible critique (on se souvient de l'empereur d'Autriche se plaignant du travail sujet un peu plus tard).
de Mozart : trop de notes ! , mais n'allez pas penser que je cherche d'une manire Outre les quelques nouvelles fonctionnalits du langage Java 2 et les corrections
ou d'une autre me comparer Mozart). De plus, je peux seulement supposer effectues dans tout le livre, un autre changement majeur est le chapitre sur les
qu'une telle demande provient d'une personne qui en est encore prendre collections (chapitre 9), qui met maintenant l'accent sur les collections Java 2
conscience de l'tendue du langage Java lui-mme, et qui n'a pas encore vu ou lu les utilises tout au long du livre. J'ai galement amlior ce chapitre pour traiter plus
autres livres traitant du sujet par exemple, ma rfrence favorite, Core Java de en profondeur certaines facettes des collections, entre autres expliquer comment
Cay Horstmann & Gary Cornell (Prentice-Hall), qui a tellement grossi qu'on a d le fonctionne une fonction de hashing (afin que vous sachiez comment en crer une
scinder en deux volumes. Malgr cela, une des choses que j'ai essay de faire dans convenablement). Il y a eu d'autres changements, tels que la rcriture du Chapitre
cette dition a t d'liminer les parties obsoltes, ou tout au moins non essentielles. 1, la suppression de quelques appendices ainsi que d'autres parties qui ne me
Je n'ai pas eu de scrupules en faisant cela car l'original existe toujours sur le site paraissent plus indispensables pour le livre imprim, mais ce fut le plus gros des
Web ainsi que sur le CD ROM qui accompagne ce livre, sous la forme de la premire
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 10/459
suppressions. D'une manire gnrale, j'ai essay de tout revoir, d'enlever de cette 2e me souviens pas avoir jamais rencontr l'ensemble de ces fonctionnalits dans
dition tout ce qui n'tait plus indispensable (mais que l'on peut trouver sous la aucun outil auparavant). Et Java a trouv une trs importante niche dans la
forme lectronique de la premire dition), de traiter les modifications, et programmation ct serveur sous la forme des Servlets, une technologie qui est une
d'amliorer tout ce qui pouvait l'tre. Comme le langage continue d'voluer mais norme amlioration de la programmation CGI traditionnelle (ceci est dcrit dans le
toutefois pas la mme allure vertigineuse qu'auparavant il ne fait pas de doute chapitre Informatique Distribue ).
que de nouvelles ditions de ce livre verront le jour. Aussi, malgr le fait que j'aimerais n'utiliser que les toutes nouvelles fonctionnalits
Je dois m'excuser auprs de ceux qui persistent dans leur critique propos de la de Java, il est essentiel que l'ensemble puisse tre compil sous Linux, et donc que
taille du livre. Que vous me croyiez ou non, j'ai travaill dur pour le rendre plus lorsque vous installerez le code source et que vous le compilerez sous cet OS (avec le
mince. Malgr sa taille, je pense qu'il existe assez d'alternatives pour vous satisfaire. dernier JDK) vous puissiez constater que l'ensemble peut tre compil. Toutefois,
D'une part, le livre existe sous forme lectronique (sur le site Web, ainsi que sur le vous verrez que le texte est parsem et l de notes propos des fonctionnalits du
CD ROM accompagnant ce livre), ainsi lorsque vous prenez votre ordinateur JDK 1.3.
portable vous pouvez galement emporter le livre sans supplment de poids. Si vous
tes rellement partisan de la minceur, il existe des versions Palm Pilot (quelqu'un
m'a dit qu'il lirait le livre au lit sur l'cran rtro-clair de son Palm afin de ne pas Le CD ROM
dranger sa femme. Je ne peux qu'esprer que cela l'aidera glisser dans les bras de
Morphe). Si vous le prfrez sur papier, je connais des personnes qui impriment un Un autre bonus de cette dition est le CD ROM que vous trouverez la fin du livre.
chapitre la fois et l'emmnent dans leur attach-case afin de le lire dans le train. J'ai nagure rejet cette ide, pensant que mettre quelques Ko de code source sur cet
norme CD n'tait pas justifi, et prfr cela que les gens le tlchargent depuis
mon site Web. Cependant, vous allez voir tout de suite que ce CD ROM reprsente
Java 2 autre chose.
Alors que j'cris ceci, la sortie de la version 1.3 du Java Development Kit (JDK) de Le CD contient le code source que l'on trouve dans le livre, mais il contient aussi
Sun est imminente, et les modifications proposes pour le JDK 1.4 ont t publies. l'intgralit du livre, sous diffrents formats lectroniques. Mon prfr est le format
Bien que ces numros de version soient encore dans les uns , la manire standard HTML, parce qu'il est rapide et compltement index vous cliquez simplement
de se rfrer une version du JDK 1.2 ou suprieur est de l'appeler Java 2 . Ceci sur une entre de l'index ou de la table des matires et vous vous retrouvez
souligne les modifications significatives entre le vieux Java qui possde immdiatement l'endroit voulu dans le livre.
beaucoup de verrues, ce que je critiquais dans la premire version de ce livre et la Toutefois la plus grande partie des 300 Mo du CD consiste en un ensemble
nouvelle version du langage, amliore et plus moderne, comportant bien moins de multimdia complet nomm Thinking in C : Foundations for C++ & Java. A
verrues et beaucoup de complments, ainsi qu'une conception agrable. l'origine, j'avais dlgu Chuck Allison la cration de ce sminaire sur CD ROM
Ce livre est crit pour Java 2. J'ai la grande chance de dominer l'ancien langage et de en tant que produit part entire, puis j'ai dcid de l'inclure dans les secondes
n'crire que pour le nouveau langage amlior, parce que l'ancienne information ditions de Thinking in C++ et de Thinking in Java aprs avoir vcu, lors d'un
existe encore dans la 1re dition sur le Web et sur le CD ROM (ce qui reprsente sminaire, l'arrive de personnes dpourvues de connaissances suffisantes en
votre source d'information si vous utilisez une version antrieure Java 2). D'autre langage C. Leur propos tait apparemment je suis un bon programmeur et je n'ai
part, et parce que n'importe qui peut librement tlcharger le JDK depuis pas envie d'apprendre le C, mais plutt C++ ou Java, c'est pourquoi je compte
java.sun.com, cela signifie qu'en crivant sur Java 2 je n'oblige personne une passer rapidement sur C pour aller directement C++/Java . Peu aprs leur arrive
contrainte budgtaire leve en lui imposant une mise jour. au sminaire, ils prennent conscience que le prrequis de la connaissance de la
syntaxe du C se trouve l pour d'excellentes raisons. En incluant le CD ROM dans le
Il y a toutefois une nuance. JDK 1.3 possde quelques amliorations que j'aimerais livre, nous nous assurons que chaque participant un sminaire a une prparation
rellement utiliser, mais la version de Java actuellement fournie pour Linux est le suffisante.
JDK 1.2.2. Le systme Linux (voir http://www.Linux.org) est un dveloppement trs
important en conjonction avec Java, parce qu'il est en train de devenir rapidement Le CD permet galement d'largir l'audience du livre. Mme si le chapitre 3
la plus importante plate-forme serveur rapide, fiable, robuste, scurise, bien (Contrle du flux de programme) traite de parties fondamentales de Java provenant
maintenue, et gratuite, une vraie rvolution dans l'histoire de l'informatique (je ne du langage C, le CD est une introduction en douceur, et l'inverse du livre suppose
de la part de l'tudiant une moindre connaissance de la programmation. Le CD tant
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 11/459
inclus dans le livre, j'espre que davantage de personnes intgreront le cercle de la dduire la solution.
programmation Java.
Prrequis
[1]j'ai enlev ceci de la 2me dition : je pense que le langage Python est trs proche
Ce livre part du principe que le lecteur est un familier de la programmation : il sait
de faire exactement cela. Voir http://www.Python.org.
qu'un programme est un ensemble d'instructions, il sait ce que sont un sous-
#/TIJ_PAGE01# programme, une fonction, une macro-instruction, un ordre de contrle tel que if
ainsi qu'une structure de boucle telle que while , etc. Toutefois, il a certainement
#TIJ_PAGE01#
appris cela de diffrentes faons, par exemple en programmant avec un macro-
langage ou bien en utilisant un outil tel que Perl. Si vous faites partie de ceux qui
25.04.2001 - Version 0.2 : sont l'aise avec les ides de base de la programmation, vous lirez ce livre sans
- Mise en forme du code html (titres-hx[verdana], paragraphes-
p[Georgia], code-blockquote). problme. Bien entendu, le livre sera plus facile pour les programmeurs C et encore
19.08.2000 - Version 0.1 : plus pour les programmeurs C++, mais n'abandonnez pas pour autant si vous n'avez
- Dernire mise jour de la version franaise aucune exprience de ces langages (en revanche, prparez-vous travailler dur ; par
Traducteur : ailleurs, le CD multimdia fourni avec ce livre vous amnera rapidement
- Jean-Pierre VIDAL comprendre la syntaxe de base du langage C ncessaire l'apprentissage de Java).
Texte original :
- Thinking in Java, 2nd edition, Revision 10 Je vais introduire les concepts de la programmation oriente objet (POO) et les
2000 by Bruce Eckel mcanismes de contrle de base de Java, ainsi le lecteur en aura connaissance, et
rencontrera dans les premiers exercices les instructions de base du contrle de flux
de programme.
Introduction Bien qu'il soit souvent fait rfrence aux fonctionnalits des langages C et C++, il ne
s'agit pas d'un apart pour initis, mais au contraire d'aider tous les programmeurs
mettre Java en perspective avec ces deux langages, qui, aprs tout, sont ses
Tout comme n'importe quel langage humain, Java permet d'exprimer des concepts. parents. Je vais essayer de simplifier ces rfrences et d'expliquer un
S'il y parvient, il deviendra un moyen d'expression considrablement plus simple et programmeur ne connaissant ni C ni C++ tout ce que j'imagine tre peu familier
plus souple que n'importe quelle alternative, alors mme que les problmes pour lui.
augmentent en taille et en complexit.
Il est impossible de considrer Java uniquement sous l'angle d'une collection de Apprendre Java
fonctionnalits beaucoup de fonctionnalits perdent leur sens hors de leur
contexte. On ne peut utiliser la somme des parties que si l'on pense en termes de
J'ai commenc enseigner C++ l'poque o tait dit mon premier livre Using
conception, et non simplement en termes de code. Pour apprhender Java de cette
C++(Osborne McGraw-Hill, 1989). Enseigner la programmation est devenu ma
manire, il faut comprendre les problmes qui lui sont propres et ceux qui relvent
profession ; depuis 1989 j'ai vu bien des hochements de tte, de visages vides, ainsi
de la programmation en gnral. Ce livre traite de problmes de programmation, en
que beaucoup d'expressions d'incomprhension chez maint auditoire travers le
quoi ce sont des problmes, et quelle est l'approche de Java pour les rsoudre. Ainsi,
monde. Lorsque je me mis donner des cours chez moi, pour des groupes plus
l'ensemble de fonctionnalits que je prsente dans chaque chapitre est base sur ma
rduits, je dcouvris que mme ceux qui souriaient et hochaient la tte taient
manire de rsoudre un certain type de problmes au moyen de ce langage. Par cette
dconcerts face de nombreux problmes. J'ai dcouvert aussi, alors que je
dmarche j'espre peu peu amener le lecteur au point o penser Java lui
prsidais le cursus C++ durant plusieurs annes la Software Development
deviendra naturel.
Conference (et plus tard le cursus Java), que moi-mme ainsi que les autres
Je garderai constamment l'esprit qu'il faut que chacun se construise un modle de confrenciers avions tendance traiter trop de choses trop rapidement. Finalement,
pense permettant de dvelopper une profonde connaissance du langage ; lorsqu'il cause des diffrences entre les niveaux de mes auditeurs tout autant que de la
rencontrera un problme ardu il devra tre capable d'en alimenter ce modle et d'en manire dont je prsentais mon expos, j'aurais fini par perdre une partie de mon
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 12/459
auditoire. Je me suis pos beaucoup de questions, mais, faisant partie de ceux qui magistral, limite qu'il faut imprativement ne pas dpasser. A ce sujet je
rechignent au cours magistral (et chez beaucoup de gens, je crois qu'une telle devrais recevoir quelques critiques pour avoir utilis des exemples
attitude ne peut provenir que du souvenir de l'ennui que distillent de tels cours), j'ai jouets , et je les accepte volontiers, avec le prtexte que ce que je prsente
voulu faire en sorte que tout le monde reste veill. est utile, pdagogiquement parlant ;
une certaine priode, je terminais mes diffrents cours sous la pression des 3. enchaner soigneusement la prsentation des fonctionnalits afin que l'on ne
besoins. C'est ainsi que j'ai fini par enseigner par essais et erreurs (une technique qui rencontre jamais quoi que ce soit qui n'ait jamais t expos. Bien entendu,
marche bien galement dans la conception des programmes Java), et finalement j'ai ce n'est pas toujours possible, et, dans de telles situations, je donne une
ralis un cours qui utilise tout ce que j'ai appris grce mon exprience brve description en introduction ;
d'enseignant un cours qu'il me serait agrable de donner durant longtemps. Il
4. montrer ce que je pense tre important concernant la comprhension du
consiste s'attaquer au problme de l'apprentissage par touches discrtes et faciles
langage, plutt qu'exposer tout mon savoir. Je crois que l'information est
intgrer, et lors d'un sminaire impromptu (la situation idale pour
fortement hirarchise, qu'il est avr que 95 % des programmeurs n'ont pas
enseigner) chaque courte leon est suivie d'exercices. Je donne maintenant ce cours
besoin de tout connatre, et que cela droute tout le monde et ajoute leur
dans des sminaires Java publics, que l'on peut trouver sur le site
impression de complexit du langage. Pour prendre un exemple en C,
http://www.BruceEckel.com. (Le sminaire d'introduction est galement disponible
connaissant par coeur le tableau de priorit des oprateurs (ce qui n'est pas
sur le CD ROM, son contenu est disponible sur le mme site Web.)
mon cas), il est possible d'crire un code astucieux. Mais en y rflchissant
Le retour d'exprience que me procure chaque sminaire m'aide modifier et un instant, ceci risque de drouter le lecteur et/ou le mainteneur de ce code.
recentrer mon discours jusqu' ce qu'il devienne un bon moyen d'enseignement. Il est donc prfrable d'oublier la priorit des oprateurs, et d'utiliser des
Mais ce livre est plus qu'une simple compilation de notes de sminaires : j'ai tent parenthses lorsque les choses ne sont pas claires ;
d'y intgrer autant d'informations que je le pouvais, et je l'ai structur afin que
5. maintenir chaque section assez concentre de telle manire que le temps de
chaque sujet mne droit au suivant. Enfin, plus que tout, le livre est conu pour
lecture - et le temps entre les exercices - soit court. Non seulement cela
aider le lecteur solitaire qui se bat avec un nouveau langage de programmation.
maintient l'attention et l'implication des auditeurs lors d'un sminaire, mais
cela donne au lecteur une plus grande impression de travail bien fait ;
Buts 6. vous munir de bases solides afin que votre connaissance soit suffisante
avant de suivre un cours ou lire un livre plus difficiles.
Comme mon prcdent livre Thinking in C++, celui-ci a t structur pour enseigner
le langage. En particulier, ma motivation est de faire en sorte qu'il puisse me servir
pour enseigner le langage dans mes propres sminaires. Lorsque je pense un Documentation en ligne
chapitre du livre, je me demande s'il pourrait faire l'objet d'une bonne leon lors
d'un sminaire. Mon but est d'avoir des chapitres courts pouvant tre exposs en un Le langage Java et les bibliothques de Sun Microsystems (en tlchargement
temps raisonnable, suivis par des exercices ralisables dans une situation de salle de libre) sont accompagns d'une documentation sous forme lectronique, que l'on
classe. peut lire avec un navigateur Web, et en pratique chaque implmentation tierce de
Java possde un systme de documentation quivalent. La plupart des livres publis
Dans ce livre je me suis donn comme buts :
propos de Java dupliquent cette documentation. Soit vous l'avez dj, soit vous
1. prsenter le cours pas pas afin que le lecteur assimile chaque concept pouvez la tlcharger, et donc ce livre ne la reprendra pas, except lorsque c'est
avant d'aller plus avant ; ncessaire, parce qu'il sera gnralement plus rapide de trouver la description d'une
classe au moyen d'un navigateur plutt que dans le livre (de plus, la documentation
2. utiliser des exemples qui soient aussi simples et courts que possible. De
en ligne sera probablement davantage jour). Ce livre fournira certaines
temps en temps, cela me dtournera des problmes du monde rel , mais
descriptions de classes supplmentaires lorsqu'il sera ncessaire de complter la
j'ai remarqu que les dbutants sont gnralement plus satisfaits de
documentation afin de comprendre un exemple particulier.
comprendre chaque dtail d'un exemple qu'ils ne sont impressionns par la
porte du problme qu'ils cherchent rsoudre. Il y a galement une limite
la taille du code qui peut tre assimil dans une situation de cours
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 13/459
Les chapitres Ce chapitre commence avec tous les oprateurs provenant de C et C++. On y
dcouvre les piges classiques des oprateurs, le changement de type, la promotion
et la priorit. Suivent le classique contrle de flux de programme, les instructions de
Ce livre a t conu en gardant une seule chose l'esprit : la manire dont les gens rupture de squence dj connues pour avoir t rencontres dans d'autres langages
apprennent le langage Java. Le retour d'information des auditeurs de sminaires de programmation : le choix avec if-else, la boucle avec for et while ; comment sortir
m'a aid dcouvrir les parties difficiles qui justifient un autre clairage. Dans les d'une boucle avec break et continue aussi bien qu'avec les break tiquets et les
domaines o je fus ambitieux, o j'ai ajout trop de fonctionnalits dans un mme continue tiquets (qui reprsentent le goto manquant en java) ; la slection
temps, j'ai fini par comprendre - au travers du processus d'enseignement - que si avec switch. Bien que la majorit de ces fonctionnalits ressemblent au code C et
l'on ajoute de nouvelles fonctionnalits, on doit les expliquer compltement, et que C++, il existe certaines diffrences. De plus, tous les exemples sont crits en pur
cela peut drouter les tudiants. Je me suis donc donn beaucoup de mal pour Java, afin de mieux montrer quoi ressemble le langage.
introduire aussi peu que possible de nouveaux concepts en un mme temps. Chapitre 4 : Initialisation et Nettoyage Mmoire
Le but est donc d'enseigner une seule fonctionnalit par chapitre, ou la rigueur un Ce chapitre commence par dcrire le constructeur, lequel garantit une initialisation
petit ensemble de fonctionnalits associes, en vitant les liaisons avec des correcte. La dfinition du constructeur dbouche sur le concept de surcharge de
fonctionnalits supplmentaires. De cette manire, il est possible d'assimiler chaque fonction (dans la mesure o plusieurs constructeurs peuvent coexister). La suite est
chose dans le contexte de la connaissance actuelle avant d'aller plus loin. une discussion sur le processus de nettoyage mmoire, qui n'est pas toujours aussi
Voici une brve description des chapitres contenus dans le livre, qui correspondent simple qu'il semblerait. Normalement, il suffit simplement d'abandonner un objet
aux leons et exercices de mes sminaires. lorsqu'on n'en a plus besoin, et le ramasse-miettes finira par librer la mmoire.
Cette partie explore le ramasse-miettes ainsi que quelques-unes de ses
Chapitre 1 : Introduction sur les Objets particularits. Le chapitre se termine par une vision plus centre sur l'initialisation :
Ce chapitre est une vue d'ensemble de ce qu'est la programmation oriente objet, y initialisation automatique des membres, spcification de l'initialisation des
compris la rponse la question de base Qu'est-ce qu'un objet , ce que sont une membres, ordre d'initialisation, initialisation static et initialisation des tableaux.
interface et une implmentation, l'abstraction et l'encapsulation, les messages et les Chapitre 5 : Cacher l'Implmentation
fonctions, l'hritage et la composition, ainsi que le polymorphisme qui est d'une trs
haute importance. On y trouve galement une vue d'ensemble de la manire dont les Ce chapitre traite de la manire dont le code est mis en paquetages, et pourquoi
objets sont crs avec les constructeurs, o se trouvent les objets, o les ranger une certaines parties d'une bibliothque sont visibles alors que d'autres sont caches. Il
fois crs, ainsi que le magique ramasse-miettes (garbage collector) qui dtruit tous s'intresse tout d'abord aux mots clefs package et import, qui sont en relation
les objets devenus inutiles. D'autres questions seront abordes, comme le traitement avec la gestion des paquetages au niveau fichier et permettent de construire des
des erreurs par les exceptions, le multithreading pour des interfaces utilisateur bibliothques de classes. Il examine ensuite le problme sous l'angle des chemins de
ractives, la programmation rseau et l'Internet. On y apprendra ce qui rend Java dossier et des noms de fichiers. Le reste du chapitre traite des mots clefs public,
spcial, pourquoi il a tant de succs, ainsi que l'analyse et la conception orientes private et protected, du concept de l'accs amical (accs par dfaut, NdT), et
objet. de ce que signifient les diffrents niveaux de contrle d'accs utiliss dans divers
contextes.
Chapitre 2 : Tout est Objet
Chapitre 6 : Rutilisation des Classes
Avec ce chapitre on arrive au point o l'on peut crire un premier programme Java.
Il doit donc donner une vision d'ensemble des choses essentielles, entre autres : le Le concept d'hritage se retrouve dans pratiquement tous les langages de POO. Il
concept de rfrence un objet ; comment crer un objet ; une introduction aux s'agit de prendre une classe existante et d'tendre ses fonctionnalits (ou tout aussi
types primitifs et aux tableaux ; comment ils sont dtruits par le ramasse-miettes ; bien les modifier, c'est le sujet du chapitre 7). L'hritage consiste toujours
comment toute chose est en Java un nouveau type de donnes (class) et comment rutiliser du code en gardant la mme classe de base , et en modifiant
crer vos propres classes ; les fonctions, leurs arguments et leur valeur de retour ; la simplement certaines choses et l afin d'obtenir ce que l'on veut. Toutefois,
visibilit des noms et l'utilisation de composants provenant d'autres bibliothques ; l'hritage n'est pas la seule manire de crer de nouvelles classes partir de classes
le mot clef static ; les commentaires et la documentation intgre. existantes. Il est galement possible d'encapsuler un objet dans une nouvelle classe
au moyen de la composition. Ce chapitre explique ces deux mthodes de
Chapitre 3 : Contrler le Droulement du Programme rutilisation du code en Java, et comment les utiliser.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 14/459
Chapitre 7 : Le Polymorphisme pour s'occuper de tout problme survenant pendant l'excution. Ce chapitre
examine comment fonctionnent en Java les mots clefs try, catch, throw, throws,
Si vous appreniez par vous-mme, il vous faudrait neuf mois pour dcouvrir et
et finally ; quand lancer des exceptions ; et ce que l'on doit faire si on les intercepte.
comprendre le polymorphisme, l'une des pierres angulaires de la POO. Des
Il expose aussi les exceptions standard de Java, comment crer vos propres
exemples simples et courts montreront comment crer une famille de types au
exceptions, ce qu'il advient des exceptions dans les constructeurs, et comment sont
moyen de l'hritage et comment manipuler les objets dans cette famille par
localiss les codes de traitement d'exception.
l'intermdiaire de leur classe de base. Le polymorphisme de Java permet de traiter
de manire gnrique tout objet d'une famille, ce qui signifie que la plus grande Chapitre 11 : le Systme d'E/S de Java
partie du code n'est pas lie une information spcifique sur le type. Ceci rend les
En thorie, on peut diviser n'importe quel programme en trois parties : entre,
programmes extensibles, et donc leur dveloppement et leur maintenance plus
traitement, et sortie des donnes. Ceci suggre que les E/S (entres/
simples et moins onreux.
sorties) reprsentent une part importante de n'importe quel problme. Ce chapitre
Chapitre 8 : Interfaces & Classes Internes tudie les diffrentes classes fournies par Java pour lire et crire des fichiers, des
blocs mmoire, ainsi que la console. Il montre la distinction entre E/S vieux style
Java fournit une troisime voie pour la rutilisation du code, avec l'interface, qui est
et E/S nouveau style Java. Il examine galement le processus consistant
une pure abstraction de l'interface d'un objet. L'interface est bien plus qu'une
prendre un objet, le transformer en flux (de manire pouvoir le ranger sur disque
simple classe abstraite dont on aurait pouss l'abstraction l'extrme, puisqu'il vous
ou l'envoyer travers un rseau) puis le reconstruire, ce qui est pris en charge par la
permet de dvelopper une variation sur l' hritage multiple du C++, en crant
srialisation des objets de Java. Il prsente galement les bibliothques de
une classe qui peut tre transtype vers plus d'un type de base.
compression de Java, utilises dans le format de fichier Java ARchive (JAR).
Au premier abord, les classes internes ressemblent un simple mcanisme
Chapitre 12 : Identification Dynamique de Type
permettant de cacher le code : on place des classes l'intrieur d'autres classes.
Vous apprendrez toutefois que la classe interne fait plus que cela - elle connat la L'identification dynamique de type de Java (Run-Time Type Identification,
classe enveloppante et peut communiquer avec elle - et il est certain que le style de RTTI) permet de connatre le type exact d'un objet partir d'une rfrence sur le
code que l'on crit au moyen des classes internes est plus lgant et plus clair, bien type de base. Habituellement, on prfre ignorer intentionnellement le type exact
que cela reprsente pour la plupart d'entre vous une nouvelle fonctionnalit d'un objet et laisser au mcanisme de liaison dynamique de
ncessitant un certain temps d'apprentissage avant d'tre matrise. Java (polymorphisme) le soin d'implmenter la signification correcte pour ce type.
Mais de temps en temps il est trs utile de connatre le type rel d'un objet pour
Chapitre 9 : Stockage des Objets
lequel on n'a qu'une rfrence sur le type de base. Souvent cette information permet
Un programme qui manipule un nombre fixe d'objets dont la dure de vie est d'implmenter plus efficacement un traitement spcial. Ce chapitre explique quoi
connue ne peut tre que clair et trs simple. Mais gnralement, les programmes sert la RTTI, comment l'utiliser, et comment s'en dbarrasser lorsqu'on n'en a plus
crent de nouveaux objets diffrents moments, qui ne seront connus que lors de besoin. Enfin, il introduit le mcanisme de rflexion de Java.
l'excution. De plus, avant l'excution, on ne connat ni le nombre ni parfois le type
Chapitre 13 : Crer des Fentres et des Applets
exact des objets qui seront ncessaires. Afin de rsoudre ce problme gnral de la
programmation, nous devons pouvoir crer n'importe quel nombre d'objets, Java est livr avec la bibliothque GUI Swing , qui est un ensemble de classes
n'importe quel moment, n'importe o. Ce chapitre explore en profondeur la traitant du fentrage d'une manire portable (NdT : sur diffrentes plates-formes).
bibliothque fournie par Java 2 pour ranger les objets durant leur existence : les Ces programmes fentrs peuvent tre soit des applets soit des applications
tableaux simples et les conteneurs plus sophistiqus (structures de donnes) comme autonomes. Ce chapitre est une introduction Swing et la cration d'applets pour
ArrayList et HashMap. le World Wide Web. Il introduit aussi l'importante technologie des JavaBeans ,
fondamentale pour la cration d'outils de dveloppement de programmes destins
Chapitre 10 : Traitement des Erreurs au Moyen des Exceptions
au Dveloppement Rapide d'Applications (RAD, Rapid-Application Development).
Java a pour philosophie de base qu'un code mal crit ne sera jamais excut. Autant
Chapitre 14 : Les Threads Multiples
que possible, le compilateur repre les problmes, mais parfois les problmes - aussi
bien une erreur de programmation qu'une condition d'erreur naturelle survenant Java fournit un moyen de crer de multiples sous-tches concurrentes, appeles
lors de l'excution normale du programme - ne peuvent tre dtects et traits qu'au threads, s'excutant dans le contexte d'un mme programme (mis part le cas o la
moment de l'excution. Java possde un traitement des erreurs par les exceptions machine possde plus d'un processeur, ceci n'a que l'apparence de sous-tches
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 15/459
multiples). Bien qu'on puisse les utiliser n'importe o, l'utilisation des threads est
plus vidente lorsqu'il s'agit de crer une interface utilisateur ractive comme, par Exercices
exemple, lorsqu'un certain processus gourmand en ressources systme en cours
d'excution empche un utilisateur d'utiliser un bouton ou d'entrer des donnes. Ce Je me suis aperu que des exercices simples sont trs utiles pour consolider les
chapitre examine la syntaxe et la smantique du multithreading en Java. connaissances des tudiants lors d'un sminaire, on en trouvera donc un ensemble
Chapitre 15 : Informatique Distribue la fin de chaque chapitre.
Toutes les fonctionnalits et bibliothques de Java semblent vraiment faites les unes La plupart d'entre eux sont conus afin d'tre assez simples pour tre raliss dans
pour les autres lorsqu'on commence crire des programmes qui travaillent en un temps raisonnable dans le contexte d'une salle de classe, pendant que
rseau. Ce chapitre explore la communication au travers des rseaux et sur l'instructeur vrifie que tous les tudiants ont assimil le sujet de la leon. Quelques
l'Internet, ainsi que les classes fournies par Java pour faciliter cela. Il introduit les exercices sont plus pointus, afin d'viter l'ennui chez les tudiants expriments. La
concepts trs importants de Servlets et des JSPs (pour la programmation ct majorit est conue pour tre raliss rapidement, ainsi que pour tester et
serveur ), ainsi que la connectivit aux bases de donnes, Java DataBase perfectionner les connaissances. Quelques-uns prsentent des difficults, mais
Connectivity (JDBC), et l'invocation de mthodes distantes, Remote Method jamais de difficult majeure. (Je prsume que vous les dcouvrirez par vous-mme
Invocation (RMI). Et, pour finir, une introduction aux nouvelles technologies JINI, ou plutt qu'ils vous trouveront).
JavaSpaces, et Enterprise JavaBeans (EJB). Les solutions des exercices se trouvent dans le document lectronique The Thinking
Annexe A : Passage & Retour d'Objets in Java Annotated Solution Guide, disponible pour un faible cot sur
http://www.BruceEckel.com.
Etant donn qu'en Java seules les rfrences permettent d'apprhender les objets, le
concept de passer un objet une fonction et celui de retourner un objet depuis
une fonction ont quelques consquences intressantes. Cette annexe explique ce Le CD ROM Multimdia
qu'il faut savoir afin de grer les objets l'entre et la sortie d'une fonction, et
montre galement la classe String, qui utilise une approche diffrente du problme. Deux CD ROM multimdia sont associs ce livre. Le premier est fourni avec le livre
Annexe B : L'interface Java Natif (JNI) lui-mme : Thinking in C, dcrit la fin de la prface, et consiste en une prparation
ce livre qui dcrit la syntaxe C ncessaire la comprhension de Java.
Un programme Java entirement portable a de srieux inconvnients : la vitesse, et
l'incapacit d'accder des services spcifiques de la plate-forme. Connaissant la Il existe un deuxime CD ROM Multimdia, bas sur le contenu du livre. Ce CD
plate-forme sur laquelle sera excut le programme, il est possible d'acclrer ROM est un produit spar et contient la totalit du sminaire d'une semaine de
spectaculairement certaines oprations en les transformant en mthodes natives, formation Java Hands-On Java . J'y ai enregistr plus de 15 heures de
qui sont des fonctions crites dans un autre langage de confrence, synchronises avec des centaines de diapositives d'information. C'est un
programmation (actuellement, seuls C/C++ sont supports). Cette annexe procure accompagnement idal, dans la mesure o le sminaire est bas sur ce livre.
une courte introduction cette fonctionnalit, suffisante pour qu'on puisse crer des Le CD ROM contient toutes les confrences du sminaire de formation en
exemples simples utilisant cette interface avec un code autre que Java. immersion totale de cinq jours (il ne traite pas de l'attention porte aux cas
#/TIJ_PAGE01# #TIJ_PAGE02# particuliers !). Nous esprons que cela dfinira un nouveau standard de qualit.
Annexe C : Conseils pour une Programmation Style en Java Le CD ROM Hands-On Java est uniquement disponible en le commandant
directement sur le site http://www.BruceEckel.com.
Cet annexe est un ensemble de suggestions qui vous aideront dans la conception et
le codage de bas niveau de votre application.
Annexe D : Ressources
Le Code Source
Une liste des livres sur Java que m'ont paru particulirement utile. L'ensemble du code source de ce livre est disponible en freeware sous copyright, en
une seule archive, en visitant le site Web http://www.BruceEckel.com. Afin que
vous soyez certains d'obtenir la dernire version, cette adresse est celle du site
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 16/459
officiel pour la distribution du code et de la version lectronique du livre. Il existe possibility of such damages. Should the software
des versions miroir du livre lectronique et du code sur d'autres sites (dont certains prove defective, you assume the cost of all
necessary servicing, repair, or correction. If you
sont rfrencs sur le site http://www.BruceEckel.com), mais il est prfrable de think you've found an error, please submit the
rendre visite au site officiel afin de s'assurer que la version miroir est la plus rcente. correction using the form you will find at
Vous tes autoriss distribuer le code des fins d'enseignement ou d'ducation. www.BruceEckel.com. (Please use the same
form for non-code errors found in the book.)
Le but essentiel du copyright est d'assurer que la source du code soit correctement ///:~
cite, et d'viter que le code soit utilis sans autorisation dans un mdium
imprim. (Tant que la source est cite, l'utilisation d'exemples provenant du livre ne Vous tes autoriss utiliser le code pour vos projets ainsi qu' des fins
pose gnralement pas problme). d'ducation (ceci incluant vos cours) la condition de conserver le copyright inclus
Chaque code source contient une rfrence l'annonce suivante du copyright : dans chaque fichier source.
//:!:CopyRight.txt
Copyright 2000 Bruce Eckel Typographie et style de code
Source code file from the 2nd edition of the book
"Thinking in Java." All rights reserved EXCEPT as
allowed by the following statements: Dans ce livre, les identificateurs (de fonction, de variable, de nom de classe) sont
You can freely use this file crits en gras. La plupart des mots clefs sont galement en gras, l'exception de
for your own work (personal or commercial), ceux qui sont si souvent utiliss, tels que class , que cela en deviendrait
including modifications and distribution in
executable form only. Permission is granted to use
ennuyeux.
this file in classroom situations, including its J'utilise un style de code particulier pour les exemples de ce livre. Ce style suit les
use in presentation materials, as long as the book
"Thinking in Java" is cited as the source. rgles que Sun utilise lui-mme dans pratiquement tous les codes que l'on peut
Except in classroom situations, you cannot copy trouver sur son site (voir java.sun.com/docs/codeconv/index.html), et semble tre
and distribute this code; instead, the sole pris en compte par la plupart des environnements de dveloppement Java. Si vous
distribution point is http://www.BruceEckel.com avez lu mes autres livres, vous avez pu remarquer que le style de codage de Sun
(and official mirror sites) where it is concide avec le mien ce qui me fait videmment plaisir, bien que je n'y sois pour
freely available. You cannot remove this
copyright and notice. You cannot distribute rien. Le sujet du style de format demanderait des heures de dbat assez chaud, aussi
modified versions of the source code in this je vais simplement dire que je ne prtends pas imposer un style correct au travers de
package. You cannot use this file in printed mes exemples, j'ai seulement mes propres motivations pour faire ainsi. Puisque Java
media without the express permission of the est un langage de programmation indpendant de la forme, vous pouvez continuer
author. Bruce Eckel makes no representation about utiliser le style qui vous convient.
the suitability of this software for any purpose.
It is provided "as is" without express or implied Les programmes de ce livre sont des fichiers directement inclus, au moyen du
warranty of any kind, including any implied traitement de texte, depuis des fichiers ayant dj subi une compilation. Par suite, le
warranty of merchantability, fitness for a
particular purpose or non-infringement. The entire code imprim dans le livre ne doit pas provoquer d'erreurs de compilation. Les
risk as to the quality and performance of the erreurs qui pourraient entraner des messages d'erreur lors de la compilation sont
software is with you. Bruce Eckel and the mis en commentaires au moyen de //! de manire tre facilement repres et
publisher shall not be liable for any damages testes par des moyens automatiques. Les erreurs dcouvertes et rapportes
suffered by you or any third party as a result of l'auteur feront d'abord l'objet d'une modification du code source distribu, puis,
using or distributing software. In no event will
Bruce Eckel or the publisher be liable for any plus tard, d'une rvision du livre (qui sera galement disponible sur le site Web
lost revenue, profit, or data, or for direct, http://www.BruceEckel.com).
indirect, special, consequential, incidental, or
punitive damages, however caused and regardless of
the theory of liability, arising out of the use of
or inability to use software, even if Bruce Eckel
and the publisher have been advised of the
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 17/459
Les versions de Java livre de Bruce Eckel)
No matter how many tricks a writer uses to detect errors, some always creep in and
these often leap off the page for a fresh reader.
Je me rfre gnralement l'implmentation Sun de Java pour dterminer la There is an error submission form linked from the beginning of each chapter in the
dmarche correcte. HTML version of this book (and on the CD ROM bound into the back of this book,
Depuis le dbut, Sun a fourni trois versions majeures de Java : 1.0, 1.1 et 2 (laquelle and downloadable from http://www.BruceEckel.com) and also on the Web site
est appele version 2 mme si les versions du JDK de Sun continuent tre itself, on the page for this book. If you discover anything you believe to be an error,
numrotes 1.2, 1.3, 1.4, etc.). La version 2 semble dfinitivement mettre Java en please use this form to submit the error along with your suggested correction. If
lumire, en particulier lorsqu'il est question des outils d'interface utilisateur. Ce livre necessary, include the original source file and note any suggested modifications.
en parle et a t test avec Java 2, bien que je fasse de temps en temps des Your help is appreciated.
concessions aux fonctionnalits futures de Java 2 afin que le code soit compilable
sous Linux (avec le JDK Linux disponible alors que j'crivais ceci).
propos de la conception de la
Si vous dsirez apprendre les versions antrieures du langage non couvertes par
cette dition, la premire dition de ce livre est librement tlchargeable l'adresse couverture du livre
url : http://www.BruceEckel.com, vous la trouverez galement dans le CD livr
avec ce livre. La couverture de Thinking in Java est inspire par le Mouvement des Arts et
Attention : lorsqu'il m'a fallu mentionner les versions antrieures du langage, je Mtiers Amricain (American Arts & Crafts Movement), qui commena peu avant le
n'utilise pas les numros de sous-rvision. Dans ce livre je fais uniquement rfrence XXe sicle et atteignit son znith entre 1900 et 1920. Il vit le jour en Angleterre en
Java 1.0, Java 1.1, et Java 2, afin de me prmunir contre les erreurs typographiques raction la fois contre la production des machines de la Rvolution Industrielle et
qui pourraient rsulter de futures sous-rvisions de ces produits. contre le style hautement ornemental de l're Victorienne. Arts & Crafts mit l'accent
sur la sobrit, les formes de la nature telles que les voyait le mouvement art
Seminars and mentoring nouveau" (en franais dans le texte, NdT), le travail manuel, et l'importance des
travailleurs et artisans particuliers, et encore n'ont-ils pas ddaign l'utilisation des
outils modernes. Il y a beaucoup de ressemblances avec la situation actuelle : le
(non traduit, les personnes intresses par les sminaires de Bruce Eckel devant tournant du sicle, l'volution des dbuts inexpriments de la rvolution
priori matriser l'anglais) informatique vers quelque chose de plus raffin et significatif pour les individus, et
My company provides five-day, hands-on, public and in-house training seminars l'engouement pour la connaissance du mtier de programmeur face la fabrication
based on the material in this book. Selected material from each chapter represents a industrielle de code.
lesson, which is followed by a monitored exercise period so each student receives Je considre Java de la mme manire : une tentative pour lever le programmeur
personal attention. The audio lectures and slides for the introductory seminar are au-dessus de la mcanique du systme d'exploitation afin de l'amener devenir un
also captured on CD ROM to provide at least some of the experience of the seminar artisan du logiciel .
without the travel and expense. For more information, go to
http://www.BruceEckel.com. L'auteur, tout autant que le concepteur du livre et de sa couverture (qui sont amis
depuis l'enfance) ont trouv leur inspiration dans ce mouvement, et tous deux
My company also provides consulting, mentoring and walkthrough services to help possdent des meubles, lampes etc. soit originaux, soit inspirs par cette priode.
guide your project through its development cycle especially your company's first
Java project. L'autre thme de cette couverture suggre une bote servant la prsentation des
spcimens d'insectes recueillis par un naturaliste. Ces insectes sont des objets, qui
sont placs dans des botes-objets. Les botes-objets sont elles-mmes places dans
Errors la couverture-objet , ce qui illustre le concept fondamental d'agrgation en
programmation oriente objet. Bien entendu, ceci n'est d'aucune utilit pour un
(non traduit car cela concerne les erreurs releves dans la version anglaise du programmeur, mais cre une association avec les punaises ( bugs ), ici les
punaises ont t captures, probablement tues dans un bocal spcimen, et pour
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 18/459
finir confines dans une petite bote pour tre exposes, comme pour montrer la Je remercie spcialement Larry et Tina O'Brien, qui m'ont aid mettre mon
capacit de Java trouver, montrer, et soumettre les bugs (ce qui est vraiment l'un sminaire sur le CD ROM original Hands-On Java (vous en saurez davantage sur
de ses attributs les plus puissants). http://www.BruceEckel.com).
Beaucoup de gens m'ont envoy des correctifs et je reste en dette avec eux, mais je
Remerciements dois remercier particulirement (pour la premire dition) : Kevin Raulerson (qui
repra des tonnes d'normes bugs), Bob Resendes (tout simplement incroyable),
John Pinto, Joe Dante, Joe Sharp (les trois, fabuleux), David Combs (beaucoup de
En premier, merci tous les associs qui travaillrent avec moi pour encadrer des corrections grammaticales et d'claircissements), Dr. Robert Stephenson, John
sminaires, faire du consulting, et dvelopper des projets ducatifs : Andrea Cook, Franklin Chen, Zev Griner, David Karr, Leander A. Stroschein, Steve Clark,
Provaglio, Dave Bartlett (qui a par ailleurs fortement contribu au Chapitre 15), Bill Charles A. Lee, Austin Maher, Dennis P. Roth, Roque Oliveira, Douglas Dunn, Dejan
Venners, et Larry O'Brien. J'ai apprci leur patience alors que je continuais de Ristic, Neil Galarneau, David B. Malkovsky, Steve Wilkinson, ainsi qu'une foule
dvelopper le meilleur modle permettant des personnes indpendantes comme d'autres. Prof. Ir. Marc Meurrens dploya beaucoup d'efforts de publication et
nous de travailler ensemble. Merci Rolf Andr Klaedtke (Suisse) ; Martin Vlcek, ralisa la version lectronique de la premire dition du livre disponible en Europe.
Martin Byer, Vlada & Pavel Lahoda, Martin the Bear, et Hanka (Prague) ; ainsi que
Marco Cantu (Italie) pour leur hbergement lors de ma premire tourne de J'ai rencontr dans ma vie une avalanche de personnes trs techniques et trs
confrences improvise en Europe. intelligentes qui sont devenues des amis mais qui taient galement peu communes
et qui m'ont influenc en ce qu'elles pratiquaient le yoga ainsi que d'autres formes
Merci aussi la Doyle Street Cohousing Community pour m'avoir support de spiritualit, ce qui m'a instruit et inspir. Ce sont Kraig Brockschmidt, Gen
durant les deux annes ncessaires la rdaction de cette premire dition (ainsi Kiyooka, et Andrea Provaglio (qui aida la comprhension de Java et de la
que pour m'avoir support dans l'absolu). Bien des remerciements Kevin et Sonda programmation en gnral en Italie, et qui est maintenant aux Etats-Unis associ
Donovan pour m'avoir accueilli dans leur magnifique Crested Butte, Colorado, l't l'quipe MindView).
o je travaillais la premire dition du livre. Merci aussi tous les amis rsidents
de Crested Butte et au Rocky Mountain Biological Laboratory qui m'ont si Ce ne fut pas une grande surprise pour moi de dcouvrir que ma connaissance de
bien accueilli. Delphi m'a aid comprendre Java, car ces deux langages ont beaucoup de concepts
et de dcisions de conception de langage en commun. Des amis fanatiques de Delphi
Merci galement Claudette Moore de Moore Literary Agency pour son norme m'ont aid devenir plus perspicace propos de ce merveilleux environnement de
patience et sa constance m'obtenir exactement ce je dsirais. programmation. Ce sont Marco Cantu (un autre italien il se pourrait qu'tre
Mes deux premiers livres ont t publis sous la houlette de l'diteur Jeff Pepper aux imprgn de culture latine donne certaines aptitudes pour la programmation ?),
ditions Osborne/McGraw-Hill. Jeff est arriv au bon endroit au bon moment Neil Rubenking (qui se nourrissait de culture yoga/vgtarienne/Zen avant de
Prentice-Hall, il a dbroussaill le chemin et fait tout ce qu'il fallait pour rendre dcouvrir les ordinateurs), et bien entendu Zack Urlocker, un vieux copain avec qui
cette exprience de publication trs agrable. Merci, Jeff cela a compt pour moi. j'ai parcouru le monde.
J'ai une dette spciale envers Gen Kiyooka et sa compagnie Digigami, qui m'ont La perspicacit et l'aide de mon ami Richard Hale Shaw m'ont t fort utiles (celles
gracieusement fourni un serveur Web les premires annes. Cela a reprsent pour de Kim galement). Richard et moi avons pass de concert beaucoup de mois
moi une aide inestimable. donner des sminaires et tenter de trouver l'enseignement parfait pour les
auditeurs. Merci galement KoAnn Vikoren, Eric Faurot, Marco Pardi, ainsi qu'
Merci Cay Horstmann (co-auteur de Core Java, Prentice-Hall, 2000), D'Arcy toute l'quipe du MFI. Merci particulirement Tara Arrowood, qui me rendit
Smith (Symantec), et Paul Tyma (co-auteur de Java Primer Plus, The Waite Group, confiance propos des possibilits de confrences.
1996), pour m'avoir aid clarifier les concepts du langage.
La conception du livre, de la couverture, ainsi que la photo de couverture sont ds
Merci aux personnes qui ont pris la parole dans mon cursus Java la Software mon ami Will-Harris, auteur et concepteur connu (http://www.Will-Harris.com),
Development Conference, aux tudiants de mes sminaires, pour m'avoir pos les qui jouait au collge avec des lettres transfert en attendant l'invention de la
bonnes questions qui m'ont permis de clarifier mes cours. publication assiste par ordinateur, tout en se plaignant de mes grognements
propos de mes problmes d'algbre. Toutefois, j'ai produit moi-mme mes pages
prtes imprimer, et donc j'assume mes erreurs de frappe. Microsoft Word 97 for
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 19/459
Windows a t utilis pour crire le livre et Adobe Acrobat pour crer les pages - Ajout des tags de sparation de pages pour le site (Armel).
offset ; le livre est sorti directement des fichiers PDF d'Acrobat (pour rendre 28.04.2001 - version 5.7 :
- Remise en forme du code html [Armel avec HTML-Kit],
hommage l're lectronique, je me trouvais outre-mer les deux fois o la version balises font, a...
finale du livre fut produite la premire dition fut envoye depuis Le Cap en 04.08.2000 - version 5.6 :
Afrique du Sud et la seconde depuis Prague). Les polices de caractres sont Georgia - Corrections apportes par Daniel Le Berre
pour le corps du texte et Verdana pour les titres. La police de couverture est ITC 26.06.2000 - version 5.5 :
Rennie Mackintosh. - Insertion du journal de log.
18.06.2000 - version 5.4 :
Merci aux groupes qui ont cr les compilateurs : Borland, le Blackdown group - Modification des tags {url: http://www.blahblah.com} en
(pour Linux), et bien entendu, Sun. www.blahblah.com.
- "langage de scripting" modifi en "langage de script".
Je remercie particulirement tous mes matres et tous mes tudiants (qui furent en - Modification des guillemets "" en .
mme temps mes matres). Le plus plaisant de mes matres en criture fut Gabrielle 06.06.2000 - version 5.3 :
- Corrections apportes par Philippe Bote.
Rico (auteur de Writing the Natural Way, Putnam, 1983). Je garderai 05.06.2000 - version 5.2 :
prcieusement le souvenir d'une formidable semaine Esalen. - Corrections apportes par Jean-Pierre Vidal.
02.06.2000 - version 5.1 :
Liste non exhaustive de mes collaborateurs : Andrew Binstock, Steve Sinofsky, JD - Premire publication sur eGroups.
Hildebrandt, Tom Keffer, Brian McElhinney, Brinkley Barr, Bill Gates au Midnight Traducteur :
Engineering Magazine, Larry Constantine et Lucy Lockwood, Greg Perry, Dan - Jrome QUELIN
Putterman, Christi Westphal, Gene Wang, Dave Mayer, David Intersimone, Andrea Texte original :
Rosenfield, Claire Sawyers, d'autres italiens (Laura Fallai, Corrado, Ilsa, et Cristina - Thinking in Java, 2nd edition, Revision 10
2000 by Bruce ECKEL
Giustozzi), Chris et Laura Strand, les Almquists, Brad Jerbic, Marilyn Cvitanic, les
Mabrys, les Haflingers, les Pollocks, Peter Vinci, la famille Robbins, la famille
Moelter (ainsi que les McMillans), Michael Wilk, Dave Stoner, Laurie Adams, les
Cranstons, Larry Fogg, Mike et Karen Sequeira, Gary Entsminger et Allison Brody, 1) Introduction sur les Objets
Kevin Donovan et Sonda Eastlack, Chester et Shannon Andersen, Joe Lordi, Dave et
Brenda Bartlett, David Lee, les Rentschlers, les Sudeks, Dick, Patty, et Lee Eckel, La rvolution informatique a pris naissance dans une
Lynn et Todd, et leurs familles. Et, bien entendu, Papa et Maman.
machine. Nos langages de programmation ont donc
Collaborateurs Internet tendance ressembler cette machine.
Mais les ordinateurs ne sont pas tant des machines que des outils au service de
Merci tous ceux qui m'ont aid rcrire les exemples au moyen de la bibliothque l'esprit ( des vlos pour le cerveau , comme aime le rpter Steve Jobs) et un
Swing, ou pour d'autres choses : Jon Shvarts, Thomas Kirsch, Rahim Adatia, Rajesh nouveau moyen d'expression. Ainsi, ces outils commencent moins ressembler
Jain, Ravi Manthena, Banu Rajamani, Jens Brandt, Nitin Shivaram, Malcolm Davis, des machines et plus des parties de notre cerveau ou d'autres formes d'expressions
ainsi qu' tous ceux qui se sont exprims. Cela m'a rellement aid mettre le projet telles que l'criture, la peinture, la sculpture ou la ralisation de films. La
jour. Programmation Oriente Objet (POO) fait partie de ce mouvement qui utilise
l'ordinateur en tant que moyen d'expression.
#/TIJ_PAGE02#
Ce chapitre prsente les concepts de base de la POO, y compris quelques mthodes
#TIJ_PAGE01#
de dveloppement. Ce chapitre et ce livre prsupposent que vous avez dj
02.12.2001 -version 5.9.1 [Armel] : expriment avec un langage de programmation procdural, bien que celui-ci ne soit
- Enlev l'encodage latin-1 lors du passage dans html-tidy pas forcment le C. Si vous pensez que vous avez besoin de plus de pratique dans la
- Ajout de deux, trois balises font manquantes.
02.12.2001 - version 5.9 [Jrome] :
programmation et / ou la syntaxe du C avant de commencer ce livre, vous devriez
- Corrections apportes par Patrick Godeau. explorer le CD ROM fourni avec le livre, Thinking in C: Foundations for C++ and
22.06.2001 - version 5.8 : Java, aussi disponible sur www.BruceEckel.com.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 20/459
Ce chapitre tient plus de la culture gnrale. Beaucoup de personnes ne veulent pas reprsentation se veut assez gnrale pour ne pas restreindre le programmeur un
se lancer dans la programmation oriente objet sans en comprendre d'abord les type particulier de problmes. Nous nous rfrons aux lments dans l'espace
tenants et les aboutissants. C'est pourquoi nous allons introduire ici de nombreux problme et leur reprsentation dans l'espace solution en tant qu' objets . (Bien
concepts afin de vous donner un solide aperu de la POO. Au contraire, certaines sr, on aura aussi besoin d'autres objets qui n'ont pas leur analogue dans l'espace
personnes ne saisissent les concepts gnraux qu'aprs en avoir vu quelques problme). L'ide est que le programme est autoris s'adapter l'esprit du
mcanismes mis en uvre ; ces gens-l se sentent perdus s'ils n'ont pas un bout de problme en ajoutant de nouveaux types d'objet, de faon ce que, quand on lit le
code se mettre sous la dent. Si vous faites partie de cette catgorie de personnes et code dcrivant la solution, on lit aussi quelque chose qui dcrit le problme. C'est
tes impatients d'attaquer les spcificits du langage, vous pouvez sauter ce chapitre une abstraction plus flexible et puissante que tout ce qu'on a pu voir jusqu' prsent.
- cela ne vous gnera pas pour l'criture de programme ou l'apprentissage du Ainsi, la POO permet de dcrire le problme avec les termes mmes du problme
langage. Mais vous voudrez peut-tre y revenir plus tard pour approfondir vos plutt qu'avec les termes de la machine o la solution sera mise en oeuvre. Il y a tout
connaissances sur les objets, les comprendre et assimiler la conception objet. de mme une connexion avec l'ordinateur, bien entendu. Chaque objet ressemble
un mini-ordinateur ; il a un tat, et il a sa disposition des oprations qu'on peut lui
demander d'excuter. Cependant, l encore on retrouve une analogie avec les objets
Les bienfaits de l'abstraction du monde rel - ils ont tous des caractristiques et des comportements.
Des concepteurs de langage ont dcrt que la programmation oriente objet en
Tous les langages de programmation fournissent des abstractions. On peut dire que elle-mme n'tait pas adquate pour rsoudre facilement tous les problmes de
la complexit des problmes qu'on est capable de rsoudre est directement programmation, et recommandent la combinaison d'approches varies dans des
proportionnelle au type et la qualit de nos capacits d'abstraction. Par type , il langages de programmation multiparadigmes.[2]
faut comprendre Qu'est-ce qu'on tente d'abstraire ? . Le langage assembleur est
une petite abstraction de la machine sous-jacente. Beaucoup de langages Alan Kay rsume les cinq caractristiques principales de Smalltalk, le premier
impratifs (tels que Fortran, BASIC, et C) sont des abstractions du langage vritable langage de programmation orient objet et l'un des langages sur lequel est
assembleur. Ces langages sont de nettes amliorations par rapport l'assembleur, bas Java. Ces caractristiques reprsentent une approche purement oriente objet :
mais leur abstraction premire requiert une rflexion en termes de structure 1. Toute chose est un objet. Il faut penser un objet comme une variable
ordinateur plutt qu' la structure du problme qu'on essaye de rsoudre. Le amliore : il stocke des donnes, mais on peut effectuer des requtes
programmeur doit tablir l'association entre le modle de la machine (dans sur cet objet, lui demander de faire des oprations sur lui-mme. En thorie,
l'espace solution , qui est l'endroit o le problme est modlis, tel que on peut prendre n'importe quel composant conceptuel du problme qu'on
l'ordinateur) et le modle du problme rsoudre (dans l'espace problme , qui essaye de rsoudre (un chien, un immeuble, un service administratif, etc...)
est l'endroit o se trouve le problme). Les efforts requis pour raliser cette et le reprsenter en tant qu'objet dans le programme.
association, et le fait qu'elle est trangre au langage de programmation, produit des 2. Un programme est un ensemble d'objets se disant les uns aux
programmes difficiles crire et maintenir, et comme effet de bord a men la autres quoi faire en s'envoyant des messages. Pour qu'un objet
cration de l'industrie du Gnie Logiciel. effectue une requte, on envoie un message cet objet. Plus
L'autre alternative la modlisation de la machine est de modliser le problme concrtement, on peut penser un message comme un appel de fonction
qu'on tente de rsoudre. Les premiers langages tels que LISP ou APL choisirent une appartenant un objet particulier.
vue particulire du monde ( Tous les problmes se ramnent des listes ou 3. Chaque objet a son propre espace de mmoire compos d'autres
Tous les problmes sont algorithmiques , respectivement). PROLOG convertit objets. Dit d'une autre manire, on cre un nouveau type d'objet en crant
tous les problmes en chanes de dcisions. Des langages ont t crs en vue de un paquetage contenant des objets dj existants. Ainsi, la complexit d'un
programmer par contrainte, ou pour programmer en ne manipulant que des programme est cache par la simplicit des objets mis en oeuvre.
symboles graphiques (ces derniers se sont rvls tre trop restrictifs). Chacune de 4. Chaque objet est d'un type prcis. Dans le jargon de la POO, chaque
ces approches est une bonne solution pour la classe particulire de problmes pour objet est une instance d'une classe, o classe est synonyme de type .
laquelle ils ont t conus, mais devient une horreur ds lors que vous les sortez de La plus importante caractristique distinctive d'une classe est : Quels
leur domaine d'application. messages peut-on lui envoyer ? .
5. Tous les objets d'un type particulier peuvent recevoir le mme
L'approche oriente objet va un cran plus loin en fournissant des outils au message. C'est une caractristique lourde de signification, comme vous le
programmeur pour reprsenter des lments dans l'espace problme. Cette
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 21/459
verrez plus tard. Parce qu'un objet de type cercle est aussi un objet de au lieu d'tre forc d'utiliser un type de donnes conu pour reprsenter une unit
type forme gomtrique , un cercle se doit d'accepter les messages de stockage de l'ordinateur. Le langage de programmation est tendu en ajoutant de
destins aux formes gomtriques. Cela veut dire qu'on peut crire du code nouveaux types de donnes spcifiques nos besoins. Le systme de programmation
parlant aux formes gomtriques qui sera accept par tout ce qui accepte la nouvelle classe et lui donne toute l'attention et le contrle de type qu'il
correspond la description d'une forme gomtrique. Cette substituabilit fournit aux types prdfinis.
est l'un des concepts les plus puissants de la programmation oriente objet.
L'approche oriente objet n'est pas limite aux simulations. Que vous pensiez ou
non que tout programme n'est qu'une simulation du systme qu'on reprsente,
Un objet dispose d'une interface l'utilisation des techniques de la POO peut facilement rduire un ensemble de
problmes une solution simple.
Aristote fut probablement le premier commencer une tude approfondie du Une fois qu'une classe est cre, on peut crer autant d'objets de cette classe qu'on
concept de type ; il parle de la classe des poissons et la classe des oiseaux . L'ide veut et les manipuler comme s'ils taient les lments du problme qu'on tente de
que tous les objets, tout en tant uniques, appartiennent une classe d'objets qui rsoudre. En fait, l'une des difficults de la programmation oriente objet est de
ont des caractristiques et des comportements en commun fut utilise directement crer une association un--un entre les lments de l'espace problme et les
dans le premier langage orient objet, Simula-67, avec son mot clef fondamental lments de l'espace solution.
class qui introduit un nouveau type dans un programme. Mais comment utiliser un objet ? Il faut pouvoir lui demander d'excuter une
Simula, comme son nom l'indique, a t conu pour dvelopper des simulations requte, telle que terminer une transaction, dessiner quelque chose l'cran, ou
telles qu'un guichet de banque. Dans celle-ci, vous avez un ensemble de guichetiers, allumer un interrupteur. Et chaque objet ne peut traiter que certaines requtes. Les
de clients, de comptes, de transactions et de devises - un tas d'objets . Des objets requtes qu'un objet est capable de traiter sont dfinies par son interface, et son
semblables, leur tat durant l'excution du programme mis part, sont groups type est ce qui dtermine son interface. Prenons l'exemple d'une ampoule
ensemble en tant que classes d'objets et c'est de l que vient le mot clef class. lectrique :
Crer des types de donnes abstraits (des classes) est un concept fondamental dans
la programmation oriente objet. On utilise les types de donnes abstraits
exactement de la mme manire que les types de donnes prdfinis. On peut crer
des variables d'un type particulier (appels objets ou instances dans le jargon OO) et
manipuler ces variables (ce qu'on appelle envoyer des messages ou des requtes ; on
envoie un message et l'objet se dbrouille pour le traiter). Les membres (lments)
d'une mme classe partagent des caractristiques communes : chaque compte
dispose d'un solde, chaque guichetier peut accepter un dpt, etc... Cependant,
chaque lment a son propre tat : chaque compte a un solde diffrent, chaque
guichetier a un nom. Ainsi, les guichetiers, clients, comptes, transactions, etc...
peuvent tous tre reprsents par la mme entit au sein du programme. Cette
entit est l'objet, et chaque objet appartient une classe particulire qui dfinit ses
caractristiques et ses comportements. Ampoule amp = new Ampoule();
amp.allumer();
Donc, comme la programmation oriente objet consiste en la cration de nouveaux
types de donnes, quasiment tous les langages orients objet utilisent le mot clef L'interface prcise quelles oprations on peut effectuer sur un objet particulier.
class . Quand vous voyez le mot type pensez classe et inversement [3]. Cependant, il doit exister du code quelque part pour satisfaire cette requte. Ceci,
Comme une classe dcrit un ensemble d'objets partageant des caractristiques avec les donnes caches, constitue l'implmentation. Du point de vue de la
communes (donnes) et des comportements (fonctionnalits), une classe est programmation procdurale, ce n'est pas si compliqu. Un type dispose d'une
rellement un type de donnes. En effet, un nombre en virgule flottante par fonction associe chaque requte possible, et quand on effectue une requte
exemple, dispose d'un ensemble de caractristiques et de comportements. La particulire sur un objet, cette fonction est appele. Ce mcanisme est souvent
diffrence est qu'un programmeur dfinit une classe pour reprsenter un problme rsum en disant qu'on envoie un message (fait une requte) un objet, et l'objet
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 22/459
se dbrouille pour l'interprter (il excute le code associ). de la classe ne manipule pas directement certains membres de la classe, sans
contrle d'accs il n'y a aucun moyen de l'empcher : tout est expos tout le
Ici, le nom du type / de la classe est Ampoule, le nom de l'objet Ampoule cr est
monde.
amp, et on peut demander un objet Ampoule de s'allumer, de s'teindre,
d'intensifier ou de diminuer sa luminosit. Un objet Ampoule est cr en La raison premire du contrle d'accs est donc d'empcher les programmeurs
dfinissant une rfrence (amp) pour cet objet et en appelant new pour crer clients de toucher certaines portions auxquelles ils ne devraient pas avoir accs -
un nouvel objet de ce type. Pour envoyer un message cet objet, il suffit de spcifier les parties qui sont ncessaires pour les manipulations internes du type de donnes
le nom de l'objet suivi de la requte avec un point entre les deux. Du point de vue de mais n'appartiennent pas l'interface dont les utilisateurs ont besoin pour rsoudre
l'utilisateur d'une classe prdfinie, c'est tout ce qu'il est besoin de savoir pour leur problme. C'est en ralit un service rendu aux utilisateurs car ils peuvent voir
programmer avec des objets. facilement ce qui est important pour leurs besoins et ce qu'ils peuvent ignorer.
L'illustration ci-dessus reprend le formalisme UML (Unified Modeling Language). La deuxime raison d'tre du contrle d'accs est de permettre au concepteur de la
Chaque classe est reprsente par une bote, avec le nom du type dans la partie bibliothque de changer le fonctionnement interne de la classe sans se soucier des
suprieure, les donnes membres qu'on dcide de dcrire dans la partie du milieu et effets que cela peut avoir sur les programmeurs clients. Par exemple, on peut
les fonctions membres (les fonctions appartenant cet objet qui reoivent les implmenter une classe particulire d'une manire simpliste afin d'acclrer le
messages envoyes cet objet) dans la partie du bas de la bote. Souvent on ne dveloppement, et se rendre compte plus tard qu'on a besoin de la rcrire afin de
montre dans les diagrammes UML que le nom de la classe et les fonctions gagner en performances. Si l'interface et l'implmentation sont clairement spares
publiques, et la partie du milieu n'existe donc pas. Si seul le nom de la classe nous et protges, cela peut tre ralis facilement.
intresse, alors la portion du bas n'a pas besoin d'tre montre non plus.
Java utilise trois mots clefs pour fixer des limites au sein d'une classe : public,
private et protected. Leur signification et leur utilisation est relativement
L'implmentation cache explicite. Ces spcificateurs d'accs dterminent qui peut utiliser les dfinitions qui
suivent. public veut dire que les dfinitions suivantes sont disponibles pour tout le
monde. Le mot clef private, au contraire, veut dire que personne, le crateur de la
Il est plus facile de diviser les personnes en crateurs de classe (ceux qui crent les classe et les fonctions internes de ce type mis part, ne peut accder ces
nouveaux types de donnes) et programmeurs clients [4] (ceux qui utilisent ces dfinitions. private est un mur de briques entre le crateur de la classe et le
types de donnes dans leurs applications). Le but des programmeurs clients est de programmeur client. Si quelqu'un tente d'accder un membre dfini comme
se monter une bote outils pleine de classes rutilisables pour le dveloppement private, ils rcupreront une erreur lors de la compilation. protected se comporte
rapide d'applications (RAD, Rapid Application Development en anglais). Les comme private, en moins restrictif : une classe drive a accs aux membres
crateurs de classes, eux, se focalisent sur la construction d'une classe qui n'expose protected, mais pas aux membres private. L'hritage sera introduit bientt.
que le ncessaire aux programmeurs clients et cache tout le reste. Pourquoi cela ?
Parce que si c'est cach, le programmeur client ne peut l'utiliser, et le crateur de la Java dispose enfin d'un accs par dfaut , utilis si aucun de ces spcificateurs
classe peut changer la portion cache comme il l'entend sans se proccuper de n'est mentionn. Cet accs est souvent appel accs amical car les classes
l'impact que cela pourrait avoir chez les utilisateurs de sa classe. La portion cache peuvent accder aux membres amicaux des autres classes du mme package, mais
correspond en gnral aux donnes de l'objet qui pourraient facilement tre en dehors du package ces mmes membres amicaux se comportent comme des
corrompues par un programmeur client ngligent ou mal inform. Ainsi, cacher attributs private.
l'implmentation rduit considrablement les bugs.
Le concept d'implmentation cache ne saurait tre trop lou : dans chaque relation Rutilisation de l'implmentation
il est important de fixer des frontires respectes par toutes les parties concernes.
Quand on cre une bibliothque, on tablit une relation avec un programmeur
Une fois qu'une classe a t cre et teste, elle devrait (idalement) reprsenter une
client, programmeur qui cre une application (ou une bibliothque plus
partie de code utile. Il s'avre que cette rutilisabilit n'est pas aussi facile obtenir
consquente) en utilisant notre bibliothque.
que cela ; cela demande de l'exprience et de l'anticipation pour produire une bonne
Si tous les membres d'une classe sont accessibles pour tout le monde, alors le conception. Mais une fois bien conue, cette classe ne demande qu' tre rutilise.
programmeur client peut faire ce qu'il veut avec cette classe et il n'y a aucun moyen La rutilisation de code est l'un des plus grands avantages que les langages orients
de faire respecter certaines rgles. Mme s'il est vraiment prfrable que l'utilisateur objets fournissent.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 23/459
La manire la plus simple de rutiliser une classe est d'utiliser directement un objet Il serait toutefois dommage, aprs s'tre donn beaucoup de mal pour crer une
de cette classe, mais on peut aussi placer un objet de cette classe l'intrieur d'une classe de devoir en crer une toute nouvelle qui aurait des fonctionnalits similaires.
nouvelle classe. On appelle cela crer un objet membre . La nouvelle classe peut Ce serait mieux si on pouvait prendre la classe existante, la cloner, et faire des ajouts
tre constitue de n'importe quel nombre d'objets d'autres types, selon la ou des modifications ce clone. C'est ce que l'hritage permet de faire, avec la
combinaison ncessaire pour que la nouvelle classe puisse raliser ce pour quoi elle restriction suivante : si la classe originale (aussi appele classe de base, superclasse
a t conue. Parce que la nouvelle classe est compose partir de classes existantes, ou classe parent) est change, le clone modifi (appel classe drive, hrite,
ce concept est appel composition (ou, plus gnralement, agrgation). On se rfre enfant ou sousclasse) rpercutera aussi ces changements.
souvent la composition comme une relation possde-un , comme dans une
voiture possde un moteur .
(Le diagramme UML ci-dessus indique la composition avec le losange rempli, qui
indique qu'il y a un moteur dans une voiture. J'utiliserai une forme plus simple :
juste une ligne, sans le losange, pour indiquer une association [5].)
La composition s'accompagne d'une grande flexibilit : les objets membres de la (La flche dans le diagramme UML ci-dessus pointe de la classe drive vers la
nouvelle classe sont gnralement privs, ce qui les rend inaccessibles aux classe de base. Comme vous le verrez, il peut y avoir plus d'une classe drive.)
programmeurs clients de la classe. Cela permet de modifier ces membres sans #/TIJ_PAGE01# #TIJ_PAGE02#
perturber le code des clients existants. On peut aussi changer les objets membres
lors la phase d'excution, pour changer dynamiquement le comportement du Un type fait plus que dcrire des contraintes sur un ensemble d'objets ; il a aussi des
programme. L'hritage, dcrit juste aprs, ne dispose pas de cette flexibilit car le relations avec d'autres types. Deux types peuvent avoir des caractristiques et des
compilateur doit placer des restrictions lors de la compilation sur les classes cres comportements en commun, mais l'un des deux peut avoir plus de caractristiques
avec hritage. que l'autre et peut aussi ragir plus de messages (ou y ragir de manire
diffrente). L'hritage exprime cette similarit entre les types en introduisant le
Parce que la notion d'hritage est trs importante au sein de la programmation concept de types de base et de types drivs. Un type de base contient toutes les
oriente objet, elle est trop souvent martele, et le nouveau programmeur pourrait caractristiques et comportements partags entre les types drivs. Un type de base
croire que l'hritage doit tre utilis partout. Cela mne des conceptions ultra est cr pour reprsenter le coeur de certains objets du systme. De ce type de base,
compliques et cauchemardesques. La composition est la premire approche on drive d'autres types pour exprimer les diffrentes manires existantes pour
examiner lorsqu'on cre une nouvelle classe, car elle est plus simple et plus flexible. raliser ce coeur.
Le design de la classe en sera plus propre. Avec de l'exprience, les endroits o
utiliser l'hritage deviendront raisonnablement vidents. Prenons l'exemple d'une machine de recyclage qui trie les dtritus. Le type de base
serait dtritus , caractris par un poids, une valeur, etc.. et peut tre concass,
fondu, ou dcompos. A partir de ce type de base, sont drivs des types de dtritus
Hritage : rutilisation de l'interface plus spcifiques qui peuvent avoir des caractristiques supplmentaires (une
bouteille a une couleur) ou des actions additionnelles (une canette peut tre
L'ide d'objet en elle-mme est un outil efficace. Elle permet de fournir des donnes dcoupe, un container d'acier est magntique). De plus, des comportements
et des fonctionnalits lies entre elles par concept, afin de reprsenter une ide de peuvent tre diffrents (la valeur du papier dpend de son type et de son tat
l'espace problme plutt que d'tre forc d'utiliser les idiomes internes de la gnral). En utilisant l'hritage, on peut btir une hirarchie qui exprime le
machine. Ces concepts sont exprims en tant qu'unit fondamentale dans le langage problme avec ses propres termes.
de programmation en utilisant le mot clef class. Un autre exemple classique : les formes gomtriques , utilises entre autres
dans les systmes d'aide la conception ou dans les jeux vidos. Le type de base est
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 24/459
la forme gomtrique , et chaque forme a une taille, une couleur, une position, Comme la classe de base et la classe drive ont toutes les deux la mme interface,
etc... Chaque forme peut tre dessine, efface, dplace, peinte, etc... A partir de ce certaines implmentations accompagnent cette interface. C'est dire qu'il doit y
type de base, des types spcifiques sont drivs (hrits) : des cercles, des carrs, des avoir du code excuter quand un objet reoit un message particulier. Si on ne fait
triangles et autres, chacun avec des caractristiques et des comportements qu'hriter une classe sans rien lui rajouter, les mthodes de l'interface de la classe de
additionnels (certaines figures peuvent tre inverses par exemple). Certains base sont importes dans la classe drive. Cela veut dire que les objets de la classe
comportements peuvent tre diffrents, par exemple quand on veut calculer l'aire de drive n'ont pas seulement le mme type, ils ont aussi le mme comportement, ce
la forme. La hirarchie des types rvle la fois les similarits et les diffrences qui n'est pas particulirement intressant.
entre les formes.
Il y a deux faons de diffrencier la nouvelle classe drive de la classe de base
originale. La premire est relativement directe : il suffit d'ajouter de nouvelles
fonctions la classe drive. Ces nouvelles fonctions ne font pas partie de la classe
parent. Cela veut dire que la classe de base n'tait pas assez complte pour ce qu'on
voulait en faire, on a donc ajout de nouvelles fonctions. Cet usage simple
de l'hritage se rvle souvent tre une solution idale. Cependant, il faut tout de
mme vrifier s'il ne serait pas souhaitable d'intgrer ces fonctions dans la classe de
base qui pourrait aussi en avoir l'usage. Ce processus de dcouverte et d'itration
dans la conception est frquent dans la programmation oriente objet.
Reprsenter la solution avec les mmes termes que ceux du problme est
extraordinairement bnfique car on n'a pas besoin de modles intermdiaires pour
passer de la description du problme la description de la solution. Avec les objets,
la hirarchie de types est le modle primaire, on passe donc du systme dans le
monde rel directement au systme du code. En fait, l'une des difficults laquelle
les gens se trouvent confronts lors de la conception oriente objet est que c'est trop
simple de passer du dbut la fin. Les esprits habitus des solutions compliques
sont toujours stupfaits par cette simplicit.
Quand on hrite d'un certain type, on cre un nouveau type. Ce nouveau type non
seulement contient tous les membres du type existant (bien que les membres privs
soient cachs et inaccessibles), mais plus important, il duplique aussi l'interface de Bien que l'hritage puisse parfois impliquer (spcialement en Java, o le mot clef qui
la classe de la base. Autrement dit, tous les messages accepts par les objets de la indique l'hritage est extends) que de nouvelles fonctions vont tre ajoutes
classe de base seront accepts par les objets de la classe drive. Comme on connat l'interface, ce n'est pas toujours vrai. La seconde et plus importante manire de
le type de la classe par les messages qu'on peut lui envoyer, cela veut dire que la diffrencier la nouvelle classe est de changer le comportement d'une des fonctions
classe drive est du mme type que la classe de base. Dans l'exemple prcdent, existantes de la superclasse. Cela s'appelle redfinir cette fonction.
un cercle est une forme . Cette quivalence de type via l'hritage est l'une des
notions fondamentales dans la comprhension de la programmation oriente objet.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 25/459
pas rellement dire que ce soient exactement les mmes. Prenons le cas d'un
systme de climatisation. Supposons que notre maison dispose des tuyaux et des
systmes de contrle pour le refroidissement, autrement dit elle dispose d'une
interface qui nous permet de contrler le refroidissement. Imaginons que le systme
de climatisation tombe en panne et qu'on le remplace par une pompe chaleur, qui
peut la fois chauffer et refroidir. La pompe chaleur est-comme-un systme de
climatisation, mais il peut faire plus de choses. Parce que le systme de contrle n'a
t conu que pour contrler le refroidissement, il en est restreint ne
communiquer qu'avec la partie refroidissement du nouvel objet. L'interface du
nouvel objet a t tendue, mais le systme existant ne connat rien qui ne soit dans
l'interface originale.
Pour redfinir une fonction, il suffit de crer une nouvelle dfinition pour la fonction
dans la classe drive. C'est comme dire : j'utilise la mme interface ici, mais je la
traite d'une manire diffrente dans ce nouveau type .
Les relations est-un vs. est-comme-un
Un certain dbat est rcurrent propos de l'hritage : l'hritage ne devrait-il pas Bien sr, quand on voit cette modlisation, il est clair que la classe de base
seulement redfinir les fonctions de la classe de base (et ne pas ajouter de nouvelles Systme de refroidissement n'est pas assez gnrale, et devrait tre renomme
fonctions membres qui ne font pas partie de la superclasse) ? Cela voudrait dire que en Systme de contrle de temprature afin de pouvoir inclure le chauffage -
le type driv serait exactement le mme que celui de la classe de base puisqu'il auquel cas le principe de substitution marcherait. Cependant, le diagramme ci-
aurait exactement la mme interface. Avec comme consquence logique le fait qu'on dessus est un exemple de ce qui peut arriver dans le monde rel.
puisse exactement substituer un objet de la classe drive un objet de la classe de Quand on considre le principe de substitution, il est tentant de se dire que cette
base. On fait souvent rfrence cette substitution pure sous le nom de principe de approche (la substitution pure) est la seule manire correcte de modliser, et de fait
substitution. Dans un sens, c'est la manire idale de traiter l'hritage. La relation c'est apprciable si la conception fonctionne ainsi. Mais dans certains cas il est tout
entre la classe de base et la classe drive dans ce cas est une relation est-un, parce aussi clair qu'il faut ajouter de nouvelles fonctions l'interface d'une classe drive.
qu'on peut dire un cercle est une forme . Un test pour l'hritage est de dterminer En examinant le problme, les deux cas deviennent relativement vidents.
si la relation est-un entre les deux classes considres a un sens.
Mais parfois il est ncessaire d'ajouter de nouveaux lments l'interface d'un type
driv, et donc tendre l'interface et crer un nouveau type. Le nouveau type peut Polymorphisme : des objets
toujours tre substitu au type de base, mais la substitution n'est plus parfaite parce
que les nouvelles fonctions ne sont pas accessibles partir de la classe parent. On interchangeables
appelle cette relation une relation est-comme-un [6]; le nouveau type dispose de
l'interface de l'ancien type mais il contient aussi d'autres fonctions, on ne peut donc Il arrive qu'on veuille traiter un objet non en tant qu'objet du type spcifique qu'il
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 26/459
est, mais en tant qu'objet de son type de base. Cela permet d'crire du code
indpendant des types spcifiques. Dans l'exemple de la forme gomtrique, les
fonctions manipulent des formes gnriques sans se soucier de savoir si ce sont des
cercles, des carrs, des triangles ou mme des formes non encore dfinies. Toutes les
formes peuvent tre dessines, effaces, et dplaces, donc ces fonctions envoient
simplement un message un objet forme, elles ne se soucient pas de la manire
dont l'objet traite le message.
Un tel code n'est pas affect par l'addition de nouveaux types, et ajouter de
nouveaux types est la faon la plus commune d'tendre un programme orient objet
pour traiter de nouvelles situations. Par exemple, on peut driver un nouveau type
de forme appel pentagone sans modifier les fonctions qui traitent des formes
gnriques. Cette capacit tendre facilement un programme en drivant de
nouveaux sous-types est important car il amliore considrablement la conception
tout en rduisant le cot de maintenance. La rponse constitue l'astuce fondamentale de la programmation oriente objet : le
Un problme se pose cependant en voulant traiter les types drivs comme leur type compilateur ne peut faire un appel de fonction au sens traditionnel du terme. Un
de base gnrique (les cercles comme des formes gomtriques, les vlos comme des appel de fonction gnr par un compilateur non orient objet cre ce qu'on appelle
vhicules, les cormorans comme des oiseaux, etc...). Si une fonction demande une une association prdfinie, un terme que vous n'avez sans doute jamais entendu
forme gnrique de se dessiner, ou un vhicule gnrique de tourner, ou un auparavant car vous ne pensiez pas qu'on puisse faire autrement. En d'autres
oiseau gnrique de se dplacer, le compilateur ne peut savoir prcisment lors de la termes, le compilateur gnre un appel un nom de fonction spcifique, et l'diteur
phase de compilation quelle portion de code sera excute. C'est d'ailleurs le point de liens rsout cet appel l'adresse absolue du code excuter. En POO, le
crucial : quand le message est envoy, le programmeur ne veut pas savoir quelle programme ne peut dterminer l'adresse du code avant la phase d'excution, un
portion de code sera excute ; la fonction dessiner peut tre applique aussi bien autre mcanisme est donc ncessaire quand un message est envoy un objet
un cercle qu' un carr ou un triangle, et l'objet va excuter le bon code suivant son gnrique.
type spcifique. Si on n'a pas besoin de savoir quelle portion de code est excute, Pour rsoudre ce problme, les langages orients objet utilisent le concept
alors le code excut lorsque on ajoute un nouveau sous-type peut tre diffrent d'association tardive. Quand un objet reoit un message, le code appel n'est pas
sans exiger de modification dans l'appel de la fonction. Le compilateur ne peut donc dtermin avant l'excution. Le compilateur s'assure que la fonction existe et vrifie
prcisment savoir quelle partie de code sera excute, donc que va-t-il faire ? Par le type des arguments et de la valeur de retour (un langage omettant ces
exemple, dans le diagramme suivant, l'objet Contrleur d'oiseaux travaille vrifications est dit faiblement typ), mais il ne sait pas exactement quel est le code
seulement avec des objets Oiseaux gnriques, et ne sait pas de quel type ils sont. excuter.
Cela est pratique du point de vue de Contrleur d'oiseaux car il n'a pas besoin
d'crire du code spcifique pour dterminer le type exact d'Oiseau avec lequel il Pour crer une association tardive, Java utilise une portion spciale de code en lieu
travaille, ou le comportement de cet Oiseau. Comment se fait-il donc que, lorsque et place de l'appel absolu. Ce code calcule l'adresse du corps de la fonction, en
bouger() est appel tout en ignorant le type spcifique de l'Oiseau, on obtienne le utilisant des informations stockes dans l'objet (ce mcanisme est couvert plus en
bon comportement (une Oie court, vole ou nage, et un Pingouin court ou nage) ? dtails dans le Chapitre 7). Ainsi, chaque objet peut se comporter diffremment
suivant le contenu de cette portion spciale de code. Quand un objet reoit un
message, l'objet sait quoi faire de ce message.
Dans certains langages (en particulier le C++), il faut prciser explicitement qu'on
souhaite bnficier de la flexibilit de l'association tardive pour une fonction. Dans
ces langages, les fonctions membres ne sont pas lies dynamiquement par dfaut.
Cela pose des problmes, donc en Java l'association dynamique est le dfaut et
aucun mot clef supplmentaire n'est requis pour bnficier du polymorphisme.
Reprenons l'exemple de la forme gomtrique. Le diagramme de la hirarchie des
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 27/459
classes (toutes bases sur la mme interface) se trouve plus haut dans ce chapitre.
Pour illustrer le polymorphisme, crivons un bout de code qui ignore les dtails
spcifiques du type et parle uniquement la classe de base. Ce code est dconnect
des informations spcifiques au type, donc plus facile crire et comprendre. Et si
un nouveau type - un Hexagone, par exemple - est ajout grce l'hritage, le code
continuera de fonctionner aussi bien pour ce nouveau type de Forme qu'il le faisait
avec les types existants. Le programme est donc extensible.
Si nous crivons une mthode en Java (comme vous allez bientt apprendre le
faire) :
void faireQuelqueChose(Forme f) {
f.effacer();
// ...
f.dessiner(); Un programme orient objet contient obligatoirement des transtypages ascendants,
} car c'est de cette manire que le type spcifique de l'objet peut tre dlibrment
ignor. Examinons le code de faireQuelqueChose() :
Cette fonction s'adresse n'importe quelle Forme, elle est donc indpendante du f.effacer();
type spcifique de l'objet qu'elle dessine et efface. Si nous utilisons ailleurs dans le // ...
programme cette fonction faireQuelqueChose() : f.dessiner();
Cercle c = new Cercle();
Triangle t = new Triangle(); Remarquez qu'il ne dit pas Si tu es un Cercle, fais ceci, si tu es un Carr, fais cela,
Ligne l = new Ligne(); etc... . Ce genre de code qui vrifie tous les types possibles que peut prendre une
faireQuelqueChose(c); Forme est confus et il faut le changer chaque extension de la classe Forme. Ici, il
faireQuelqueChose(t);
faireQuelqueChose(l); suffit de dire : Tu es une forme gomtrique, je sais que tu peux te dessiner() et
t'effacer(), alors fais-le et occupe-toi des dtails spcifiques .
Les appels faireQuelqueChose() fonctionnent correctement, sans se Ce qui est impressionnant dans le code de faireQuelqueChose(), c'est que tout
proccuper du type exact de l'objet. fonctionne comme on le souhaite. Appeler dessiner() pour un Cercle excute une
portion de code diffrente de celle excute lorsqu'on appelle dessiner() pour un
En fait c'est une manire de faire trs lgante. Considrons la ligne :
Carr ou une Ligne, mais lorsque le message dessiner() est envoy une Forme
faireQuelqueChose(c); anonyme, on obtient le comportement idoine bas sur le type rel de la Forme. Cela
est impressionnant dans la mesure o le compilateur Java ne sait pas quel type
Un Cercle est ici pass une fonction qui attend une Forme. Comme un Cercle d'objet il a affaire lors de la compilation du code de faireQuelqueChose(). On
est-une Forme, il peut tre trait comme tel par faireQuelqueChose(). C'est serait en droit de s'attendre un appel aux versions dessiner() et effacer() de la
dire qu'un Cercle peut accepter tous les messages que faireQuelqueChose() classe de base Forme, et non celles des classes spcifiques Cercle, Carr et Ligne.
pourrait envoyer une forme. C'est donc une faon parfaitement logique et sre de Mais quand on envoie un message un objet, il fera ce qu'il a faire, mme quand la
faire. gnralisation est implique. C'est ce qu'implique le polymorphisme. Le compilateur
et le systme d'excution s'occupent des dtails, et c'est tout ce que vous avez besoin
Traiter un type driv comme s'il tait son type de base est appel transtypage de savoir, en plus de savoir comment modliser avec.
ascendant, surtypage ou gnralisation (upcasting). L'adjectif ascendant vient du
fait que dans un diagramme d'hritage typique, le type de base est reprsent en
haut, les classes drives s'y rattachant par le bas. Ainsi, changer un type vers son Classes de base abstraites et interfaces
type de base revient remonter dans le diagramme d'hritage : transtypage
ascendant . Dans une modlisation, il est souvent souhaitable qu'une classe de base ne prsente
qu'une interface pour ses classes drives. C'est dire qu'on ne souhaite pas qu'il
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 28/459
soit possible de crer un objet de cette classe de base, mais seulement pouvoir mmoire appel le segment. Dans cette approche, le nombre d'objets ncessaire
surtyper jusqu' elle pour pouvoir utiliser son interface. Cela est possible en rendant n'est pas connu avant l'excution, de mme que leur dure de vie ou leur type exact.
cette classe abstraite en utilisant le mot clef abstract. Le compilateur se plaindra si Ces paramtres sont dtermins sur le coup, au moment o le programme s'excute.
une tentative est faite de crer un objet d'une classe dfinie comme abstract. C'est Si on a besoin d'un nouvel objet, il est simplement cr dans le segment au moment
un outil utilis pour forcer une certain conception. o on en a besoin. Comme le stockage est gr de manire dynamique lors de
l'excution, le temps de traitement requis pour allouer de la place dans le segment
Le mot clef abstract est aussi utilis pour dcrire une mthode qui n'a pas encore
est plus important que le temps mis pour stocker sur la pile (stocker sur la pile se
t implmente - comme un panneau indiquant voici une fonction de l'interface
rsume souvent une instruction assembleur pour dplacer le pointeur de pile vers
dont les types drivs ont hrit, mais actuellement je n'ai aucune implmentation
le bas, et une autre pour le redplacer vers le haut). L'approche dynamique fait la
pour elle . Une mthode abstract peut seulement tre cre au sein d'une classe
supposition gnralement justifie que les objets ont tendance tre compliqus, et
abstract. Quand cette classe est drive, cette mthode doit tre implmente, ou la
que le surcot de temps d la recherche d'une place de stockage et sa libration
classe drive devient abstract elle aussi. Crer une mthode abstract permet de
n'aura pas d'impact significatif sur la cration d'un objet. De plus, la plus grande
l'inclure dans une interface sans tre oblig de fournir une portion de code
flexibilit qui en rsulte est essentielle pour rsoudre le problme modlis par le
ventuellement dpourvue de sens pour cette mthode.
programme.
Le mot clef interface pousse le concept de classe abstract un cran plus loin en
#/TIJ_PAGE02# #TIJ_PAGE03#
vitant toute dfinition de fonction. Une interface est un outil trs pratique et trs
largement rpandu, car il fournit une sparation parfaite entre l'interface et Java utilise exclusivement la deuxime approche [7]. Le mot clef new est utilis
l'implmentation. De plus, on peut combiner plusieurs interfaces, alors qu'hriter de pour crer une instance dynamique d'un objet chaque fois qu'on en a besoin.
multiples classes normales ou abstraites est impossible.
Une autre particularit importante est la dure de vie d'un objet. Avec les langages
qui autorisent la cration d'objets dans la pile, le compilateur dtermine combien de
Environnement et dure de vie des temps l'objet est amen vivre et peut le dtruire automatiquement. Mais si l'objet
est cr dans le segment, le compilateur n'a aucune ide de sa dure de vie. Dans un
objets langage comme le C++, il faut dterminer dans le programme quand dtruire l'objet,
ce qui peut mener des fuites de mmoire si cela n'est pas fait correctement (et c'est
un problme courant en C++). Java propose une fonctionnalit appele ramasse-
Techniquement, les spcificits de la programmation oriente objet se rsument au
miettes (garbage collector) qui dcouvre automatiquement quand un objet n'est plus
typage abstrait des donnes, l'hritage et au polymorphisme, mais d'autres
utilis et le dtruit. Java propose donc un niveau plus lev d'assurance contre les
particularits peuvent se rvler aussi importantes. Le reste de cette section traite de
fuites de mmoire. Disposer d'un ramasse-miettes est pratique car cela rduit le
ces particularits.
code crire et, plus important, le nombre de problmes lis la gestion de la
L'une des particularits les plus importantes est la faon dont les objets sont crs et mmoire (qui ont men l'abandon de plus d'un projet C++).
dtruits. O se trouvent les donnes d'un objet et comment sa dure de vie est-elle
Le reste de cette section s'attarde sur des facteurs additionnels concernant
contrle ? Diffrentes philosophies existent. En C++, qui prne que l'efficacit est
l'environnement et la dure de vie des objets.
le facteur le plus important, le programmeur a le choix. Pour une vitesse optimum
l'excution, le stockage et la dure de vie peuvent tre dtermins quand le
programme est crit, en plaant les objets sur la pile (ces variables sont parfois Collections et itrateurs
appeles automatiques ou de porte) ou dans l'espace de stockage statique. La
vitesse d'allocation et de libration est dans ce cas prioritaire et leur contrle peut Si le nombre d'objets ncessaires la rsolution d'un problme est inconnu, ou
tre vraiment apprciable dans certaines situations. Cependant, cela se fait aux combien de temps on va en avoir besoin, on ne peut pas non plus savoir comment
dpends de la flexibilit car il faut connatre la quantit exacte, la dure de vie et le les stocker. Comment dterminer l'espace ncessaire pour crer ces objets ? C'est
type des objets pendant qu'on crit le programme. Si le problme rsoudre est plus impossible car cette information n'est connue que lors de l'excution.
gnral, tel que de la modlisation assiste par ordinateur, de la gestion d'entrepts
ou du contrle de trafic arien, cela se rvle beaucoup trop restrictif. La solution la plupart des problmes en conception oriente objet est simple : il
suffit de crer un nouveau type d'objet. Le nouveau type d'objets qui rsout ce
La deuxime approche consiste crer les objets dynamiquement dans un pool de problme particulier contient des rfrences aux autres objets. Bien sr, un tableau
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 29/459
ferait aussi bien l'affaire. Mais il y a plus. Ce nouvel objet, appel conteneur (ou une interface et un comportement diffrents de ceux d'une file, qui sont diffrents
collection, mais la bibliothque Java utilise ce terme dans un autre sens ; nous de ceux fournis par un ensemble ou une liste. L'un de ces conteneurs peut se rvler
utiliserons donc le terme conteneur dans la suite de ce livre), grandira plus flexible qu'un autre pour la rsolution du problme considr. Deuximement,
automatiquement pour accepter tout ce qu'on place dedans. Connatre le nombre les conteneurs ne sont pas d'une mme efficacit pour les mmes oprations.
d'objets qu'on dsire stocker dans un conteneur n'est donc plus ncessaire. Il suffit Prenons le cas d'une ArrayList et d'une LinkedList. Les deux sont de simples
de crer un objet conteneur et le laisser s'occuper des dtails. squences qui peuvent avoir la mme interface et comportement. Mais certaines
oprations ont des cots radicalement diffrents. Accder des lments au hasard
Heureusement, les langages orients objet dcents fournissent ces conteneurs. En
dans une ArrayList est une opration qui demande toujours le mme temps, quel
C++, ils font partie de la bibliothque standard (STL, Standard Template Library).
que soit l'lment auquel on souhaite accder. Mais dans une LinkedList, il est
Le Pascal Objet dispose des conteneurs dans sa Bibliothque de Composants Visuels
coteux de se dplacer dans la liste pour rechercher un lment, et cela prend plus
(VCL, Visual Component Library). Smalltalk propose un ensemble vraiment complet
de temps pour trouver un lment qui se situe plus loin dans la liste. Par contre, si
de conteneurs. Java aussi propose des conteneurs dans sa bibliothque standard.
on souhaite insrer un lment au milieu d'une squence, c'est bien plus efficace
Dans certaines bibliothques, un conteneur gnrique est jug suffisant pour tous
dans une LinkedList que dans une ArrayList. Ces oprations et d'autres ont des
les besoins, et dans d'autres (Java par exemple), la bibliothque dispose de
efficacits diffrentes suivant la structure sous-jacente de la squence. Dans la phase
diffrents types de conteneurs suivant les besoins : des vecteurs (appel ArrayList
de conception, on peut dbuter avec une LinkedList et lorsqu'on se penche sur
en Java) pour un accs pratique tous les lments, des listes chanes pour faciliter
l'optimisation, changer pour une ArrayList. Grce l'abstraction fournie par les
l'insertion, par exemple, on peut donc choisir le type particulier qui convient le
itrateurs, on peut passer de l'une l'autre avec un impact minime sur le code.
mieux. Les bibliothques de conteneurs peuvent aussi inclure les ensembles, les
files, les dictionnaires, les arbres, les piles, etc... En dfinitive, un conteneur n'est qu'un espace de stockage o placer des objets. Si ce
conteneur couvre tous nos besoins, son implmentation relle n'a pas grande
Tous les conteneurs disposent de moyens pour y stocker des choses et les rcuprer ;
importance (un concept de base pour la plupart des objets). Mais il arrive que la
ce sont habituellement des fonctions pour ajouter des lments dans un conteneur
diffrence de cots entre une ArrayList et une LinkedList ne soit pas ngliger,
et d'autres pour les y retrouver. Mais retrouver des lments peut tre
suivant l'environnement du problme et d'autres facteurs. On peut n'avoir besoin
problmatique, car une fonction de slection unique peut se rvler trop restrictive.
que d'un seul type de squence. On peut mme imaginer le conteneur parfait ,
Comment manipuler ou comparer un ensemble d'lments dans le conteneur ?
qui changerait automatiquement son implmentation selon la manire dont on
La rponse cette question prend la forme d'un itrateur, qui est un objet dont le l'utilise.
travail est de choisir les lments d'un conteneur et de les prsenter l'utilisateur de
l'itrateur. En tant que classe, il fournit de plus un niveau d'abstraction
supplmentaire. Cette abstraction peut tre utilise pour sparer les dtails du
La hirarchie de classes unique
conteneur du code qui utilise ce conteneur. Le conteneur, via l'itrateur, est peru
comme une squence. L'itrateur permet de parcourir cette squence sans se L'une des controverses en POO devenue prominente depuis le C++ demande si
proccuper de sa structure sous-jacente - qu'il s'agisse d'une ArrayList (vecteur), toutes les classes doivent tre finalement drives d'une classe de base unique. En
une LinkedList (liste chane), une Stack (pile) ou autre. Cela permet de changer Java (et comme dans pratiquement tous les autres langages OO) la rponse est
facilement la structure de donnes sous-jacente sans perturber le code du oui et le nom de cette classe de base ultime est tout simplement Object. Les
programme. Java commena (dans les versions 1.0 et 1.1) avec un itrateur bnfices d'une hirarchie de classes unique sont multiples.
standard, appel Enumeration, pour toutes ses classes conteneurs. Java 2 est Tous les objets dans une hirarchie unique ont une interface commune, ils sont donc
accompagn d'une bibliothque de conteneurs beaucoup plus complte qui contient tous du mme type fondamental. L'alternative (propose par le C++) est qu'on ne
entre autres un itrateur appel Iterator bien plus puissant que l'ancienne sait pas que tout est du mme type fondamental. Du point de vue de la compatibilit
Enumeration. ascendante, cela pouse plus le modle du C et peut se rvler moins restrictif, mais
Du point de vue du design, tout ce dont on a besoin est une squence qui peut tre lorsqu'on veut programmer en tout objet il faut reconstruire sa propre hirarchie de
manipule pour rsoudre le problme. Si un seul type de squence satisfaisait tous classes pour bnficier des mmes avantages fournis par dfaut par les autres
les besoins, il n'y aurait pas de raison d'en avoir de types diffrents. Il y a deux langages OO. Et dans chaque nouvelle bibliothque de classes qu'on rcupre, une
raisons qui font qu'on a besoin d'un choix de conteneurs. Tout d'abord, les interface diffrente et incompatible sera utilise. Cela demande des efforts (et
conteneurs fournissent diffrents types d'interfaces et de comportements. Une pile a ventuellement l'utilisation de l'hritage multiple) pour intgrer la nouvelle
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 30/459
interface dans la conception. Est-ce que la flexibilit que le C++ fournit en vaut Comment le rcuprer et retrouver l'interface de l'objet qu'on a stock dans le
rellement le coup ? Si on en a besoin - par exemple si on dispose d'un gros conteneur ?
investissement en C - alors oui. Mais si on dmarre de zro, d'autres alternatives
On assiste ici aussi un transtypage, mais cette fois-ci il ne remonte pas dans la
telles que Java se rvlent beaucoup plus productives.
hirarchie de classe un type plus gnral, mais descend dans la hirarchie jusqu'
Tous les objets dans une hirarchie de classes unique (comme celle que propose un type plus spcifique, c'est un transtypage descendant ou spcialisation, ou
Java) sont garantis d'avoir certaines fonctionnalits. Un certain nombre soustypage. Avec la gnralisation, on sait par exemple qu'un Cercle est un type de
d'oprations lmentaires peuvent tre effectues sur tous les objets du systme. Forme, et que le transtypage est donc sans danger ; mais on ne sait pas qu'un
Une hirarchie de classes unique, accompagne de la cration des objets dans le Object est aussi un Cercle ou une Forme, il est donc rarement sr d'appliquer une
segment, simplifie considrablement le passage d'arguments (l'un des sujets les plus spcialisation moins de savoir exactement quoi on a affaire.
complexes en C++).
Ce n'est pas trop dangereux cependant, car si une spcialisation est tente jusqu'
Une hirarchie de classes unique facilite aussi l'implmentation d'un ramasse- un type incompatible le systme d'excution gnrera une erreur appele exception,
miettes (qui est fourni en standard en Java). Le support ncessaire est implant qui sera dcrite plus loin. Quand une rfrence d'objet est rapatrie d'un conteneur,
dans la classe de base, et le ramasse-miettes peut donc envoyer le message idoine il faut donc un moyen de se rappeler exactement son type afin de pouvoir le
tout objet du systme. Sans une hirarchie de classe unique et un systme spcialiser correctement.
permettant de manipuler un objet via une rfrence, il est difficile d'implmenter un
La spcialisation et les contrles l'excution gnrent un surcot de temps pour le
ramasse-miettes.
programme, et des efforts supplmentaires de la part du programmeur. Il semblerait
Comme tout objet dispose en lui d'informations dynamiques, on ne peut se plus logique de crer le conteneur de faon ce qu'il connaisse le type de l'objet
retrouver avec un objet dont on ne peut dterminer le type. Ceci est particulirement stock, liminant du coup la spcialisation et la possibilit d'erreur. La solution est
important avec les oprations du niveau systme, telles que le traitement des fournie par les types paramtrs, qui sont des classes que le compilateur peut
exceptions, et cela permet une plus grande flexibilit dans la programmation. personnaliser pour les faire fonctionner avec des types particuliers. Par exemple,
avec un conteneur paramtr, le compilateur peut personnaliser ce conteneur de
faon ce qu'il n'accepte que des Formes et ne renvoie que des Formes.
Bibliothques de collections et support pour
l'utilisation aise des collections Les types paramtrs sont importants en C++, en particulier parce que le C++ ne
dispose pas d'une hirarchie de classe unique. En C++, le mot clef qui implmente
les types paramtrs est template . Java ne propose pas actuellement de types
Parce qu'un conteneur est un outil qu'on utilise frquemment, il est logique d'avoir paramtrs car c'est possible de les simuler - bien que difficilement - via la
une bibliothque de conteneurs conus de manire tre rutilisables, afin de hirarchie de classes unique. Une solution de types paramtrs base sur la syntaxe
pouvoir en prendre un et l'insrer dans le programme. Java fournit une telle des templates C++ est actuellement en cours de proposition.
bibliothque, qui devrait satisfaire tous les besoins.
Transtypages descendants vs. patrons gnriques
Le dilemme du nettoyage : qui en est
responsable ?
Pour rendre ces conteneurs rutilisables, ils stockent le type universel en Java
prcdemment mentionn : Object. La hirarchie de classe unique implique que Chaque objet requiert des ressources, en particulier de la mmoire. Quand un objet
tout est un Object, un conteneur stockant des Objects peut donc stocker n'importe n'est plus utilis il doit tre nettoy afin de rendre ces ressources pour les rutiliser.
quoi. Cela rend les conteneurs aisment rutilisables. Dans la programmation de situations simples, la question de savoir comment un
objet est libr n'est pas trop complique : il suffit de crer l'objet, l'utiliser aussi
Pour utiliser ces conteneurs, il suffit d'y ajouter des rfrences des objets, et les
longtemps que dsir, et ensuite le dtruire. Il n'est pas rare par contre de se trouver
redemander plus tard. Mais comme le conteneur ne stocke que des Objects, quand
dans des situations beaucoup plus complexes.
une rfrence un objet est ajoute dans le conteneur, il subit un transtypage
ascendant en Object, perdant alors son identit. Quand il est recherch par la suite, Supposons qu'on veuille concevoir un systme pour grer le trafic arien d'un
on rcupre une rfrence un Object, et non une rfrence au type qu'on a insr. aroport (ou pour grer des caisses dans un entrept, ou un systme de location de
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 31/459
cassettes, ou un chenil pour animaux). Cela semble simple de prime abord : crer un Les concepteurs du langage C++, en voulant amadouer les programmeurs C, ne
conteneur pour stocker les avions, puis crer un nouvel avion et le placer dans le voulurent pas ajouter de nouvelles fonctionnalits au langage qui puissent impacter
conteneur pour chaque avion qui entre dans la zone de contrle du trafic arien. la vitesse ou dfavoriser l'utilisation du C++ dans des situations o le C se serait
Pour le nettoyage, il suffit de dtruire l'objet avion correspondant lorsqu'un avion rvl acceptable. Cet objectif a t atteint, mais au prix d'une plus grande
quitte la zone. complexit lorsqu'on programme en C++. Java est plus simple que le C++, mais la
contrepartie en est l'efficacit et quelquefois son champ d'applications. Pour un
Mais supposons qu'une autre partie du systme s'occupe d'enregistrer des
grand nombre de problmes de programmation cependant, Java constitue le
informations propos des avions, ces donnes ne requrant pas autant d'attention
meilleur choix.
que la fonction principale de contrle. Il s'agit peut-tre d'enregistrer les plans de
vol de tous les petits avions quittant l'aroport. On dispose donc d'un second
conteneur des petits avions, et quand on cre un objet avion on doit aussi le stocker
dans le deuxime conteneur si c'est un petit avion. Une tche de fond s'occupe de
Traitement des exceptions : grer
traiter les objets de ce conteneur durant les moments d'inactivit du systme. les erreurs
Le problme est maintenant plus compliqu : comment savoir quand dtruire les
objets ? Quand on en a fini avec un objet, une autre partie du systme peut ne pas en Depuis les dbuts des langages de programmation, le traitement des erreurs s'est
avoir termin avec. Ce genre de problme arrive dans un grand nombre de rvl l'un des problmes les plus ardus. Parce qu'il est difficile de concevoir un bon
situations, et dans les systmes de programmation (comme le C++) o les objets mcanisme de gestion des erreurs, beaucoup de langages ignorent ce problme et le
doivent tre explicitement dtruits cela peut devenir relativement complexe. dlguent aux concepteurs de bibliothques qui fournissent des mcanismes qui
fonctionnent dans beaucoup de situations mais peuvent tre facilement contourns,
Avec Java, le ramasse-miettes est conu pour s'occuper du problme de la libration
gnralement en les ignorant. L'une des faiblesses de la plupart des mcanismes
de la mmoire (bien que cela n'inclut pas les autres aspects du nettoyage de l'objet).
d'erreur est qu'ils reposent sur la vigilance du programmeur suivre des
Le ramasse-miettes sait quand un objet n'est plus utilis, et il libre
conventions non imposes par le langage. Si le programmeur n'est pas assez vigilant
automatiquement la mmoire utilise par cet objet. Ceci (associ avec le fait que
- ce qui est souvent le cas s'il est press - ces mcanismes peuvent facilement tre
tous les objets sont drivs de la classe de base fondamentale Object et que les
oublis.
objets sont crs dans le segment) rend la programmation Java plus simple que la
programmation C++. Il y a beaucoup moins de dcisions prendre et d'obstacles Le systme des exceptions pour grer les erreurs se situe au niveau du langage de
surmonter. programmation et parfois mme au niveau du systme d'exploitation. Une exception
est un objet qui est mis depuis l'endroit o l'erreur est apparue et peut tre
Ramasse-miettes vs. efficacit et flexibilit intercept par un gestionnaire d'exception conu pour grer ce type particulier
d'erreur. C'est comme si la gestion des exceptions tait un chemin d'excution
parallle suivre quand les choses se gtent. Et parce qu'elle utilise un chemin
Si cette ide est si bonne, pourquoi le C++ n'intgre-t-il pas ce mcanisme ? Bien sr
d'excution spar, elle n'interfre pas avec le code s'excutant normalement. Cela
car il y a un prix payer pour cette facilit de programmation, et ce surcot se
rend le code plus simple crire car on n'a pas vrifier constamment si des erreurs
traduit par du temps systme. Comme on l'a vu, en C++ on peut crer des objets
sont survenues. De plus, une exception mise n'est pas comme une valeur de retour
dans la pile et dans ce cas ils sont automatiquement nettoys (mais dans ce cas on
d'une fonction signalant une erreur ou un drapeau positionn par une fonction pour
n'a pas la flexibilit de crer autant d'objets que voulu lors de l'excution). Crer des
indiquer une erreur - ils peuvent tre ignors. Une exception ne peut pas tre
objets dans la pile est la faon la plus efficace d'allouer de l'espace pour des objets et
ignore, on a donc l'assurance qu'elle sera traite quelque part. Enfin, les exceptions
de librer cet espace. Crer des objets dans le segment est bien plus coteux. Hriter
permettent de revenir d'une mauvaise situation assez facilement. Plutt que
de la mme classe de base et rendre tous les appels de fonctions polymorphes
terminer un programme, il est souvent possible de remettre les choses en place et de
prlvent aussi un tribut. Mais le ramasse-miettes est un problme part car on ne
restaurer son excution, ce qui produit des programmes plus robustes.
sait pas quand il va dmarrer ou combien de temps il va prendre. Cela veut dire qu'il
y a une inconsistance dans le temps d'excution de programmes Java ; on ne peut Le traitement des exceptions de Java se distingue parmi les langages de
donc l'utiliser dans certaines situations, comme celles o le temps d'excution d'un programmes, car en Java le traitement des exceptions a t intgr depuis le dbut
programme est critique (appels programmes en temps rel, bien que tous les et on est forc de l'utiliser. Si le code produit ne gre pas correctement les
problmes de programmation en temps rel ne soient pas aussi astreignants). exceptions, le compilateur gnrera des messages d'erreur. Cette consistance rend la
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 32/459
gestion des erreurs bien plus aise. quelqu'un d'autre puisse utiliser cette ressource.
Il est bon de noter que le traitement des exceptions n'est pas une caractristique #/TIJ_PAGE03# #TIJ_PAGE04#
oriente objet, bien que dans les langages OO une exception soit normalement
Le multithreading Java est intgr au langage, ce qui simplifie grandement ce sujet
reprsente par un objet. Le traitement des exceptions existait avant les langages
compliqu. Le multithreading est support au niveau de l'objet, donc un thread
orients objet.
d'excution est reprsent par un objet. Java fournit aussi des mcanismes limits
de verrouillage de ressources. Il peut verrouiller la mmoire de n'importe quel objet
Multithreading (qui n'est, aprs tout, qu'un type de ressource partage) de manire ce qu'un seul
thread puisse l'utiliser un moment donn. Ceci est ralis grce au mot
clef synchronized. D'autres types de ressources doivent tre verrouilles
L'un des concepts fondamentaux dans la programmation des ordinateurs est l'ide explicitement par le programmeur, typiquement en crant un objet qui reprsente
de traiter plus d'une tche la fois. Beaucoup de problmes requirent que le un verrou que tous les threads doivent vrifier avant d'accder cette ressource.
programme soit capable de stopper ce qu'il est en train de faire, traite un autre
problme puis retourne sa tche principale. Le problme a t abord de beaucoup
de manires diffrentes. Au dbut, les programmeurs ayant des connaissances sur le Persistance
fonctionnement de bas niveau de la machine crivaient des routines d'interruption
de service et l'interruption de la tche principale tait initie par une interruption
Quand un objet est cr, il existe aussi longtemps qu'on en a besoin, mais en aucun
matrielle. Bien que cela fonctionne correctement, c'tait difficile et non portable, et
cas il continue d'exister aprs que le programme se termine. Bien que cela semble
cela rendait le portage d'un programme sur un nouveau type de machine lent et
logique de prime abord, il existe des situations o il serait trs pratique si un objet
cher.
pouvait continuer d'exister et garder son information mme quand le programme ne
Quelquefois les interruptions sont ncessaires pour grer les tches critiques, mais il tourne plus. A l'excution suivante du programme, l'objet serait toujours l et il
existe une large classe de problmes dans lesquels on tente juste de partitionner le aurait la mme information dont il disposait dans la session prcdente. Bien sr,
problme en parties spares et indpendantes afin que le programme soit plus on peut obtenir ce comportement en crivant l'information dans un fichier ou une
ractif. Dans un programme, ces parties spares sont appels threads et le concept base de donnes, mais dans l'esprit du tout objet, il serait pratique d'tre capable de
gnral est appel multithreading. Un exemple classique de multithreading est dclarer un objet persistant et que tous les dtails soient pris en charge.
l'interface utilisateur. En utilisant les threads, un utilisateur peur appuyer sur un
Java fournit un support pour la persistance lgre , qui signifie qu'on peut
bouton et obtenir une rponse plus rapide que s'il devait attendre que le programme
facilement stocker des objets sur disque et les rcuprer plus tard. La raison pour
termine sa tche courante.
laquelle on parle de persistance lgre est qu'on est toujours oblig de faire des
Gnralement, les threads sont juste une faon d'allouer le temps d'un seul appels explicites pour le stockage et la rcupration. De plus, JavaSpaces (dcrit au
processeur. Mais si le systme d'exploitation supporte les multi-processeurs, chaque Chapitre 15) fournit un type de stockage persistant des objets. Un support plus
thread peut tre assign un processeur diffrent et ils peuvent rellement complet de la persistance peut tre amen apparatre dans de futures versions.
s'excuter en parallle. L'une des caractristiques intressantes du multithreading
au niveau du langage est que le programmeur n'a pas besoin de se proccuper du
nombre de processeurs. Le programme est divis logiquement en threads et si la Java et l'Internet
machine dispose de plusieurs processeurs, le programme tourne plus vite, sans
aucun ajustement. Java n'tant qu'un autre langage de programmation, on peut se demander pourquoi
Tout ceci pourrait faire croire que le multithreading est simple. Il y a toutefois un il est si important et pourquoi il est prsent comme une tape rvolutionnaire de la
point d'achoppement : les ressources partages. Un problme se pose si plus d'un programmation. La rponse n'est pas immdiate si on se place du point de vue de la
thread s'excutant veulent accder la mme ressource. Par exemple, deux tches programmation classique. Bien que Java soit trs pratique pour rsoudre des
ne peuvent envoyer simultanment de l'information une imprimante. Pour problmes traditionnels, il est aussi important car il permet de rsoudre des
rsoudre ce problme, les ressources pouvant tre partages, comme l'imprimante, problmes lis au web.
doivent tre verrouilles avant d'tre utilises. Un thread verrouille donc une
ressource, accomplit ce qu'il a faire, et ensuite relche le verrou pos afin que
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 33/459
Qu'est-ce que le Web ? L'ide relativement simple de distribuer de l'information aux gens a de si nombreux
niveaux de complexit dans son implmentation que le problme peut sembler
dsesprment insoluble. Et pourtant il est crucial : le client/serveur compte pour
Le Web peut sembler un peu mystrieux au dbut, avec tout ce vocabulaire de environ la moiti des activits de programmation. On le retrouve pour tout ce qui va
surf , pages personnelles , etc... Il y a mme eu une raction importante contre des transactions de cartes de crdit la distribution de n'importe quel type de
cette Internet-mania , se questionnant sur la valeur conomique et les revenus donnes - conomique, scientifique, gouvernementale, il suffit de choisir. Dans le
d'un tel engouement. Il peut tre utile de revenir en arrire et voir de quoi il pass, on en est arriv des solutions particulires aux problmes particuliers,
retourne, mais auparavant il faut comprendre le modle client/serveur, un autre obligeant rinventer une solution chaque fois. Elles taient difficiles crer et
aspect de l'informatique relativement confus. utiliser, et l'utilisateur devait apprendre une nouvelle interface pour chacune. Le
problme devait tre repris dans son ensemble.
Le concept Client/Serveur
Le Web en tant que serveur gant
L'ide primitive d'un systme client/serveur est qu'on dispose d'un dpt
centralis de l'information - souvent dans une base de donnes - qu'on Le Web est en fait un systme client/serveur gant. C'est encore pire que a, puisque
veut distribuer un ensemble de personnes ou de machines. L'un des tous les serveurs et les clients coexistent en mme temps sur un seul rseau. Vous
concepts majeurs du client/serveur est que le dpt d'informations est n'avez pas besoin de le savoir d'ailleurs, car tout ce dont vous vous souciez est de
centralis afin qu'elles puissent tre changes facilement et que ces vous connecter et d'interagir avec un serveur la fois (mme si vous devez parcourir
changements se propagent jusqu'aux consommateurs de ces le monde pour trouver le bon serveur).
informations. Pris ensemble, le dpt d'informations, le programme qui
Initialement, c'tait un processus une tape. On faisait une requte un serveur
distribue l'information et la (les) machine(s) o rsident informations et
qui renvoyait un fichier, que le logiciel (ie, le client) interprtait en le formatant sur
programme sont appels le serveur. Le programme qui rside sur la la machine locale. Mais les gens en voulurent plus : afficher des pages d'un serveur
machine distante, communique avec le serveur, rcupre l'information, ne leur suffisait plus. Ils voulaient bnficier de toutes les fonctionnalits du
la traite et l'affiche sur la machine distante est appel le client. client/serveur afin que le client puisse renvoyer des informations au serveur, par
Le concept de base du client/serveur n'est donc pas si compliqu. Les problmes exemple pour faire des requtes prcises dans la base de donnes, ajouter de
surviennent car un seul serveur doit servir de nombreux clients la fois. nouvelles informations au serveur, ou passer des commandes (ce qui ncessitait plus
Gnralement, un systme de gestion de base de donnes est impliqu afin que le de scurit que ce que le systme primitif offrait). Nous assistons ces changements
concepteur rpartisse les informations dans des tables pour une utilisation optimale. dans le dveloppement du Web.
De plus, les systmes permettent gnralement aux utilisateurs d'ajouter de Le navigateur Web fut un grand bond en avant en avanant le concept qu'une
nouvelles informations au serveur. Cela veut dire qu'ils doivent s'assurer que les information pouvait tre affiche indiffremment sur n'importe quel ordinateur.
nouvelles donnes d'un client ne contredisent pas les nouvelles donnes d'un autre Cependant, les browsers taient relativement primitifs et ne remplissaient pas
client, ou que ces nouvelles donnes ne soient pas perdues pendant leur inscription toutes les demandes des utilisateurs. Ils n'taient pas particulirement interactifs, et
dans la base de donnes (cela fait appel aux transactions). Comme les programmes avaient tendance saturer le serveur et l'Internet car chaque fois qu'on avait
d'application client changent, ils doivent tre crs, dbuggus, et installs sur les besoin de faire quelque chose qui requrait un traitement il fallait renvoyer les
machines clientes, ce qui se rvle plus compliqu et onreux que ce quoi on informations au serveur pour que celui-ci les traite. Cela pouvait prendre plusieurs
pourrait s'attendre. C'est particulirement problmatique dans les environnements secondes ou minutes pour finalement se rendre compte qu'on avait fait une faute de
htrognes comprenant diffrents types de matriels et de systmes d'exploitation. frappe dans la requte. Comme le browser n'tait qu'un afficheur, il ne pouvait pas
Enfin, se pose toujours le problme des performances : on peut se retrouver avec des effectuer le moindre traitement (d'un autre ct, cela tait beaucoup plus sr, car il
centaines de clients excutant des requtes en mme temps, et donc un petit dlai ne pouvait pas de ce fait excuter sur la machine locale de programmes contenant
multipli par le nombre de clients peut tre particulirement pnalisant. Pour des bugs ou des virus).
minimiser les temps de latence, les programmeurs travaillent dur pour rduire la
charge de travail des tches incrimines, parfois jusque sur les machines clientes, Pour rsoudre ce problme, diffrentes solutions ont t approches. En
mais aussi sur d'autres machines du site serveur, utilisant ce qu'on appelle le commenant par les standards graphiques qui ont t amliors pour mettre des
middleware (le middleware est aussi utilis pour amliorer la maintenabilit). animations et de la vido dans les browsers. Le reste du problme ne peut tre
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 34/459
rsolu qu'en incorporant la possibilit d'excuter des programmes sur le client, dans capable de traiter, avec comme rsultat pour l'utilisateur une interactivit et une
le browser. C'est ce qu'on appelle la programmation ct client. vitesse ingales.
Les problmes de la programmation ct client ne sont gure diffrents des
La programmation ct client discussions de la programmation en gnral. Les paramtres sont quasiment les
mmes, mais la plateforme est diffrente : un browser Web est comme un systme
Le concept initial du Web (serveur-browser) fournissait un contenu interactif, mais d'exploitation limit. Au final, on est toujours oblig de programmer, et ceci
l'interactivit tait uniquement le fait du serveur. Le serveur produisait des pages explique le nombre de problmes rencontrs dans la programmation ct client. Le
statiques pour le browser client, qui ne faisait que les interprter et les afficher. Le reste de cette section prsente les diffrentes approches de la programmation ct
HTML de base contient des mcanismes simples pour rcuprer de l'information : client.
des botes de texte, des cases cocher, des listes options et des listes de choix, ainsi
qu'un bouton permettant de rinitialiser le contenu du formulaire ou d'envoyer les Les plugins (modules d'extension)
donnes du formulaire au serveur. Cette soumission de donnes passe par CGI
(Common Gateway Interface), un mcanisme fourni par tous les serveurs web. Le L'une des plus importantes avances en terme de programmation oriente client a
texte de la soumission indique CGI quoi faire avec ces donnes. L'action la plus t le dveloppement du plug-in. C'est une faon pour le programmeur d'ajouter de
commune consiste excuter un programme situ sur le serveur dans un rpertoire nouvelles fonctionnalits au browser en tlchargeant une partie de logiciel qui
typiquement appel cgi-bin (si vous regardez l'adresse en haut de votre browser s'enfiche l'endroit adquat dans le browser. Il indique au browser : partir de
quand vous appuyez sur un bouton dans une page web, vous verrez certainement maintenant tu peux raliser cette nouvelle opration (on n'a besoin de tlcharger
cgi-bin quelque part au milieu de tous les caractres). Ces programmes peuvent le plug-in qu'une seule fois). De nouveaux comportements puissants sont donc
tre crits dans la plupart des langages. Perl est souvent prfr car il a t conu ajouts au browser via les plug-ins, mais crire un plug-in n'est pas une tche facile,
pour la manipulation de texte et est interprt, et peut donc tre install sur et ce n'est pas quelque chose qu'on souhaiterait faire juste pour btir un site Web
n'importe quel serveur sans tenir compte du matriel ou du systme d'exploitation. particulier. La valeur d'un plug-in pour la programmation ct client est qu'il
Beaucoup de sites Web populaires sont aujourd'hui btis strictement sur CGI, et de permet un programmeur expriment de dvelopper un nouveau langage et
fait on peut faire ce qu'on veut avec. Cependant, les sites web btis sur des d'intgrer ce langage au browser sans la permission du distributeur du browser.
programmes CGI peuvent rapidement devenir ingrables et trop compliqus Ainsi, les plug-ins fournissent une porte drobe qui permet la cration de
maintenir, et se pose de plus le problme du temps de rponse. La rponse d'un nouveaux langages de programmation ct client (bien que tous les langages ne
programme CGI dpend de la quantit de donnes envoyer, ainsi que de la charge soient pas implments en tant que plug-ins).
du serveur et de l'Internet (de plus, le dmarrage d'un programme CGI a tendance
tre long). Les concepteurs du Web n'avaient pas prvu que la bande passante serait Les langages de script
trop petite pour le type d'applications que les gens dvelopprent. Par exemple, tout
type de graphisme dynamique est impossible raliser correctement car un fichier Les plug-ins ont dclench une explosion de langages de script. Avec un langage de
GIF doit tre cr et transfr du serveur au client pour chaque version de ce graphe. script, du code source est intgr directement dans la page HTML, et le plug-in qui
Et vous avez certainement dj fait l'exprience de quelque chose d'aussi simple que interprte ce langage est automatiquement activ quand le page HTML est affiche.
la validation de donnes sur un formulaire. Vous appuyez sur le bouton submit Les langages de script tendent tre relativement aiss comprendre ; et parce
d'une page, les donnes sont envoyes sur le serveur, le serveur dmarre le qu'ils sont du texte faisant partie de la page HTML, ils se chargent trs rapidement
programme CGI qui y dcouvre une erreur, formate une page HTML vous informant dans la mme requte ncessaire pour se procurer la page auprs du serveur. La
de votre erreur et vous la renvoie ; vous devez alors revenir en arrire d'une page et contrepartie en est que le code est visible pour tout le monde (qui peut donc le
ressayer. Non seulement c'est lent et frustrant, mais c'est inlgant. voler). Mais gnralement on ne fait pas des choses extraordinairement
La solution est la programmation ct client. La plupart des machines qui font sophistiques avec les langages de script et ce n'est donc pas trop pnalisant.
tourner des browsers Web sont des ordinateurs puissants capables de beaucoup de Ceci montre que les langages de script utiliss dans les browsers Web sont vraiment
choses, et avec l'approche originale du HTML statique, elles ne font qu'attendre que spcifiques certains types de problmes, principalement la cration d'interfaces
le serveur leur envoie parcimonieusement la page suivante. La programmation ct utilisateurs plus riches et attrayantes. Cependant, un langage de script permet de
client implique que le browser Web prenne en charge la partie du travail qu'il est rsoudre 80 pour cent des problmes rencontrs dans la programmation ct client.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 35/459
La plupart de vos problmes devraient se trouver parmi ces 80 pour cent, et puisque requte comportant une erreur dans une date ou utilisant un mauvais paramtre n'a
les langages de script sont plus faciles mettre en oeuvre et permettent un plus besoin d'tre envoye sur Internet pour se voir refuse par le serveur ; un client
dveloppement plus rapide, vous devriez d'abord vrifier si un langage de script ne peut trs bien aussi s'occuper de grer l'affichage d'un nouveau point sur un graphe
vous suffirait pas avant de vous lancer dans une solution plus complexe telle que la plutt que d'attendre que le serveur ne s'en occupe, cre une nouvelle image et
programmation Java ou ActiveX. l'envoie au client. On gagne ainsi non seulement en vitesse et confort d'utilisation,
mais le trafic engendr sur le rseau et la charge rsultante sur les serveurs peut tre
Les langages de script les plus rpandus parmi les browsers sont JavaScript (qui n'a
rduite, ce qui est bnfique pour l'Internet dans son ensemble.
rien voir avec Java ; le nom a t choisi uniquement pour bnficier de
l'engouement marketing pour Java du moment), VBScript (qui ressemble Visual L'un des avantages qu'une applet Java a sur un programme crit dans un langage de
Basic), et Tcl/Tk, qui vient du fameux langage de construction d'interfaces script est qu'il est fourni sous une forme prcompile, et donc le code source n'est
graphiques. Il y en a d'autres bien sr, et sans doute encore plus en dveloppement. pas disponible pour le client. D'un autre ct, une applet Java peut tre
rtroingnire sans trop de problmes, mais cacher son code n'est pas souvent une
JavaScript est certainement le plus commun d'entre eux. Il est prsent ds l'origine
priorit absolue. Deux autres facteurs peuvent tre importants. Comme vous le
dans Netscape Navigator et Microsoft Internet Explorer (IE). De plus, il y a
verrez plus tard dans ce livre, une applet Java compile peut comprendre plusieurs
certainement plus de livres disponibles sur JavaScript que sur les autres langages, et
modules et ncessiter plusieurs accs au serveur pour tre tlcharge ( partir de
certains outils crent automatiquement des pages utilisant JavaScript. Cependant, si
Java 1.1 cela est minimis par les archives Java ou fichiers JAR, qui permettent de
vous parlez couramment Visual Basic ou Tcl/Tk, vous serez certainement plus
paqueter tous les modules requis ensemble dans un format compress pour un
productif en utilisant ces langages qu'en en apprenant un nouveau (vous aurez dj
tlchargement unique). Un programme script sera juste insr dans le texte de la
largement de quoi faire avec les problmes soulevs par le Web).
page Web (et sera gnralement plus petit et rduira le nombre d'accs au serveur).
Cela peut tre important pour votre site Web. Un autre facteur prendre en compte
Java est la courbe d'apprentissage. Indpendamment de tout ce que vous avez pu
entendre, Java n'est pas un langage trivial et facile apprendre. Si vous avez
Si un langage de script peut rsoudre 80 pour cent des problmes de la l'habitude de programmer en Visual Basic, passer VBScript sera beaucoup plus
programmation ct client, qu'en est-il des 20 pour cent restants ? La solution la rapide et comme cela permet de rsoudre la majorit des problmes typiques du
plus populaire aujourd'hui est Java. C'est non seulement un langage de client/serveur, il pourrait tre difficile de justifier l'investissement de l'apprentissage
programmation puissant conu pour tre sur, interplateformes et international, de Java. Si vous tes familier avec un langage de script, vous serez certainement
mais Java est continuellement tendu pour fournir un langage proposant des gagnant en vous tournant vers JavaScript ou VBScript avant Java, car ils peuvent
caractristiques et des bibliothques permettant de grer de manire lgante des certainement combler vos besoins et vous serez plus productif plus tt.
problmes traditionnellement complexes dans les langages de programmation
classiques, tels que le multithreading, les accs aux bases de donnes, la ActiveX
programmation rseau, l'informatique rpartie Java permet la programmation ct
client via les applets.
A un certain degr, le comptiteur de Java est ActiveX de Microsoft, bien qu'il
Une applet est un mini-programme qui ne tourne que dans un browser Web. s'appuie sur une approche radicalement diffrente. ActiveX tait au dpart une
L'applet est tlcharge automatiquement en temps que partie d'une page Web solution disponible uniquement sur Windows, bien qu'il soit actuellement dvelopp
(comme, par exemple, une image est automatiquement tlcharge). Quand l'applet par un consortium indpendant pour devenir interplateformes. Le concept
est active elle excute un programme. L se trouve la beaut de la chose : cela vous d'ActiveX clame : si votre programme se connecte son environnement de cette
permet de distribuer le logiciel client partir du serveur au moment o l'utilisateur faon, il peut tre insr dans une page Web et excut par un browser qui supporte
en a besoin et pas avant. L'utilisateur rcupre toujours la dernire version en date ActiveX (IE supporte ActiveX en natif et Netscape utilise un plug-in). Ainsi,
du logiciel et sans avoir besoin de le rinstaller. De par la conception mme de Java, ActiveX ne vous restreint pas un langage particulier. Si par exemple vous tes un
le programmeur n'a besoin de crer qu'un seul programme, et ce programme programmeur Windows expriment utilisant un langage tel que le C++, Visual
tournera automatiquement sur tous les browsers disposant d'un interprteur Basic ou Delphi de Borland, vous pouvez crer des composants ActiveX sans avoir
interne (ce qui inclut la grande majorit des machines). Puisque Java est un langage tout rapprendre. ActiveX fournit aussi un mcanisme pour la rutilisation de code
de programmation complet, on peut dporter une grande partie des traitements sur dans les pages Web.
le client avant et aprs avoir envoy les requtes au serveur. Par exemple, une
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 36/459
La scurit une clef publique pour vrifier qu'une applet provient bien de l o elle dit venir.
Une applet signe peut toujours endommager vos donnes et votre ordinateur, mais
on en revient la thorie selon laquelle la perte de l'anonymat rend le crateur de
Le tlchargement automatique et l'excution de programmes sur Internet
l'applet responsable de ses actes, il ne fera donc rien de prjudiciable. Java fournit
ressemble au rve d'un concepteur de virus. ActiveX en particulier pose la question
un environnement pour les signatures digitales afin de permettre une applet de
pineuse de la scurit dans la programmation ct client. Un simple click sur un
sortir du primtre de scurit si besoin est.
site Web peut dclencher le tlchargement d'un certain nombre de fichiers en
mme temps que la page HTML : des images, du code script, du code Java compil, Les signatures digitales ont toutefois oubli un paramtre important, qui est la
et des composants ActiveX. Certains d'entre eux sont sans importance : les images vitesse laquelle les gens bougent sur Internet. Si on tlcharge un programme
ne peuvent causer de dommages, et les langages de script sont gnralement limits buggu et qu'il accomplisse ses mfaits, combien de temps se passera-t-il avant que
dans les oprations qu'ils sont capables de faire. Java a t conu pour excuter ses les dommages ne soient dcouverts ? Cela peut se compter en jours ou en semaines.
applets l'intrieur d'un primtre de scurit (appel bac sable), qui l'empche Et alors, comment retrouver le programme qui les a causs ? Et en quoi cela vous
d'aller crire sur le disque ou d'accder la mmoire en dehors de ce primtre de aidera ce point ?
scurit.
#/TIJ_PAGE04# #TIJ_PAGE05#
ActiveX se trouve l'oppos du spectre. Programmer avec ActiveX est comme
programmer sous Windows - on peut faire ce qu'on veut. Donc un composant Internet vs. intranet
ActiveX tlcharg en mme temps qu'une page Web peut causer bien des dgts
aux fichiers du disque. Bien sr, les programmes tlchargs et excuts en dehors
du browser prsentent les mmes risques. Les virus tlchargs depuis les BBS ont Le Web est la solution la plus gnrique au problme du client/serveur, il est donc
pendant longtemps t un problme, mais la vitesse obtenue sur Internet accrot logique de vouloir appliquer la mme technologie pour rsoudre ceux lis aux
client/serveur l'intrieur d'une entreprise. Avec l'approche traditionnelle du
encore les difficults.
client/serveur se pose le problme de l'htrognit du parc de clients, de mme
La solution semble tre les signatures digitales , o le code est vrifi pour que les difficults pour installer les nouveaux logiciels clients. Ces problmes sont
montrer qui est l'auteur. L'ide est base sur le fait qu'un virus se propage parce que rsolus par les browsers Web et la programmation ct client. Quand la technologie
son concepteur peut rester anonyme, et si cet anonymat lui est retir, l'individu du Web est utilise dans le systme d'information d'une entreprise, on s'y rfre en
devient responsable de ses actions. Mais si le programme contient un bug fatal bien tant qu'intranet. Les intranets fournissent une plus grande scurit qu'Internet
que non intentionnel cela pose toujours problme. puisqu'on peut contrler les accs physiques aux serveurs l'intrieur de
l'entreprise. En terme d'apprentissage, il semblerait qu'une fois que les utilisateurs
L'approche de Java est de prvenir ces problmes via le primtre de scurit.
se sont familiariss avec le concept d'un browser il leur est plus facile de grer les
L'interprteur Java du browser Web examine l'applet pendant son chargement pour
diffrences de conception entre les pages et applets, et le cot d'apprentissage de
y dtecter les instructions interdites. En particulier, les applets ne peuvent crire sur
nouveaux systmes semble se rduire.
le disque ou effacer des fichiers (ce que font la plupart des virus). Les applets sont
gnralement considres comme sres ; et comme ceci est essentiel pour bnficier Le problme de la scurit nous mne l'une des divisions qui semble se former
d'un systme client/serveur fiable, les bugs dcouverts dans Java permettant la automatiquement dans le monde de la programmation ct client. Si un programme
cration de virus sont trs rapidement corrigs (il est bon de noter que le browser est distribu sur Internet, on ne sait pas sur quelle plateforme il va tourner et il faut
renforce ces restrictions de scurit, et que certains d'entre eux permettent de tre particulirement vigilant pour ne pas diffuser du code buggu. Il faut une
slectionner diffrents niveaux de scurit afin de permettre diffrents niveaux solution multiplateformes et sre, comme un langage de script ou Java.
d'accs au systme).
Dans le cas d'un intranet, les contraintes peuvent tre compltement diffrentes. Le
On pourrait s'interroger sur cette restriction draconienne contre les accs en temps pass installer les nouvelles versions est la raison principale qui pousse
criture sur le disque local. Par exemple, on pourrait vouloir construire une base de passer aux browsers, car les mises jours sont invisibles et automatiques. Il n'est
donnes locale ou sauvegarder des donnes pour un usage futur en mode pas rare que tous les clients soient des plateformes Wintel (Intel / Windows). Dans
dconnect. La vision initiale obligeait tout le monde se connecter pour raliser la un intranet, on est responsable de la qualit du code produit et on peut corriger les
moindre opration, mais on s'est vite rendu compte que cela tait impraticable. La bugs quand ils sont dcouverts. De plus, on dispose du code utilis dans une
solution a t trouve avec les applets signes qui utilisent le chiffrement avec approche plus traditionnelle du client/serveur o il fallait installer physiquement le
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 37/459
client chaque mise jour du logiciel. Dans le cas d'un tel intranet, l'approche la applications qui s'excutent sans le soutien d'un browser, comme n'importe quel
plus raisonnable consiste choisir la solution qui permettra de rutiliser le code programme. Les atouts de Java sont l encore non seulement sa portabilit, mais
existant plutt que de repartir de zro dans un nouveau langage. aussi sa facilit de programmation. Comme vous allez le voir tout au long de ce livre,
Java possde beaucoup de fonctionnalits qui permettent de crer des programmes
Quand on est confront au problme de la programmation ct client, la meilleure
robustes dans un laps de temps plus court qu'avec d'autres langages de
chose faire est une analyse cots-bnfices. Il faut prendre en compte les
programmation.
contraintes du problme, et la solution qui serait la plus rapide mettre en oeuvre.
En effet, comme la programmation ct client reste de la programmation, c'est Mais il faut bien tre conscient qu'il s'agit d'un compromis. Le prix payer pour ces
toujours une bonne ide de choisir l'approche permettant un dveloppement rapide. amliorations est une vitesse d'excution rduite (bien que des efforts significatifs
soient mis en oeuvre dans ce domaine - JDK 1.3, en particulier, introduit le concept
d'amlioration de performances hotspot ). Comme tout langage de
La programmation ct serveur programmation, Java a des limitations internes qui peuvent le rendre inadquat
pour rsoudre certains types de problmes. Java volue rapidement cependant, et
Toute cette discussion a pass sous silence la programmation ct serveur. Que se chaque nouvelle version il permet d'adresser un spectre de plus en plus large de
passe-t-il lorsqu'un serveur reoit une requte ? La plupart du temps cette requte problmes.
est simplement envoie-moi ce fichier . Le browser interprte alors ce fichier d'une
manire particulire : comme une page HTML, une image graphique, une applet
Java, un programme script, etc... Une requte plus complique un serveur Analyse et conception
implique gnralement une transaction vers une base de donnes. Un scnario
classique consiste en une requte complexe de recherche d'enregistrements dans Le paradigme de la POO constitue une approche nouvelle et diffrente de la
une base de donnes que le serveur formate dans une page HTML et renvoie comme programmation. Beaucoup de personnes rencontrent des difficults pour
rsultat (bien sr, si le client est intelligent via Java ou un langage de script, la apprhender leur premier projet orient objet. Une fois compris que tout est
phase de formatage peut tre ralise par le client et le serveur n'aura qu'a envoyer suppos tre un objet, et au fur et mesure qu'on se met penser dans un style plus
les donnes brutes, ce qui allgera la charge et le trafic engendr). Ou alors un client orient objet, on commence crer de bonnes conceptions qui s'appuient sur
peut vouloir s'enregistrer dans une base de donnes quand il joint un groupe ou tous les avantages que la POO offre.
envoie une commande, ce qui implique des changements dans la base de donnes.
Ces requtes doivent tre traites par du code s'excutant sur le serveur, c'est ce Une mthode (ou mthodologie) est un ensemble de processus et d'heuristiques
qu'on appelle la programmation ct serveur. Traditionnellement, la utiliss pour rduire la complexit d'un problme. Beaucoup de mthodes orientes
programmation ct serveur s'est appuye sur Perl et les scripts CGI, mais des objet ont t formules depuis l'apparition de la POO. Cette section vous donne un
systmes plus sophistiqus sont en train de voir le jour. Cela inclut des serveurs Web aperu de ce que vous essayez d'accomplir en utilisant une mthode.
crits en Java qui permettent de raliser toute la programmation ct serveur en
Une mthodologie s'appuie sur un certain nombre d'expriences, il est donc
Java en crivant ce qu'on appelle des servlets. Les servlets et leur progniture, les
important de comprendre quel problme la mthode tente de rsoudre avant d'en
JSPs, sont les deux raisons principales qui poussent les entreprises qui dveloppent
adopter une. Ceci est particulirement vrai avec Java, qui a t conu pour rduire la
un site Web se tourner vers Java, en particulier parce qu'ils liminent les
complexit (compar au C) dans l'expression d'un programme. Cette philosophie
problmes lis aux diffrences de capacit des browsers.
supprime le besoin de mthodologies toujours plus complexes. Des mthodologies
simples peuvent se rvler tout fait suffisantes avec Java pour une classe de
Une scne spare : les applications problmes plus large que ce qu'elles ne pourraient traiter avec des langages
procduraux.
La plupart de la publicit faite autour de Java se rfrait aux applets. Mais Java est Il est important de raliser que le terme > mthodologie est trompeur et promet
aussi un langage de programmation vocation plus gnrale qui peut rsoudre trop de choses. Tout ce qui est mis en oeuvre quand on conoit et ralise un
n'importe quel type de problme - du moins en thorie. Et comme prcis plus haut, programme est une mthode. Ca peut tre une mthode personnelle, et on peut ne
il peut y avoir des moyens plus efficaces de rsoudre la plupart des problmes pas en tre conscient, mais c'est une dmarche qu'on suit au fur et mesure de
client/serveur. Quand on quitte la scne des applets (et les restrictions qui y sont l'avancement du projet. Si cette mthode est efficace, elle ne ncessitera sans doute
lies telles que les accs en criture sur le disque), on entre dans le monde des que quelques petites adaptations pour fonctionner avec Java. Si vous n'tes pas
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 38/459
satisfait de votre productivit ou du rsultat obtenu, vous serez peut-tre tent dans des classes, on aura invitablement produit durant la premire passe quelques
d'adopter une mthode plus formelle, ou d'en composer une partir de plusieurs classes qui valent la peine d'tre conserves et dvelopp des ides sur la conception
mthodes formelles. du systme. Ainsi, une premire passe rapide sur un problme non seulement
fournit des informations critiques pour la prochaine passe d'analyse, de conception
Au fur et mesure que le projet avance, le plus important est de ne pas se perdre, ce
et d'implmentation, mais elle produit aussi une base du code.
qui est malheureusement trs facile. La plupart des mthodes d'analyse et de
conception sont conues pour rsoudre mme les problmes les plus gros. Il faut Ceci dit, si on cherche une mthode qui contient de nombreux dtails et suggre de
donc bien tre conscient que la plupart des projets ne rentrant pas dans cette nombreuses tapes et documents, il est toujours difficile de savoir o s'arrter. Il
catgorie, on peut arriver une bonne analyse et conception avec juste une petite faut garder l'esprit ce qu'on essaye de dcouvrir :
partie de ce qu'une mthode recommande [8]. Une mthode de conception, mme
1. Quels sont les objets ? (Comment partitionner le projet en ses composants
limite, met sur la voie bien mieux que si on commence coder directement.
lmentaires ?)
Il est aussi facile de rester coinc et tomber dans la paralysie analytique o on se 2. Quelles en sont leur interface ? (Quels sont les messages qu'on a
dit qu'on ne peut passer la phase suivante car on n'a pas traqu le moindre petit besoin d'envoyer chaque objet ?)
dtail de la phase courante. Il faut bien se dire que quelle que soit la profondeur de
l'analyse, certains aspects d'un problme ne se rvleront qu'en phase de Si on arrive trouver quels sont les objets et leur interface, alors on peut
conception, et d'autres en phase de ralisation, voire mme pas avant que le commencer coder. On pourra avoir besoin d'autres descriptions et documents,
programme ne soit achev et excut. A cause de ceci, il est crucial d'avancer mais on ne peut pas faire avec moins que a.
relativement rapidement dans l'analyse et la conception, et d'implmenter un test Le dveloppement peut tre dcompos en cinq phases, et une Phase 0 qui est juste
du systme propos. l'engagement initial respecter une structure de base.
Il est bon de dvelopper un peu ce point. A cause des dboires rencontrs avec les
langages procduraux, il est louable qu'une quipe veuille avancer avec prcautions Phase 0 : Faire un plan
et comprendre tous les dtails avant de passer la conception et l'implmentation. Il
est certain que lors de la cration d'une base de donnes, il est capital de Il faut d'abord dcider quelles tapes on va suivre dans le dveloppement. Cela
comprendre fond les besoins du client. Mais la conception d'une base de donnes semble simple (en fait, tout semble simple), et malgr tout les gens ne prennent
fait partie d'une classe de problmes bien dfinie et bien comprise ; dans ce genre de cette dcision qu'aprs avoir commenc coder. Si le plan se rsume retroussons
programmes, la structure de la base de donnes est le problme rsoudre. Les nos manches et codons , alors a ne pose pas de problmes (quelquefois c'est une
problmes traits dans ce chapitre font partie de la classe de problmes joker approche valable quand on a affaire un problme bien connu). Mais il faut
(invention personnelle), dans laquelle la solution n'est pas une simple nanmoins accepter que c'est le plan.
reformulation d'une solution dj prouve de nombreuses fois, mais implique un
ou plusieurs facteurs joker - des lments pour lesquels il n'existe aucune On peut aussi dcider dans cette phase qu'une structure additionnelle est ncessaire.
solution prtablie connue, et qui ncessitent de pousser les recherches [9]. Tenter Certains programmeurs aiment travailler en mode vacances , sans structure
d'analyser fond un problme joker avant de passer la conception et impose sur le processus de dveloppement de leur travail : Ce sera fait lorsque ce
l'implmentation mne la paralysie analytique parce qu'on ne dispose pas d'assez sera fait . Cela peut tre sduisant un moment, mais disposer de quelques jalons
d'informations pour rsoudre ce type de problmes durant la phase d'analyse. aide se concentrer et focalise les efforts sur ces jalons au lieu d'tre obnubil par le
Rsoudre ce genre de problmes requiert de rpter le cycle complet, et cela but unique de finir le projet . De plus, cela divise le projet en parties plus petites,
demande de prendre certains risques (ce qui est sens, car on essaie de faire quelque ce qui le rend moins redoutable (sans compter que les jalons offrent des
chose de nouveau et les revenus potentiels en sont plus levs). On pourrait croire opportunits de fte).
que le risque est augment par cette rue vers une premire implmentation, mais
Quand j'ai commenc tudier la structure des histoires (afin de pouvoir un jour
elle peut rduire le risque dans un projet joker car on peut tout de suite se rendre
crire un roman), j'tais rticent au dbut l'ide de structure, trouvant que
compte si telle approche du problme est viable ou non. Le dveloppement d'un
j'crivais mieux quand je laissais juste la plume courir sur le papier. Mais j'ai ralis
produit s'apparente de la gestion de risque.
plus tard que quand j'cris propos des ordinateurs, la structure est suffisamment
Souvent cela se traduit par construire un prototype qu'il va falloir jeter . Avec la claire pour moi pour que je n'ai pas besoin de trop y rflchir. Mais je structure tout
POO, on peut encore avoir en jeter une partie, mais comme le code est encapsul de mme mon travail, bien que ce soit inconsciemment dans ma tte. Mme si on
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 39/459
pense que le plan est juste de commencer coder, on passe tout de mme par les Cela permet d'impliquer tous les acteurs du projet, et encourage la participation de
phases successives en se posant certaines questions et en y rpondant. toute l'quipe. Plus important encore, cela permet de lancer un projet dans
l'enthousiasme.
L'expos de la mission Il est ncessaire de rester concentr sur ce qu'on essaye d'accomplir dans cette
phase : dterminer ce que le systme est suppos faire. L'outil le plus utile pour cela
Tout systme qu'on construit, quelle que soit sa complexit, a un but, un besoin est une collection de ce qu'on appelle cas d'utilisation . Les cas d'utilisation
fondamental qu'il satisfait. Si on peut voir au del de l'interface utilisateur, des identifient les caractristiques clefs du systme qui vont rvler certaines des classes
dtails spcifiques au matriel - ou au systme -, des algorithmes de codage et des fondamentales qu'on utilisera. Ce sont essentiellement des rponses descriptives
problmes d'efficacit, on arrive finalement au coeur du problme - simple et nu. des questions comme[10] :
Comme le soi-disant concept fondamental d'un film hollywoodien, on peut le
Qui utilisera le systme ?
dcrire en une ou deux phrases. Cette description pure est le point de dpart.
Que peuvent faire ces personnes avec le systme ?
Le concept fondamental est assez important car il donne le ton du projet ; c'est Comment tel acteur fait-il cela avec le systme ?
l'expos de la mission. Ce ne sera pas ncessairement le premier jet qui sera le bon Comment cela pourrait-il fonctionner si quelqu'un d'autre faisait cela, ou
(on peut tre dans une phase ultrieure du projet avant qu'il ne soit compltement si le mme acteur avait un objectif diffrent ? (pour trouver les variations)
clair), mais il faut continuer d'essayer jusqu' ce que a sonne bien. Par exemple, Quels problmes peuvent apparatre quand on fait cela avec le systme ?
dans un systme de contrle de trafic arien, on peut commencer avec un concept (pour trouver les exceptions)
fondamental bas sur le systme qu'on construit : Le programme tour de contrle
garde la trace d'un avion . Mais cela n'est plus valable quand le systme se rduit Si on conoit un guichet automatique, par exemple, le cas d'utilisation pour un
un petit arodrome, avec un seul contrleur, ou mme aucun. Un modle plus utile aspect particulier des fonctionnalits du systme est capable de dcrire ce que le
ne dcrira pas tant la solution qu'on cre que le problme : Des avions arrivent, guichet fait dans chaque situation possible. Chacune de ces situations est appele
dchargent, partent en rvision, rechargent et repartent . un scnario, et un cas d'utilisation peut tre considr comme une collection de
scnarios. On peut penser un scnario comme une question qui commence par
Qu'est-ce que le systme fait si... ? . Par exemple, Qu'est que le guichet fait si un
Phase 1 : Que construit-on ? client vient de dposer un chque dans les dernires 24 heures, et qu'il n'y a pas
assez dans le compte sans que le chque soit encaiss pour fournir le retrait
Dans la gnration prcdente de conception de programmes (conception demand ? .
procdurale), cela s'appelait l'analyse des besoins et les spcifications du systme
Les diagrammes de cas d'utilisations sont voulus simples pour ne pas se perdre
. C'taient des endroits o on se perdait facilement, avec des documents au nom
prmaturment dans les dtails de l'implmentation du systme :
intimidant qui pouvaient occulter le projet. Leurs intentions taient bonnes,
pourtant. L'analyse des besoins consiste faire une liste des indicateurs qu'on
utilisera pour savoir quand le travail sera termin et le client satisfait . Les
spcifications du systme consistent en une description de ce que le programme
fera (sans ce proccuper du comment) pour satisfaire les besoins . L'analyse des
besoins est un contrat entre le dveloppeur et le client (mme si le client travaille
dans la mme entreprise, ou se trouve tre un objet ou un autre systme). Les
spcifications du systme sont une exploration gnrale du problme, et en un sens
permettent de savoir s'il peut tre rsolu et en combien de temps. Comme ils
requirent des consensus entre les intervenants sur le projet (et parce qu'ils
changent au cours du temps), il vaut mieux les garder aussi bruts que possible -
idalement en tant que listes et diagrammes - pour ne pas perdre de temps. Il peut y
avoir d'autres contraintes qui demandent de produire de gros documents, mais en
gardant les documents initiaux petits et concis, cela permet de les crer en quelques
sessions de brainstorming avec un leader qui affine la description dynamiquement.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 40/459
dispose d'un ensemble complet de cas d'utilisation, on peut dcrire le systme et
passer la phase suivante. Tout ne sera pas parfaitement clair ds le premier jet,
mais a ne fait rien. Tout se dcantera avec le temps, et si on cherche obtenir des
spcifications du systme parfaites ce point on se retrouvera coinc.
Si on est bloqu, on peut lancer cette phase en utilisant un outil d'approximation
grossier : dcrire le systme en quelques paragraphes et chercher les noms et les
verbes. Les noms suggrent les acteurs, le contexte des cas d'utilisation ou les objets
manipuls dans les cas d'utilisation. Les verbes suggrent les interactions entre les
acteurs et les cas d'utilisation, et spcifient les tapes l'intrieur des cas
d'utilisation. On verra aussi que les noms et les verbes produisent des objets et des
messages durant la phase de design (on peut noter que les cas d'utilisation dcrivent
les interactions entre les sous-systmes, donc la technique des noms et des
verbes ne peut tre utilise qu'en tant qu'outil de brainstorming car il ne fournit
pas les cas d'utilisation) [11].
#/TIJ_PAGE05# #TIJ_PAGE06#
La frontire entre un cas d'utilisation et un acteur peut rvler l'existence
Chaque bonhomme reprsente un acteur , typiquement une personne ou une d'une interface utilisateur, mais ne dfinit pas cette interface utilisateur. Pour une
autre sorte d'agent (cela peut mme tre un autre systme informatique, comme mthode de dfinition et de cration d'interfaces utilisateur, se rfrer Software
c'est le cas avec ATM ). La bote reprsente les limites du systme. Les ellipses for Use de Larry Constantine et Lucy Lockwood, (Addison-Wesley Longman, 1999)
reprsentent les cas d'utilisation, qui sont les descriptions des actions qui peuvent ou sur www.ForUse.com.
tre ralises avec le systme. Les lignes entre les acteurs et les cas d'utilisation
reprsentent les interactions. Bien que cela tienne plus de l'art obscur, ce point un calendrier de base est
important. On dispose maintenant d'une vue d'ensemble de ce qu'on construit, on
Tant que le systme est peru ainsi par l'utilisateur, son implmentation n'est pas peut donc se faire une ide du temps ncessaire sa ralisation. Un grand nombre
importante. de facteurs entre en jeu ici. Si on estime un calendrier trop important, l'entreprise
Un cas d'utilisation n'a pas besoin d'tre complexe, mme si le systme sous-jacent peut dcider d'abandonner le projet (et utiliser leurs ressources sur quelque chose
l'est. Il est seulement destin montrer le systme tel qu'il apparat l'utilisateur. de plus raisonnable - ce qui est une bonne chose). Ou un directeur peut avoir dj
Par exemple : dcid du temps que le projet devrait prendre et voudra influencer les estimations.
Mais il vaut mieux proposer un calendrier honnte et prendre les dcisions
importantes au dbut. Beaucoup de techniques pour obtenir des calendriers prcis
ont t proposes (de mme que pour prdire l'volution de la bourse), mais la
meilleure approche est probablement de se baser sur son exprience et son intuition.
Proposer une estimation du temps ncessaire pour raliser le systme, puis doubler
cette estimation et ajouter 10 pour cent. L'estimation initiale est probablement
correcte, on peut obtenir un systme fonctionnel avec ce temps. Le doublement
transforme le dlai en quelque chose de dcent, et les 10 pour cent permettront de
poser le vernis final et de traiter les dtails [12]. Peu importe comment on l'explique
Les cas d'utilisation produisent les spcifications des besoins en dterminant toutes et les gmissements obtenus quand on rvle un tel planning, il semble juste que a
les interactions que l'utilisateur peut avoir avec le systme. Il faut trouver un fonctionne de cette faon.
ensemble complet de cas d'utilisations du systme, et cela termin on se retrouve
avec le coeur de ce que le systme est cens faire. La beaut des cas d'utilisation est
qu'ils ramnent toujours aux points essentiels et empchent de se disperser dans des
discussions non essentielles la ralisation du travail faire. Autrement dit, si on
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 41/459
Phase 2 : Comment allons-nous le construire ? collaborations, et on peut remplir les cartes. Quand tous les scnarios ont t
couverts, on devrait disposer d'une bonne approximation de la conception.
Dans cette phase on doit fournir une conception qui dcrive ce quoi les classes Avant d'utiliser les cartes CRC, la meilleure conception initiale que j'ai fourni sur un
ressemblent et comment elles interagissent. Un bon outil pour dterminer les projet fut obtenue en dessinant des objets sur un tableau devant une quipe - qui
classes et les interactions est la mthode des cartes Classes-Responsabilits- n'avait jamais particip un projet de POO auparavant. Nous avons discut de la
Collaboration (CRC). L'un des avantages de cet outil est sa simplicit : on prend des communication entre ces objets, effac et remplac certains d'entre eux par d'autres
cartes vierges et on crit dessus au fur et mesure. Chaque carte reprsente une objets. De fait, je recrais la mthode des cartes CRC au tableau. L'quipe (qui
classe, et sur la carte on crit : connaissait ce que le projet tait cens faire) a effectivement cr la conception ; et
de ce fait ils la contrlaient. Je me contentais de guider le processus en posant les
1. Le nom de la classe. Il est important que le nom de cette classe reflte bonnes questions, proposant quelques hypothses et utilisant les rponses de
l'essence de ce que la classe fait, afin que sa comprhension soit immdiate. l'quipe pour modifier ces hypothses. La beaut de la chose fut que l'quipe a
2. Les responsabilits de la classe : ce qu'elle doit faire. appris btir une conception oriente objet non en potassant des exemples
Typiquement, cela peut tre rsum par le nom des fonctions abstraits, mais en travaillant sur la conception qui les intressait au moment
membres (puisque ces noms doivent tre explicites dans une prsent : celle de leur projet.
bonne conception), mais cela n'empche pas de complter par
Une fois qu'on dispose d'un ensemble de cartes CRC, on peut vouloir une
d'autres notes. Pour s'aider, on peut se placer du point de vue
description plus formelle de la conception en utilisant UML [13]. L'utilisation
d'un programmeur fainant : quels objets voudrait-on voir
d'UML n'est pas une obligation, mais cela peut tre utile, surtout si on veut afficher
apparatre pour rsoudre le problme ?
au mur un diagramme auquel tout le monde puisse se rfrer, ce qui est une bonne
3. Les collaborations de la classe : avec quelles classes interagit- ide. Une alternative UML est une description textuelle des objets et de leur
elle ? Interagir est intentionnellement vasif, il peut se rfrer interface, ou suivant le langage de programmation, le code lui-mme [14].
une agrgation ou indiquer qu'un autre objet existant va
travailler pour le compte d'un objet de la classe. Les UML fournit aussi une notation pour dcrire le modle dynamique du systme. Cela
collaborations doivent aussi prendre en compte l'audience de cette est pratique dans les cas o les tats de transition d'un systme ou d'un sous-sytme
classe. Par exemple, si on cre une classe Ptard, qui va sont suffisamment importants pour ncessiter leurs propres diagrammes (dans un
l'observer, un Chimiste ou un Spectateur ? Le premier voudra systme de contrle par exemple). On peut aussi dcrire les structures de donnes,
connatre la composition chimique, tandis que le deuxime sera pour les systmes ou sous-systmes dans lesquels les donnes sont le facteur
dominant (comme une base de donnes).
proccup par les couleurs et le bruit produits quand il explose.
On pourrait se dire que les cartes devraient tre plus grandes cause de toutes les On sait que la Phase 2 est termine quand on dispose de la description des objets et
informations qu'on aimerait mettre dessus, mais il vaut mieux les garder les plus de leur interface. Ou du moins de la majorit d'entre eux - il y en a toujours
quelques-uns qu'on ne dcouvre qu'en Phase 3 , mais cela ne fait rien. La
petites possibles, non seulement pour concevoir de petites classes, mais aussi pour
viter de plonger trop tt dans les dtails. Si on ne peut pas mettre toutes les proccupation principale est de dcouvrir tous les objets. Il est plus agrable de les
informations ncessaires propos d'une classe sur une petite carte, la classe est trop dcouvrir le plus tt possible, mais la POO est assez souple pour pouvoir s'adapter si
on en dcouvre de nouveaux par la suite. En fait, la conception d'un objet se fait en
complexe (soit le niveau de dtails est trop lev, soit il faut crer plus d'une classe).
La classe idale doit tre comprise en un coup d'oeil. L'objectif des cartes CRC est de cinq tapes.
fournir un premier jet de la conception afin de saisir le plan gnral pour pouvoir
ensuite affiner cette conception. Les cinq tapes de la conception d'un objet
L'un des avantages des cartes CRC rside dans la communication. Il vaut mieux les
raliser en groupe, sans ordinateur. Chacun prend le rle d'une ou plusieurs classes La conception d'un objet n'est pas limite la phase de codage du programme. En
(qui au dbut n'ont pas de nom ni d'information associe). Il suffit alors de drouler fait, la conception d'un objet passe par une suite d'tapes. Garder cela l'esprit
une simulation impliquant un scnario la fois, et dcider quels messages sont permet d'viter de prtendre la perfection immdiate. On ralise que la
envoys aux diffrents objets pour satisfaire chaque scnario. Au fur et mesure du comprhension de ce que fait un objet et de ce quoi il doit ressembler se fait
processus, on dcouvre quelles sont les classes ncessaires, leurs responsabilits et progressivement. Ceci s'applique d'ailleurs aussi la conception de nombreux types
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 42/459
de programmes ; le modle d'un type de programme n'merge qu'aprs s'tre Indications quant au dveloppement des objets
confront encore et encore au problme (se rfrer au livre Thinking in Patterns
with Java, tlchargeable sur www.BruceEckel.com). Les objets aussi ne se rvlent
Ces tapes suggrent quelques rgles de base concernant le dveloppement des
la comprhension qu'aprs un long processus.
classes :
1. Dcouverte de l'objet. Cette tape se situe durant l'analyse initiale 1. Quand un problme spcifique gnre une classe, la laisser grandir et mrir
du programme. Les objets peuvent tre dcouvert en cherchant les durant la rsolution d'autres problmes.
facteurs extrieurs et les frontires, la duplication d'lments dans le 2. Se rappeler que la conception du systme consiste principalement
systme, et les plus petites units conceptuelles. Certains objets sont dcouvrir les classes dont on a besoin (et leurs interfaces). Si on
vidents si on dispose d'un ensemble de bibliothques de classes. La dispose dj de ces classes, le projet ne devrait pas tre
ressemblance entre les classes peut suggrer des classes de base et compliqu.
l'hritage peut en tre dduit immdiatement, ou plus tard dans la phase 3. Ne pas vouloir tout savoir ds le dbut ; complter ses connaissances au fur
de conception. et mesure de l'avancement du projet. La connaissance viendra de toutes
2. Assemblage des objets. Lors de la construction d'un objet, on peut faons tt ou tard.
dcouvrir le besoin de nouveaux membres qui n'tait pas apparu durant 4. Commencer programmer ; obtenir un prototype qui marche afin
l'tape de dcouverte. Les besoins internes d'un objet peuvent requrir de pouvoir approuver la conception ou au contraire la dnoncer.
d'autres classes pour les supporter. Ne pas avoir peur de se retrouver avec du code-spaghetti la
procdurale - les classes partitionnent le problme et aident
3. Construction du systme. Une fois de plus, un objet peut rvler contrler l'anarchie. Les mauvaises classes n'affectent pas les
des besoins supplmentaires durant cette tape. Au fur et mesure de classes bien conues.
l'avancement du projet, les objets voluent. Les besoins de la 5. Toujours rester le plus simple possible. De petits objets propres
communication et de l'interconnexion avec les autres objets du systme avec une utilit apparente sont toujours mieux conus que ceux
peuvent changer les besoins des classes ou demander de nouvelles disposant de grosses interfaces compliques. Quand une dcision
classes. Par exemple, on peut dcouvrir le besoin de classes d'utilitaires, doit tre prise, utiliser l'approche du rasoir d'Occam : choisir
telles que des listes chanes, qui contiennent peu ou pas d'information la solution la plus simple, car les classes simples sont presque
et sont juste l pour aider les autres classes. toujours les meilleures. Commencer petit et simple, et tendre
4. Extension du systme. Si on ajoute de nouvelles fonctionnalits au l'interface de la classe quand on la comprend mieux. Il est
systme, on peut se rendre compte que sa conception ne facilite pas toujours plus difficile d'enlever des lments d'une classe.
l'extension du systme. Avec cette nouvelle information, on peut
restructurer certaines parties du systme, ventuellement en ajoutant de Phase 3 : Construire le coeur du systme
nouvelles classes ou de nouvelles hirarchies de classes.
5. Rutilisation des objets. Ceci est le test final pour une classe. Si Ceci est la conversion initiale de la conception brute en portion de code compilable
quelqu'un tente de rutiliser une classe dans une situation entirement et excutable qui peut tre teste, et surtout qui va permettre d'approuver ou
diffrente, il y dcouvrira certainement des imperfections. La d'invalider l'architecture retenue. Ce n'est pas un processus qui se fait en une passe,
modification de la classe pour s'adapter de nouveaux programmes va mais plutt le dbut d'une srie d'tapes qui vont construire le systme au fur et
en rvler les principes gnraux, jusqu' l'obtention d'un type vraiment mesure comme le montre la Phase 4.
rutilisable. Cependant, il ne faut pas s'attendre ce que tous les objets Le but ici est de trouver le coeur de l'architecture du systme qui a besoin d'tre
d'un systme soient rutilisables - il est tout fait lgitime que la implment afin de gnrer un systme fonctionnel, sans se soucier de l'tat de
majorit des objets soient spcifiques au systme. Les classes compltion du systme dans cette passe initiale. Il s'agit ici de crer un cadre sur
rutilisables sont moins frquentes, et doivent traiter de problmes plus lequel on va pouvoir s'appuyer pour les itrations suivantes. On ralise aussi la
gnriques pour tre rutilisables. premire des nombreuses intgrations et phases de tests, et on donne les premiers
retours aux clients sur ce quoi leur systme ressemblera et son tat d'avancement.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 43/459
Idalement, on dcouvre quelques-uns des risques critiques. Des changements ou
des amliorations sur l'architecture originelle seront probablement dcouverts - des
Phase 5 : Evolution
choses qu'on n'aurait pas dcouvert avant l'implmentation du systme.
Cette phase du cycle de dveloppement a traditionnellement t appele
Une partie de la construction du systme consiste confronter le systme avec maintenance , un terme fourre-tout qui peut tout vouloir dire depuis faire
l'analyse des besoins et les spcifications du systme (quelle que soit la forme sous marcher le produit comme il tait suppos le faire ds le dbut ajouter de
laquelle ils existent). Il faut s'assurer en effet que les tests vrifient les besoins et les nouvelles fonctionnalits que le client a oubli de mentionner au plus traditionnel
cas d'utilisations. Quand le coeur du systme est stable, on peut passer la suite et corriger les bugs qui apparaissent et ajouter de nouvelles fonctionnalits
ajouter des fonctionnalits supplmentaires. quand le besoin s'en fait sentir . Le terme maintenance a t la cause de si
nombreux malentendus qu'il en est arriv prendre un sens pjoratif, en partie
Phase 4 : Itrer sur les cas d'utilisation parce qu'il suggre qu'on a fourni un programme parfait et que tout ce qu'on a
besoin de faire est d'en changer quelques parties, le graisser et l'empcher de
rouiller. Il existe peut-tre un meilleur terme pour dcrire ce qu'il en est rellement.
Une fois que le cadre de base fonctionne, chaque fonctionnalit ajoute est un petit
projet en elle-mme. On ajoute une fonctionnalit durant une itration, priode J'utiliserai plutt le terme volution[15]. C'est dire, Tout ne sera pas parfait ds
relativement courte du dveloppement. le premier jet, il faut se laisser la latitude d'apprendre et de revenir en arrire pour
faire des modifications . De nombreux changements seront peut-tre ncessaires
Combien de temps dure une itration ? Idalement, chaque itration dure entre une au fur et mesure que l'apprhension et la comprhension du problme
et trois semaines (ceci peut varier suivant le langage d'implmentation choisi). A la augmentent. Si on continue d'voluer ainsi jusqu'au bout, l'lgance obtenue sera
fin de cette priode, on dispose d'un systme intgr et test avec plus de
payante, la fois court et long terme. L'volution permet de passer d'un bon un
fonctionnalits que celles dont il disposait auparavant. Mais ce qu'il est intressant excellent programme, et clarifie les points rests obscurs durant la premire passe.
de noter, c'est qu'un simple cas d'utilisation constitue la base d'une itration. C'est aussi dans cette phase que les classes passent d'un statut d'utilit limite au
Chaque cas d'utilisation est un ensemble de fonctionnalits qu'on ajoute au systme
systme ressource rutilisable.
toutes en mme temps, durant une itration. Non seulement cela permet de se faire
une meilleure ide de ce que recouvre ce cas d'utilisation, mais cela permet de le Ici, jusqu'au bout ne veut pas simplement dire que le programme fonctionne
valider, puisqu'il n'est pas abandonn aprs l'analyse et la conception, mais sert au suivant les exigences et les cas d'utilisation. Cela veut aussi dire que la structure
contraire tout au long du processus de cration. interne du code prsente une logique d'organisation et semble bien s'assembler,
sans abus de syntaxe, d'objets surdimensionns ou de code inutilement expos. De
Les itrations s'arrtent quand on dispose d'un systme comportant toutes les plus, il faut s'assurer que la structure du programme puisse s'adapter aux
fonctionnalits souhaites ou qu'une date limite arrive et que le client se contente de
changements qui vont invitablement arriver pendant sa dure vie, et que ces
la version courante (se rappeler que les commanditaires dirigent l'industrie du changements puissent se faire aisment et proprement. Ceci n'est pas une petite
logiciel). Puisque le processus est itratif, on dispose de nombreuses opportunits caractristique. Il faut comprendre non seulement ce qu'on construit, mais aussi
pour dlivrer une version intermdiaire plutt qu'un produit final ; les projets open-
comment le programme va voluer (ce que j'appelle le vecteur changement).
source travaillent uniquement dans un environnement itratif avec de nombreux Heureusement, les langages de programmation orients objet sont particulirement
retours, ce qui prcisment les rend si productifs. adapts ce genre de modifications continuelles - les frontires cres par les objets
Un processus de dveloppement itratif est intressant pour de nombreuses raisons. sont ce qui empchent la structure du programme de s'effondrer. Ils permettent
Cela permet de rvler et de rsoudre des risques critiques trs tt, les clients ont de aussi de faire des changements - mme ceux qui seraient considrs comme svres
nombreuses opportunits pour changer d'avis, la satisfaction des programmeurs est dans un programme procdural - sans causer de ravages dans l'ensemble du code.
plus leve, et le projet peut tre pilot avec plus de prcision. Mais un bnfice En fait le support de l'volution pourrait bien tre le bnfice le plus important de la
additionnel particulirement important est le retour aux commanditaires du projet, programmation oriente objet.
qui peuvent voir grce l'tat courant du produit o le projet en est. Ceci peut Avec l'volution, on cre quelque chose qui approche ce qu'on croit avoir construit,
rduire ou liminer le besoin de runions soporifiques sur le projet, et amliore la
on le compare avec les exigences et on repre les endroits o cela coince. On peut
confiance et le support des commanditaires. alors revenir en arrire et corriger cela en remodlisant et rimplmentant les
portions du programme qui ne fonctionnaient pas correctement [16]. De fait, on
peut avoir besoin de rsoudre le problme ou un de ses aspects un certain nombre
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 44/459
de fois avant de trouver la bonne solution (une tude de Design Patterns s'avre #/TIJ_PAGE06# #TIJ_PAGE07#
gnralement utile ici). On pourra trouver plus d'informations dans Thinking in
Patterns with Java, tlchargeable www.BruceEckel.com).
Il faut aussi voluer quand on construit un systme, qu'on voit qu'il remplit les
Programmation Extrme
exigences et qu'on dcouvre finalement que ce n'tait pas ce qu'on voulait. Quand on
se rend compte aprs avoir vu le systme en action qu'on essayait de rsoudre un J'ai tudi diffrentes reprises les techniques d'analyse et de conception depuis
autre problme. Si on pense que ce genre d'volution est prendre en considration, que je suis sorti de l'cole. Le concept de Programmation Extreme (XP) est le plus
alors on se doit de construire une premire version aussi rapidement que possible radical et divertissant que j'ai vu. Il est rapport dans Extreme Programming
afin de dterminer au plus tt si c'est rellement ce qu'on veut. Explained de Kent Beck (Addison-Wesley, 2000) et sur le web
www.xprogramming.com.
La chose la plus importante retenir est que par dfaut - par dfinition, plutt - si
on modifie une classe, ses classes parentes et drives continueront de fonctionner. XP est la fois une philosophie propos de la programmation et un ensemble de
Il ne faut pas craindre les modifications (surtout si on dispose d'un ensemble de rgles de bases. Certaines de ces rgles sont reprises dans d'autres mthodologies
tests qui permettent de vrifier les modifications apportes). Les modifications ne rcentes, mais les deux contributions les plus importantes et novatrices, sont mon
vont pas ncessairement casser le programme, et tout changement apport sera sens commencer par crire les tests et programmation en binme . Bien qu'il
limit aux sous-classes et / ou aux collaborateurs spcifiques de la classe qu'on soutienne et argumente l'ensemble de la thorie, Beck insiste sur le fait que
change. l'adoption de ces deux pratiques amliore grandement la productivit et la fiabilit.
Les plans sont payants Commencer par crire les tests
Bien sr on ne btirait pas une maison sans une multitude de plans dessins avec Les tests ont traditionnellement t relgus la dernire partie d'un projet, une fois
attention. Si on construit un pont ou une niche, les plans ne seront pas aussi que tout marche, mais c'est juste pour s'en assurer . Ils ne sont gnralement pas
labors, mais on dmarre avec quelques esquisses pour se guider. Le prioritaires et les gens qui se spcialisent dedans ne sont pas reconnus leur juste
dveloppement de logiciels a connu les extrmes. Longtemps les gens ont travaill valeur et se sont souvent vus cantonns dans un sous-sol, loin des vritables
sans structure, mais on a commenc assister l'effondrement de gros projets. En programmeurs . Les quipes de test ont ragi en consquence, allant jusqu' porter
raction, on en est arriv des mthodologies comprenant un luxe de structure et de des vtements de deuil et glousser joyeusement quand ils trouvaient des erreurs
dtails, destines justement ces gros projets. Ces mthodologies taient trop (pour tre honnte, j'ai eu moi aussi ce genre de sentiments lorsque je mettais des
intimidantes pour qu'on les utilise - on avait l'impression de passer son temps compilateurs en faute).
crire des documents et aucun moment coder (ce qui tait souvent le cas). J'espre XP rvolutionne compltement le concept du test en lui donnant une priorit aussi
que ce que je vous ai montr ici suggre un juste milieu. Utilisez une approche qui importante (ou mme plus forte) que le code. En fait, les tests sont crits avant le
corresponde vos besoins (et votre personnalit). Mme s'il est minimal, la code qui sera test, et les tests restent tout le temps avec le code. Ces tests doivent
prsence d'un plan vous apportera beaucoup dans la gestion de votre projet. tre excuts avec succs chaque nouvelle intgration dans le projet (ce qui peut
Rappelez-vous que selon la plupart des estimations, plus de 50 pour cent des projets arriver plus d'une fois par jour).
chouent (certaines estimations vont jusqu' 70 pour cent).
Ecrire les tests d'abord a deux effets extrmement importants.
En suivant un plan - de prfrence un qui soit simple et concis - et en produisant
une modlisation de la structure avant de commencer coder, vous dcouvrirez que Premirement, cela ncessite une dfinition claire de l'interface d'une classe. J'ai
les choses s'arrangent bien mieux que si on se lance comme a dans l'criture. Vous souvent suggr que les gens imaginent la classe parfaite qui rsolve un problme
en retirerez aussi une plus grande satisfaction. Suivant mon exprience, arriver particulier comme outil pour concevoir le systme. La stratgie de test de XP va
une solution lgante procure une satisfaction un niveau entirement diffrent ; plus loin - elle spcifie exactement ce quoi la classe doit ressembler pour le client
cela ressemble plus de l'art qu' de la technologie. Et l'lgance est toujours de cette classe, et comment la classe doit se comporter. Dans des termes non
payante, ce n'est pas une vaine poursuite. Non seulement on obtient un programme ambigus. On peut crire tout ce qu'on veut, ou crer tous les diagrammes qu'on veut,
plus facile construire et dbugguer, mais qui est aussi plus facile comprendre et dcrivant comment une classe devrait se comporter et ce quoi elle ressemble, mais
maintenir, et c'est l que sa valeur financire rside. rien n'est aussi rel qu'une batterie de tests. Le premier est une liste de voeux, mais
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 45/459
les tests sont un contrat certifi par un compilateur et un programme qui marche. Il et o travailler avec ses voisins est considr comme tricher ), et jusqu'aux
est dur d'imaginer une description plus concrte d'une classe que des tests. mdias, en particulier les films hollywoodiens dans lequel le hros se bat contre la
conformit [17]. Les programmeurs aussi sont considrs comme des parangons
En crant les tests, on est forc de penser compltement la classe et souvent on
d'individualisme - des codeurs cowboy comme aime le dire Larry Constantine.
dcouvre des fonctionnalits ncessaires qui ont pu tre manques lors de
Et XP, qui se bat lui-mme contre la pense conventionnelle, soutient que le code
l'utilisation des diagrammes UML, des cartes CRC, des cas d'utilisation, etc...
devrait tre crit avec deux personnes par station de travail. Et cela devrait tre fait
Le deuxime effet important dans l'criture des tests en premier vient du fait qu'on dans un endroit regroupant plusieurs stations de travail, sans les barrires dont
peut lancer les tests chaque nouvelle version du logiciel. Cela permet d'obtenir raffolent les gens des Moyens Gnraux. En fait, Beck dit que la premire tche
l'autre moiti des tests raliss par le compilateur. Si on regarde l'volution des ncessaire pour implmenter XP est de venir avec des tournevis et d'enlever tout ce
langages de programmation de ce point de vue, on se rend compte que les qui se trouve dans le passage [18](cela ncessite un responsable qui puisse absorber
amliorations relles dans la technologie ont en fait tourn autour du test. Les la colre du dpartement des Moyens Gnraux).
langages assembleur vrifiaient uniquement la syntaxe, puis le C a impos des
Dans la programmation en binme, une personne produit le code tandis que l'autre
restrictions smantiques, et cela permettait d'viter certains types d'erreurs. Les
y rflchit. Le penseur garde la conception gnrale l'esprit - la description du
langages orients objet imposent encore plus de restrictions smantiques, qui sont
problme, mais aussi les rgles de XP porte de main. Si deux personnes
quand on y pense des formes de test. Est-ce que ce type de donnes est utilis
travaillent, il y a moins de chance que l'une d'entre elles s'en aille en disant Je ne
correctement ? et Est-ce que cette fonction est appele correctement ? sont le
veux pas commencer en crivant les tests , par exemple. Et si le codeur reste
genre de tests effectus par le compilateur ou le systme d'excution. On a pu voir le
bloqu, ils peuvent changer leurs places. Si les deux restent bloqus, leurs songeries
rsultat d'avoir ces tests dans le langage mme : les gens ont t capables de
peuvent tre remarques par quelqu'un d'autre dans la zone de travail qui peut venir
construire des systmes plus complexes, et de les faire marcher, et ce en moins de
les aider. Travailler en binme permet de garder une bonne productivit et de rester
temps et d'efforts. Je me suis souvent demand pourquoi, mais maintenant je ralise
sur la bonne pente. Probablement plus important, cela rend la programmation
que c'est grce aux tests : si on fait quelque chose de faux, le filet de scurit des
beaucoup plus sociable et amusante.
tests intgr au langage prvient qu'il y a un problme et montre mme o il rside.
J'ai commenc utiliser la programmation en binme durant les priodes d'exercice
Mais les tests intgrs permis par la conception du langage ne peuvent aller plus
dans certains de mes sminaires et il semblerait que cela enrichisse l'exprience
loin. A partir d'un certain point, il est de notre responsabilit de produire une suite
personnelle de chacun.
complte de tests (en coopration avec le compilateur et le systme d'excution) qui
vrifie tout le programme. Et, de mme qu'il est agrable d'avoir un compilateur qui
vrifie ce qu'on code, ne serait-il pas prfrable que ces tests soient prsents depuis
le dbut ? C'est pourquoi on les crit en premier, et qu'on les excute
Les raisons du succs de Java
automatiquement chaque nouvelle version du systme. Les tests deviennent une
extension du filet de scurit fourni par le langage. Java est si populaire actuellement car son but est de rsoudre beaucoup de
problmes auxquels les programmeurs doivent faire face aujourd'hui. Le but de Java
L'utilisation de langages de programmation de plus en plus puissants m'a permis de est d'amliorer la productivit. La productivit vient de diffrents horizons, mais le
tenter plus de choses audacieuses, parce que je sais que le langage m'empchera de langage a t conu pour aider un maximum tout en entravant le moins possible
perdre mon temps chasser les bugs. La stratgie de tests de XP ralise la mme avec des rgles arbitraires ou l'obligation d'utiliser un ensemble particulier de
chose pour l'ensemble du projet. Et parce qu'on sait que les tests vont rvler tous caractristiques. Java a t conu pour tre pratique ; les dcisions concernant la
les problmes introduits (et on ajoute de nouveaux tests au fur et mesure qu'on les conception de Java furent prises afin que le programmeur en retire le maximum de
imagine), on peut faire de gros changements sans se soucier de mettre le projet bnfices.
complet en droute. Ceci est une approche particulirement puissante.
Les systmes sont plus faciles exprimer et
Programmation en binme comprendre
La programmation en binme va l'encontre de l'individualisme farouche
endoctrin, depuis l'cole (o on russit ou choue suivant nos mrites personnels, Les classes conues pour rsoudre le problme sont plus faciles exprimer. La
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 46/459
solution est mise en oeuvre dans le code avec des termes de l'espace problme ( Beaucoup de langages traditionnels imposent des limitations internes sur la taille
Mets le fichier la poubelle ) plutt qu'en termes machine, l'espace solution des programmes et leur complexit. BASIC, par exemple, peut s'avrer intressant
( Positionne le bit 1 ce qui veut dire que le relais va se fermer ). On traite de pour mettre en oeuvre rapidement des solutions pour certains types de problmes ;
concepts de plus haut niveau et une ligne de code est plus porteuse de sens. mais si le programme dpasse quelques pages de long, ou s'aventure en dehors du
domaine du langage, cela revient tenter de nager dans un liquide encore plus
L'autre aspect bnfique de cette facilit d'expression se retrouve dans la
visqueux. Aucune limite ne prvient que le cadre du langage est dpass, et mme
maintenance, qui reprsente (s'il faut en croire les rapports) une grosse part du cot
s'il en existait, elle serait probablement ignore. On devrait se dire : Mon
d'un programme. Si un programme est plus facile comprendre, il est forcment
programme BASIC devient trop gros, je vais le rcrire en C ! , mais la place on
plus facile maintenir. Cela rduit aussi le cot de cration et de maintenance de la
tente de glisser quelques lignes supplmentaires pour implmenter cette nouvelle
documentation.
fonctionnalit. Le cot total continue donc augmenter.
Java a t conu pour pouvoir mettre en oeuvre toutes les tailles de projets - c'est
Puissance maximale grce aux bibliothques dire, pour supprimer ces frontires lies la complexit croissante d'un gros projet.
L'utilisation de la programmation oriente objet n'est certainement pas ncessaire
La faon la plus rapide de crer un programme est d'utiliser du code dj crit : une pour crire un programme utilitaire du style Hello world ! , mais les
bibliothque. Un des buts fondamentaux de Java est de faciliter l'emploi des fonctionnalits sont prsentes quand on en a besoin. Et le compilateur ne relche
bibliothques. Ce but est obtenu en convertissant ces bibliothques en nouveaux pas son attention pour dnicher les bugs - produisant indiffremment des erreurs
types de donnes (classes), et utiliser une bibliothque revient ajouter de nouveaux pour les petits comme pour les gros programmes.
types au langage. Comme le compilateur Java s'occupe de l'interfaage avec la
bibliothque - garantissant une initialisation et un nettoyage propres, et s'assurant
que les fonctions sont appeles correctement - on peut se concentrer sur ce qu'on
attend de la bibliothque, et non sur les moyens de le faire. Stratgies de transition
Traitement des erreurs Si on dcide d'investir dans la POO, la question suivante est gnralement :
Comment convaincre mes directeur / collgues / dpartement / collaborateurs
L'une des difficults du C est la gestion des erreurs, problme connu et largement d'utiliser les objets ? . Il faut se mettre leur place et rflchir comment on ferait
ignor - le croisement de doigts est souvent impliqu. Si on construit un programme s'il fallait apprendre un nouveau langage et un nouveau paradigme de
gros et complexe, il n'y a rien de pire que de trouver une erreur enfouie quelque part programmation. Ce cas s'est srement dj prsent de par le pass. Il faut
sans qu'on sache d'o elle vienne. Le traitement des exceptions de Java est une commencer par des cours et des exemples ; puis lancer un petit projet d'essai pour
faon de garantir qu'une erreur a t remarque, et que quelque chose est mis en inculquer les bases sans les perdre dans les dtails. Ensuite passer un projet
oeuvre pour la traiter. rel qui ralise quelque chose d'utile. Au cours du premier projet, continuer
l'apprentissage par la lecture, poser des questions des experts et changer des
astuces avec des amis. Cette approche est celle recommande par de nombreux
Mise en oeuvre de gros projets programmeurs expriments pour passer Java. Si toute l'entreprise dcide de
passer Java, cela entranera bien sr une dynamique de groupe, mais cela aide de
se rappeler chaque tape comment une personne seule oprerait.
Rgles de base
Voici quelques indications prendre en compte durant la transition vers la
programmation oriente objet et Java.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 47/459
1. Cours particulier, les Bibliothques Standard Java, couvertes tout au long de ce livre). On
arrive au cycle de dveloppement le plus court quand on cre et utilise des objets
directement tirs des bibliothques. Cependant, de nouveaux programmeurs ne
La premire tape comprend une formation. Il ne faut pas jeter la confusion
saisissent pas ce point, ne connaissent pas l'existence de telles bibliothques ou,
pendant six ou neuf mois dans l'entreprise, le temps que tout le monde comprenne
fascins par le langage, veulent rcrire des classes qui existent dj. Le succs de la
comment fonctionnent les interfaces. Il vaut mieux se contenter d'un petit groupe
transition vers Java et la POO passe par des efforts pour encourager les gens
d'endoctrinement, compos de prfrence de personnes curieuses, s'entendant bien
rutiliser le plus possible le code des autres.
entre elles et suffisamment indpendantes pour crer leur propre rseau de support
concernant l'apprentissage de Java.
5. Ne pas traduire du code existant en Java
Une approche alternative suggre quelquefois comprend la formation de tous les
niveaux de l'entreprise la fois, en incluant la fois des cours de prsentation pour
Ce n'est gnralement pas le meilleur usage de son temps qu'on puisse trouver que
les responsables et des cours de conception et de programmation pour les
de prendre du code existant et fonctionnel et de le traduire en Java (si on doit le
dveloppeurs. Ceci est particulirement valable pour les petites entreprises qui
transformer en objets, on peut s'interfacer avec du code C ou C++ en utilisant
n'hsitent pas introduire des changements radicaux dans leurs manires de faire,
l'Interface Native Java - JNI - dcrite dans l'annexe B). Il y a bien sr des avantages
ou au niveau division des grosses entreprises. Cependant, comme le cot rsultant
le faire, particulirement si ce code est destin tre rutilis. Mais il y a de fortes
est plus important, certains choisiront de commencer avec des cours, de raliser un
chances pour qu'on passe ct de la spectaculaire amlioration de productivit
projet pilote (si possible avec un mentor extrieur), et de laisser l'quipe du projet
espre sauf si ce premier projet en est un nouveau. Java et la POO sont mis en
devenir les professeurs pour le reste de l'entreprise.
valeur quand on suit un projet de la conception la mise en oeuvre.
2. Projet faible risque
Les obstacles au niveau du management
Tester sur un projet faible risque qui autorise les erreurs. Une fois gagne une
certaine exprience, on peut soit rpartir les membres de cette premire quipe sur Si on se situe du ct des responsables, le travail consiste acqurir des ressources
les autres projets ou utiliser cette quipe comme support technique de la POO. Le pour l'quipe, surmonter les obstacles pouvant gner l'quipe, et en gnral tenter
premier projet peut ne pas fonctionner correctement ds le dbut, il ne faut donc de fournir l'environnement le plus productif et agrable afin que l'quipe puisse
pas qu'il soit critique pour l'entreprise. Il doit tre simple, indpendant et instructif : accomplir ces miracles qu'on vous demande toujours de raliser. Le passage Java
cela veut dire qu'il doit impliquer la cration de classes qui soient comprhensibles entre dans ces trois catgories, et ce serait merveilleux si de plus cela ne cotait rien.
aux autres programmeurs quand arrivera leur tour d'apprendre Java. Bien que le passage Java puisse tre moins onreux - suivant les contraintes - que
d'autres alternatives de POO pour une quipe de programmeurs C (et probablement
pour les dveloppeurs dans d'autres langages), ce cot n'est pas nul, et il y a des
3. S'inspirer de bonnes conceptions obstacles dont il faut tre conscient avant de promouvoir le passage Java
l'intrieur de l'entreprise et de s'embarquer dans la transition.
Rechercher des exemples de bonnes conceptions orientes objet avant de partir de
zro. Il y a de fortes chances que quelqu'un ait dj rsolu le problme, et s'ils ne
l'ont pas rsolu exactement modifier le systme existant (grce l'abstraction, cf
Cots de mise en oeuvre
plus haut) pour qu'il remplisse nos besoins. C'est le concept gnral des patrons
gnriques, couverts dans Thinking in Patterns with Java, tlchargeable Le cot du passage Java recouvre plus que l'acquisition d'un compilateur Java (le
www.BruceEckel.com. compilateur Java fourni par Sun est gratuit, cela n'est donc pas un obstacle). Les
cots moyen et long terme seront minimiss si on investit dans la formation (et
ventuellement dans la participation d'un consultant pour le premier projet), de
4. Utiliser les bibliothques de classes existantes mme que si on identifie et achte des bibliothques de classes qui rsolvent les
problmes plutt que de tenter de rcrire ces bibliothques soi-mme. Ce sont des
La motivation conomique premire pour passer la POO est la facilit de investissements lourds qui doivent tre relativiss dans une proposition raisonnable.
rutilisation de code existant sous la forme de bibliothques de classes (en De plus, il existe des cots cachs dans la baisse de productivit lie
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 48/459
l'apprentissage d'un nouveau langage et ventuellement d'un nouvel environnement la conception et l'implmentation des premiers projets, puisqu'aucun expert n'existe
de dveloppement. La formation et l'encadrement peuvent certainement les rduire, encore au sein de l'entreprise et qu'il peut y avoir des rticences engager des
mais les membres de l'quipe devront mener leur propre combat pour matriser la consultants. Il est facile de se dire trop tt qu'on matrise la POO et partir sur de
nouvelle technologie. Durant cette phase ils feront plus d'erreurs (c'est prouv, et les mauvaises bases. Quelque chose d'vident pour une personne exprimente peut
erreurs comprises constituent le meilleur moyen de progresser) et seront moins tre le sujet d'un dbat interne intense pour un novice. La plupart de ces difficults
productifs. Cependant, avec certains types de problmes, les bonnes classes et le bon peuvent tre vites en utilisant un expert extrieur pour la formation.
environnement de dveloppement, il est possible d'tre plus productif pendant
#/TIJ_PAGE07# #TIJ_PAGE08#
l'apprentissage de Java (mme en considrant qu'on fait plus d'erreurs et qu'on crit
moins de lignes de code par jour) que si on en tait rest au C.
Java vs. C++ ?
Problmes de performances
Java ressemble beaucoup au C++, et il semblerait naturel que le C++ soit remplac
Une question qui revient souvent est : Est-ce que la POO ne rend pas par Java. Mais je commence m'interroger sur cette logique. D'une part, C++
obligatoirement mes programmes plus gros et plus lents ? . La rponse est Ca dispose toujours de fonctionnalits que Java n'a pas, et bien que de nombreuses
dpend. . Les fonctionnalits de vrification introduites dans Java ont prlev leur promesses aient t faites sur le fait que Java soit un jour aussi rapide, voire mme
tribut sur la performance compar un langage comme le C++. Des technologies plus, que le C++, on a vu de grosses amliorations mais pas de rvolutions
telles que le hotspot et les techniques de compilation ont significativement spectaculaires. De plus, il semblerait que le C++ intresse une large communaut
amlior la vitesse dans la plupart des cas, et les efforts pour des performances passionne, et je ne pense donc pas que ce langage puisse disparatre prochainement
accrues continuent. (les langages semblent rsister au cours du temps. Allen Hollub a affirm durant
Quand on se concentre sur le prototypage rapide, on assemble des composants aussi l'un de mes Sminaires Java Intermdiaire/Avanc que les deux langages les
vite que possible en ignorant les problmes lis l'efficacit. Si on utilise des plus utiliss taient Rexx et COBOL, dans cet ordre).
bibliothques extrieures, celles-ci ont gnralement t optimises par leurs Je commence croire que la force de Java rside dans une optique diffrente de
distributeurs ; de toutes faons ce n'est pas la proccupation premire quand on est celle du C++. C++ est un langage qui n'essaie pas de se fondre dans un moule. Il a
en phase de dveloppement rapide. Quand on dispose d'un systme qui nous dj t adapt un certain nombre de fois pour rsoudre des problmes particuliers.
satisfait et s'il est suffisamment petit et rapide, alors le tour est jou. Sinon, on tente Certains des outils du C++ combinent des bibliothques, des modles de
de mettre au point avec un outil de profilage, en cherchant en premier des composants et des outils de gnration de code pour rsoudre les problmes
amliorations qui peuvent tre faites en rcrivant de petites portions de code. Si concernant le dveloppement d'applications fentres (pour Microsoft Windows). Et
cela ne suffit pas, il faut chercher si on peut apporter quelques changements pourtant, la vaste majorit des dveloppeurs Windows utilisent Microsoft Visual
l'implmentation sous-jacente afin qu'aucune classe particulire n'ait besoin de Basic (VB). Et ceci malgr le fait que VB produise le genre de code qui devient
modifier son code. Il ne faut toucher la conception que si rien d'autre ne rsout le ingrable quand le programme fait plus de quelques pages de long (sans compter
problme. Le fait que les performances soient si critiques dans cette phase de la que la syntaxe peut tre profondment mystrieuse). Aussi populaire que soit VB, ce
conception est un indicateur que ce doit tre un des critres essentiels de la n'est pas un trs bon exemple de conception de langage. Il serait agrable de pouvoir
conception. On a le bnfice de s'en rendre compte relativement tt en utilisant le disposer des facilits et de la puissance fournies par VB sans se retrouver avec ce
prototypage rapide. code ingrable. Et c'est l o je pense que Java va pouvoir briller : comme le VB du
Si on trouve une fonction qui soit un goulot d'tranglement, on peut la rcrire en C futur . On peut frissonner en entendant ceci, mais Java est conu pour aider le
ou en C++ en utilisant les mthodes natives de Java, sujet de l'annexe B. dveloppeur rsoudre des problmes comme les applications rseaux ou interfaces
utilisateurs multiplateformes, et la conception du langage permet la cration de
portions de code trs importantes mais nanmoins flexibles. Ajoutons ceci le fait
Erreurs classiques de conception que Java dispose des systmes de vrifications de types et de gestion des erreurs les
plus robustes que j'ai jamais rencontr dans un langage et on se retrouve avec les
Quand l'quipe commencera la programmation oriente objet et Java, les lments constitutifs d'un bond significatif dans l'amlioration de la productivit
programmeurs vont typiquement passer par une srie d'erreurs classiques de dans la programmation.
conception. Ceci est souvent du des retours insuffisants de la part d'experts durant
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 49/459
Faut-il utiliser Java en lieu et place du C++ dans les projets ? En dehors des applets La POO et Java ne sont pas forcment destins tout le monde. Il est important
Web, il y a deux points considrer. Premirement, si on veut rutiliser un certain d'valuer ses besoins et dcider si Java satisfera au mieux ces besoins, ou si un autre
nombre de bibliothques C++ (et on y gagnera certainement en productivit), ou si systme de programmation ne conviendrait pas mieux (celui qu'on utilise
on dispose d'une base existante en C ou C++, Java peut ralentir le dveloppement actuellement y compris). Si on connat ses besoins futurs et qu'ils impliquent des
plutt que l'acclrer. contraintes spcifiques non satisfaites par Java, alors on se doit d'tudier les
alternatives existantes [19]. Et mme si finalement Java est retenu, on saura au
Si on dveloppe tout le code en partant de zro, alors la simplicit de Java compare
moins quelles taient les options et les raisons de ce choix.
au C++ rduira significativement le temps de dveloppement - des anecdotes (selon
des quipes C++ qui j'ai parl aprs qu'ils eurent chang pour Java) suggrent un On sait quoi ressemble un programme procdural : des dfinitions de donnes et
doublement de la vitesse de dveloppement compar au C++. Si les performances des appels de fonctions. Pour trouver le sens d'un tel programme il faut se plonger
moindres de Java ne rentrent pas en ligne de compte ou qu'on peut les compenser, dans la chane des appels de fonctions et des concepts de bas niveau pour se
les contraintes de temps font qu'il est difficile de choisir le C++ aux dtriments de reprsenter le modle du programme. C'est la raison pour laquelle on a besoin de
Java. reprsentations intermdiaires quand on conoit des programmes procduraux -
par nature, ces programmes tendent tre confus car le code utilise des termes plus
Le point le plus important est la performance. Java interprt est lent, environ 20
orients vers la machine que vers le problme qu'on tente de rsoudre.
50 fois plus lent que le C dans les interprteurs Java originels. Ceci a t grandement
amlior avec le temps, mais il restera toujours un important facteur de diffrence. Parce que Java introduit de nombreux nouveaux concepts par rapport ceux qu'on
Les ordinateurs existent de par leur rapidit ; si ce n'tait pas considrablement plus trouve dans un langage procdural, on pourrait se dire que la fonction main() dans
rapide de raliser une tche sur ordinateur, on la ferait la main. J'ai mme entendu un programme Java sera bien plus complique que son quivalent dans un
suggrer de dmarrer avec Java, pour gagner sur le temps de dveloppement plus programme C. On sera agrablement surpris de constater qu'un programme Java
court, et ensuite utiliser un outil et des bibliothques de support pour traduire le bien crit est gnralement beaucoup plus simple et facile comprendre que son
code en C++ si on a un besoin de vitesse d'excution plus rapide. quivalent en C. On n'y voit que les dfinitions des objets qui reprsentent les
concepts de l'espace problme (plutt que leur reprsentation dans l'espace
La clef pour rendre Java viable dans la plupart des projets consiste en des
machine) et les messages envoys ces objets pour reprsenter les activits dans cet
amliorations de vitesse d'excution, grce des compilateurs juste temps
espace. L'un des avantages de la POO est qu'avec un programme bien conu, il est
( just in time , JIT), la technologie hotspot de Sun, et mme des compilateurs
facile de comprendre le code en le lisant. De plus, il y a gnralement moins de code,
de code natif. Bien sr, les compilateurs de code natif liminent les possibilits
car beaucoup de problmes sont rsolus en rutilisant du code existant dans des
d'excution interplateformes du programme compil, mais la vitesse des excutables
bibliothques.
produits se rapprochera de celle du C et du C++. Et raliser un programme
multiplateformes en Java devrait tre beaucoup plus facile qu'en C ou C++ (en
thorie, il suffit de recompiler, mais cette promesse a dj t faite pour les autres
langages). [2]Voir Multiparadigm Programming in Leda de Timothy Budd (Addison-Wesley
1995).
Vous trouverez des comparaisons entre Java et C++ et des observations sur Java
dans les annexes de la premire dition de ce livre (disponible sur le CD ROM [3]Certaines personnes tablissent une distinction, en disant qu'un type dtermine
accompagnant ce livre, et www.BruceEckel.com). une interface tandis qu'une classe est une implmentation particulire de cette
interface.
Rsum [4]Je suis reconnaissant envers mon ami Scott Meyers pour cette expression.
[5]Cela suffit gnralement pour la plupart des diagrammes, et on n'a pas besoin de
Ce chapitre tente de vous donner un aperu des sujets couverts par la prciser si on utilise un agrgat ou une composition.
programmation oriente objet et Java (les raisons qui font que la POO est [6]Invention personnelle.
particulire, de mme que Java), les concepts des mthodologies de la POO, et
finalement le genre de problmes que vous rencontrerez quand vous migrerez dans [7]Les types primitifs, que vous rencontrerez plus loin, sont un cas spcial.
votre entreprise la programmation oriente objet et Java.
[8]Un trs bon exemple en est UML Distilled, 2nd edition, de Martin Fowler
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 50/459
(Addison-Wesley 2000), qui rduit la mthode UML - parfois crasante - un sous- (www.Python.org).
ensemble facilement grable.
#/TIJ_PAGE08#
[9]Ma rgle pour estimer de tels projets : s'il y a plus d'un facteur joker, n'essayez
"http://www.w3.org/TR/html4/loose.dtd"> #TIJ_PAGE01#
mme pas de planifier combien de temps cela va prendre ou d'estimer le cot avant
d'avoir cr un prototype fonctionnel. Il y a trop de degrs de libert. 28.04.2001 - version 1.2 [Armel]
- Remise en forme du code html (DIR et PRE en blockquote et
[10]Merci James H Jarrett pour son aide. pre),
Ajout des tags de sparation de pages pour le site (Armel).
[11]D'autres informations sur les cas d'utilisation peuvent tre trouves dans Suppression des balises TIJ.
Applying Use Cases de Schneider & Winters (Addison-Wesley 1998) et Use Case 02.02.2001 - version 1.1 [Raczy]
Driven Object Modeling with UML de Rosenberg (Addison-Wesley 1999). - Tags + html nettoye
27.06.2000 - version 1.0 [Raczy]
[12]Mon avis personnel sur tout cela a chang rcemment. Doubler et ajouter 10 - Dernire modification : 27 juin 2000
pour cent donnera une estimation raisonnablement prcise (en assumant qu'il n'y Traducteur :
ait pas trop de facteurs joker), mais il faudra tout de mme ne pas traner en cours - Raczy
Texte original :
de route pour respecter ce dlai. Si on veut rellement du temps pour rendre le -Thinking in Java, 2nd edition, Revision 10
systme lgant et ne pas tre continuellement sous pression, le multiplicateur 2000 by Bruce Eckel
correct serait plus trois ou quatre fois le temps prvu, je pense..
[13]Pour les dbutants, je recommande UML Distilled, 2nd edition, dj mentionn
plus haut. 2 : Tout est Objet
[14]Python (www.python.org) est souvent utilis en tant que pseudocode
excutable . Bien qu'il soit bas sur C++, Java est un langage orient
[15]Au moins un aspect de l'volution est couvert dans le livre de Martin Fowler objet plus pur .
Refactoring : improving the design of existing code (Addison-Wesley 1999), qui C++ et Java sont tous les deux des langages hybrides, mais dans Java, les
utilise exclusivement des exemples Java. concepteurs ont pens que l'hybridation est moins importante qu'elle ne l'est en
[16]Cela peut ressembler au prototypage rapide o on est suppos fournir une C++. Un langage hybride autorise plusieurs styles de programmation : C++ est
version rapide-et-sale afin de pouvoir apprhender correctement le problme, puis hybride pour assurer la compatibilit avec le langage C. Comme C++ est une
jeter ce prototype et construire une version finale acceptable. L'inconvnient du extension du langage C, il contient un grand nombre des particularits indsirables
prototypage rapide est que les gens ne jettent pas le prototype, mais s'en servent de de ce langage, ce qui peut rendre certains aspects du C++ particulirement
base pour le dveloppement. Combin au manque de structure de la programmation embrouills.
procdurale, cela mne des systmes compliqus et embrouills, difficiles et Le langage Java suppose qu'on ne veut faire que de la programmation oriente objet
onreux maintenir. (POO). Ceci signifie qu'avant de pouvoir commencer il faut tourner sa vision des
[17]Bien que ceci soit plus une perception amricaine, les productions choses vers un monde orient objets ( moins qu'elle ne le soit dj). L'avantage de
hollywoodiennes touchent tout le monde. cet effort prliminaire est la capacit programmer dans un langage qui est plus
simple apprendre et utiliser que beaucoup d'autres langages de POO. Dans ce
[18]En particulier le systme d'annonces sonores. J'ai travaill une fois dans une chapitre nous verrons les composantes de base d'un programme Java et nous
entreprise qui insistait pour diffuser tous les appels tlphoniques tous les apprendrons que tout dans Java est objet, mme un programme Java.
responsables, et cela interrompait constamment notre productivit (mais les
responsables n'imaginaient mme pas qu'il soit concevable de vouloir couper un
service aussi important que le systme d'annonces sonores). Finalement, j'ai coup
les fils des haut-parleurs quand personne ne regardait.
[19]En particulier, je recommande de regarder dans la direction de Python
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 51/459
Les objets sont manipuls avec des
String s = new String("asdf");
rfrences Ceci ne veut pas seulement dire fabrique moi un nouvel objet String , mais cela
donne aussi une information sur comment fabriquer l'objet String en fournissant
une chane de caractres initiale.
Chaque langage de programmation a ses propres faons de manipuler les donnes.
Parfois le programmeur doit tre constamment conscient du type des manipulations Bien sr, String n'est pas le seul type qui existe. Java propose une plthore de types
en cours. Manipulez-vous l'objet directement, ou avez-vous affaire une sorte de tout prts. Le plus important est qu'on puisse crer ses propres types. En fait, c'est
reprsentation indirecte (un pointeur en C ou C++) qui doit tre trait avec une l'activit fondamentale en programmation Java et c'est ce qu'on apprendra faire
syntaxe particulire ? dans la suite de ce livre.
Tout ceci est simplifi en Java. On considre tout comme des objets, ainsi il n'y a
qu'une seule syntaxe cohrente qui est utilise partout. Bien qu'on traite tout
O rside la mmoire ?
comme des objets, les identificateurs qui sont manipuls sont en ralit des
rfrences vers des objets [21]. On pourrait imaginer cette situation comme une Il est utile de visualiser certains aspects de comment les choses sont arranges
tlvision (l'objet) avec une tlcommande (la rfrence). Tant qu'on conserve cette lorsque le programme tourne, en particulier comment la mmoire est organise. Il y
rfrence, on a une liaison vers la tlvision, mais quand quelqu'un dit change de a six endroits diffrents pour stocker les donnes :
chane ou baisse le volume , ce qu'on manipule est la rfrence, qui en retour 1. Les registres. C'est le stockage le plus rapide car il se trouve un endroit
modifie l'objet. Si on veut se dplacer dans la pice tout en contrlant la tlvision, diffrent des autres zones de stockage : dans le processeur. Toutefois, le
on emporte la tlcommande/rfrence, pas la tlvision. nombre de registres est svrement limit, donc les registres sont allous
De plus, la tlcommande peut exister par elle mme sans tlvision. C'est dire que par le compilateur en fonction de ses besoins. On n'a aucun contrle direct
le fait d'avoir une rfrence ne signifie pas ncessairement qu'un objet y soit associ. et il n'y a mme aucune trace de l'existence des registres dans les
Ainsi, si on veut avoir avoir un mot ou une phrase, on cre une rfrence sur une programmes.
String : 2. La pile. Elle se trouve dans la RAM (random access memory) mais elle est
prise en compte directement par le processeur via son pointeur de pile. Le
String s;
pointeur de pile est dplac vers le bas pour crer plus d'espace mmoire et
dplac vers le haut pour librer cet espace. C'est un moyen extrmement
Mais on a seulement cr la rfrence, pas un objet. ce point, si on dcidait efficace et rapide d'allouer de la mmoire, supplant seulement par les
d'envoyer un message s, on aurait une erreur (lors de l'excution) parce que s n'est registres. Le compilateur Java doit connatre, lorsqu'il cre le programme, la
pas rattache quoi que ce soit (il n'y a pas de tlvision). Une pratique plus sre est taille et la dure de vie exacte de toutes les donnes qui sont ranges sur la
donc de toujours initialiser une rfrence quand on la cre : pile, parce qu'il doit gnrer le code pour dplacer le pointeur de pile vers le
String s = "asdf"; haut et vers le bas. Cette contrainte met des limites la flexibilit des
programmes, donc, bien qu'il y ait du stockage Java sur la pile -- en
Toutefois, ceci utilise une caractristique spciale de Java : les chanes de caractres particulier les rfrences aux objets -- les objets Java eux mme ne sont pas
peuvent tre initialises avec du texte entre guillemets. Normalement, on doit placs sur la pile.
utiliser un type d'initialisation plus gnral pour les objets. 3. Le segment. C'est une rserve de mmoire d'usage gnral (aussi en RAM)
o rsident tous les objets java. La bonne chose propos du segment est
que, contrairement la pile, le compilateur n'a pas besoin de savoir de
Vous devez crer tous les objets combien de place il a besoin d'allouer sur le segment ni combien de temps
cette place doit rester sur le segment.Ainsi, il y a une grande flexibilit
utiliser la mmoire sur le segment. Lorsqu'on a besoin de crer un objet, il
Quand on cre une rfrence, on veut la connecter un nouvel objet. Ceci se fait, en
suffit d'crire le code pour le crer en utilisant new et la mmoire est
gnral, avec le mot-clef new. new veut dire fabrique moi un de ces objets .
alloue sur le segment lorsque le programme s'excute. Bien entendu il y a
Ainsi, dans l'exemple prcdent, on peut dire :
un prix payer pour cette flexibilit : il faut plus de temps pour allouer de la
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 52/459
mmoire sur le segment qu'il n'en faut pour allouer de la mmoire sur la pile Type primitif Taille Minimum Maximum Type wrapper
(c'est dire si on avait la possibilit de crer des objets sur la pile en Java,
comme on peut le faire en C++). boolean - - - Boolean
4. La mmoire statique. Statique est utilis ici dans le sens un char 16-bit Unicode 0 Unicode 216- 1 Character
endroit fixe (bien que ce soit aussi dans la RAM). La mmoire statique
contient les donnes qui sont disponibles pendant tout le temps d'excution byte 8-bit -128 +127 Byte
du programme. On peut utiliser le mot-clef static pour spcifier qu'un short 16-bit -215 +215-1 Short
lment particulier d'un objet est statique, mais les objets Java par eux-
mmes ne sont jamais placs dans la mmoire statique. int 32-bit -231 +231-1 Integer
5. Les constantes. Les valeurs des constantes sont souvent places long 64-bit -263 +263-1 Long
directement dans le code du programme, ce qui est sr puisqu'elles ne
peuvent jamais changer. Parfois les constantes sont isoles de faon float 32-bit IEEE754 IEEE754 Float
pouvoir tre optionnellement places dans une mmoire accessible en double 64-bit IEEE754 IEEE754 Double
lecture seulement (ROM).
6. Stockage hors RAM. Si les donnes rsident entirement hors du void - - - Void
programme, elles peuvent exister mme quand le programme ne tourne pas, Tous les types numriques sont signs, il est donc inutile d'aller chercher aprs des
en dehors du contrle du programme. Les deux exemples de base sont les types non signs.
flots de donnes, pour lesquels les donnes sont transformes en flots
Les types de donnes primitifs sont aussi associs des classes wrapper . Ceci
d'octets, gnralement pour tre transmises vers une autre machine, et les
signifie que pour faire un objet non primitif sur le segment pour reprsenter ce type
objets persistants, pour lesquels les objets sont placs sur disque de faon
primitif il faut utiliser le wrapper associ. Par exemple :
ce qu'ils conservent leur tat mme aprs que le programme soit termin.
L'astuce avec ces types de stockage est de transformer les objets en quelque char c = 'x';Character C =
chose qui peut exister sur l'autre support, tout en pouvant tre ressuscit en new Character(c);
un objet normal en mmoire, lorsque c'est ncessaire. Java fournit des outils
pour la persistance lgre, et les versions futures pourraient fournir des On peut aussi utiliser :
solutions plus compltes pour la persistance. Character C = new
Character('x');
Cas particulier : les types primitifs
Les raisons pour lesquelles on fait ceci seront indiques dans un prochain chapitre.
Il y a un ensemble de types qui sont soumis un traitement particulier ; ils peuvent
tre considrs comme les types primitifs frquemment utiliss en Nombres de grande prcision
programmation. La raison de ce traitement particulier est que la cration d'un objet
avec new -- en particulier une simple variable -- n'est pas trs efficace parce que Java contient deux classes pour effectuer des oprations arithmtiques de grande
new place les objets sur le segment. Pour ces types, Java a recours l'approche prcision : BigInteger et BigDecimal. Bien que ceux-ci soient dans la mme
retenue en C et en C++. Au lieu de crer la variable en utilisant new, une variable catgorie que les classes wrapper , aucun d'eux n'a d'analogue primitif.
automatique , qui n'est pas une rfrence, est cre. La variable contient la valeur
et elle est place sur la pile, ce qui est beaucoup plus efficace. Chacune de ces classes a des mthodes qui fournissent des oprations analogues
celles qu'on peut faire sur les types primitifs. C'est dire qu'avec un BigInteger ou
Java fixe la taille de chacun des types primitifs. Ces tailles ne changent pas d'une un BigDecimal on peut faire tout ce qu'on peut faire avec un int ou un float,
architecture de machine une autre, comme c'est le cas dans la plupart des seulement il faut utiliser des appels de mthodes au lieu des oprateurs. Par ailleurs,
langages. L'invariance de la taille de ces types est l'une des raisons pour lesquelles comme elles en font plus, les oprations sont plus lentes. On change la vitesse
Java est si portable. contre la prcision.
BigInteger sert aux entiers de prcision arbitraire. C'est dire qu'ils permettent de
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 53/459
reprsenter des valeurs entires de n'importe quelle taille sans perdre aucune erreurs sur la dure de vie des variables peuvent tre la source de nombreux bugs et
information au cours des oprations. cette partie montre comment Java simplifie normment ce problme en faisant le
mnage tout seul.
BigDecimal sert aux nombres virgule fixe de prcision arbitraire ; par exemple,
on peut les utiliser pour des calculs montaires prcis.
Il faut se reporter la documentation en ligne pour obtenir des dtails sur les
Notion de porte
constructeurs et mthodes utilisables avec ces deux classes.
La plupart des langages procduraux ont le concept de porte. Il fixe simultanment
la visibilit et la dure de vie des noms dfinis dans cette porte. En C, C++ et Java,
Tableaux en Java la porte est fixe par l'emplacement des accolades {}. Ainsi, par exemple :
{
Pratiquement tous les langages de programmation grent les tableaux. Utiliser des int x = 12;
tableaux en C ou C++ est dangereux car ces tableaux ne sont que des blocs de /* seul x est accessible */
mmoire. Si un programme accde un tableau en dehors de son bloc mmoire, ou {
s'il utilise la mmoire avant initialisation (erreurs de programmation frquentes) les int q = 96;
/* x & q sont tous les deux accessibles */
rsultats seront imprvisibles. }
Un des principaux objectifs de Java est la scurit, aussi, un grand nombre des /* seul x est accessible */
/* q est hors de porte */
problmes dont souffrent C et C++ ne sont pas rpts en Java. On est assur qu'un }
tableau Java est initialis et qu'il ne peut pas tre accd en dehors de ses bornes. La
vrification des bornes se fait au prix d'un petit excdent de mmoire pour chaque
Une variable dfinie dans une porte n'est accessible que jusqu' la fin de cette
tableau ainsi que de la vrification de l'index lors de l'excution, mais on suppose
porte.
que le gain en scurit et en productivit vaut la dpense.
L'indentation rend le code Java plus facile lire. tant donn que Java est un
Quand on cre un tableau d'objets, on cre en ralit un tableau de rfrences, et
langage indpendant de la mise en page, les espaces, tabulations et retours chariots
chacune de ces rfrences est automatiquement initialise une valeur particulire
supplmentaires ne changent pas le programme.
avec son propre mot cl : null. Quand Java voit null, il reconnat que la rfrence
en question ne pointe pas vers un objet. Il faut affecter un objet chaque rfrence Il faut remarquer qu'on ne peut pas faire la chose suivante, bien que cela soit
avant de l'utiliser et si on essaye d'utiliser une rfrence encore null, le problme autoris en C et C++ :
sera signal lors de l'excution. Ainsi, les erreurs typiques sur les tableaux sont {
vites en Java. int x = 12;
{
On peut aussi crer des tableaux de variables de type primitif. nouveau, le int x = 96; /* illegal */
compilateur garantit l'initialisation car il met zro la mmoire utilise par ces }
tableaux. }
Les tableaux seront traits plus en dtails dans d'autres chapitres.
Le compilateur annoncera que la variable x a dj t dfinie. Ainsi, la facult du C
et du C++ cacher une variable d'une porte plus tendue n'est pas autorise
Vous n'avez jamais besoin de parce que les concepteurs de Java ont pens que ceci mne des programmes
confus.
dtruire un objet
Dans la plupart des langages de programmation, le concept de dure de vie d'une
variable monopolise une part significative des efforts de programmation. Combien
de temps une variable existe-t-elle ? S'il faut la dtruire, quand faut-il le faire ? Des
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 54/459
Porte des objets nouveau type d'objet . Le mot-clef class (qui est si commun qu'il ne sera plus mis
en gras dans la suite de ce livre) est suivi par le nom du nouveau type. Par exemple :
Les objets Java n'ont pas la mme dure de vie que les variables primitives. Quand class ATypeName { /* le corps de la classe vient ici */ }
on cre un objet Java avec new, il existe toujours aprs la fin de la porte. Ainsi, si
on fait : Ceci introduit un nouveau type, on peut alors crer un objet de ce type en utilisant
new :
{
String s = new String("a string"); ATypeName a = new ATypeName();
} /* fin de porte */
Dans ATypeName, le corps de la classe ne consiste qu'en un commentaire (les
la rfrence s disparat la fin de la porte. Par contre l'objet String sur lequel s toiles et barres obliques et ce qu'il y a l'intrieur, ce qui sera dcrit ultrieurement
pointait occupe toujours la mmoire. Dans ce bout de code, il n'y a aucun moyen dans ce chapitre), donc il n'y pas grand chose faire avec. En fait, on ne peut pas lui
d'accder l'objet parce que son unique rfrence est hors de porte. Dans d'autres dire de faire quoi que ce soit (c'est dire qu'on ne peut pas lui transmettre de
chapitres on verra comment la rfrence un objet peut tre transmise et duplique message intressant) tant qu'on n'y dfinit pas de mthodes.
dans un programme.
#/TIJ_PAGE01# #TIJ_PAGE02#
Il s'avre que du simple fait qu'un objet cr avec new reste disponible tant qu'on le
veut, tout un tas de problmes de programmation du C++ disparaissent tout
simplement en Java. Il semble que les problmes les plus durs surviennent en C++ Champs et mthodes
parce que le langage ne fournit aucune aide pour s'assurer que les objets sont
disponibles quand on en a besoin. Et, encore plus important, en C++ on doit Lorsqu'on dfinit une classe (et tout ce que l'on fait en Java consiste dfinir des
s'assurer qu'on dtruit bien les objets quand on en a termin avec eux. classes, fabriquer des objets partir de ces classes et envoyer des messages ces
objets) on peut mettre deux types d'lments dans ces classes : des donnes
Ceci amne une question intressante. Si Java laisse les objets traner, qu'est-ce qui
membres de la classe (aussi appeles champs) et des fonctions membres de la classe
les empche de compltement remplir la mmoire et d'arrter le programme ? C'est
(habituellement appeles mthodes). Une donne membre est un objet de n'importe
exactement le problme qui surviendrait dans un programme C++. C'est l qu'un
quel type avec lequel on peut communiquer via sa rfrence. Il peut aussi s'agir d'un
peu de magie apparat. Java a un ramasse-miettes qui surveille tous les objets qui
des types primitifs (dans ce cas, ce n'est pas une rfrence). S'il s'agit d'une rfrence
ont t crs avec new et qui arrive deviner lesquels ne sont plus rfrencs.
un objet, il faut initialiser cette rfrence pour la connecter un objet rel (en
Ensuite il libre la mmoire de ces objets de faon ce que cette mmoire puisse
utilisant new comme indiqu prcdemment) grce une fonction particulire
tre utilise pour de nouveaux objets. Ceci signifie qu'il ne faut jamais s'embter
appele un constructeur (entirement dcrit dans le chapitre 4). S'il s'agit d'un type
rcuprer la mmoire soi-mme. On cre simplement les objets, et quand on n'en a
primitif il est possible de l'initialiser directement lors de sa dfinition dans la classe
plus besoin, ils disparaissent d'eux mme. Ceci limine toute une classe de
(comme on le verra plus tard, les rfrences peuvent aussi tre initialises lors de la
problmes de programmation : les soi-disant fuites de mmoire qui arrivent
dfinition).
quand un programmeur oublie de librer la mmoire.
Chaque objet met ses donnes membres dans sa zone de mmoire propre, les
donnes membres ne sont pas partages entre les objets. Voici un exemple de classe
Crer de nouveaux types de avec des donnes membres :
donnes : class class DataOnly {
int i;
float f;
Si tout est objet, qu'est-ce qui dfinit quoi ressemble une classe particulire boolean b;
}
d'objets et comment elle se comporte ? Autrement dit, qu'est-ce qui constitue le type
d'un objet ? On pourrait s'attendre avoir un mot-clef appel type , et cela serait
parfaitement sens. Historiquement, toutefois, la plupart des langages orients objet Cette classe ne fait rien mais on peut crer un objet :
ont utilis le mot-clef class qui signifie je vais dcrire quoi ressemble un DataOnly d = new DataOnly();
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 55/459
On peut affecter des valeurs aux donnes membres mais il faut d'abord savoir le fait pas), ce qui supprime une source de bugs. Toutefois, cette valeur initiale peut
comment faire rfrence un membre d'un objet. Ceci s'effectue en indiquant le ne pas tre correcte ou mme lgale pour le programme qui est crit. Il est
nom de la rfrence l'objet, suivi par un point, suivi par le nom du membre dans prfrable de toujours initialiser explicitement les variables.
l'objet :
Cette garantie ne s'applique pas aux variables locales -- celles qui ne sont pas des
objectReference.member champs d'une classe. Ainsi, si dans la dfinition d'une fonction, on a :
int x;
Par exemple :
d.i = 47; Alors x aura une valeur arbitraire (comme en C et C++), il ne sera pas initialis
d.f = 1.1f; automatiquement zro. On a la responsabilit d'affecter une valeur approprie
d.b = false;
avant d'utiliser x. Si on oublie de le faire, Java est sans aucun doute mieux conu
que C++ sur ce point : on obtient une erreur de compilation qui dit que la variable
Il est aussi possible que l'objet puisse contenir d'autres objets qui contiennent des pourrait ne pas tre initialise (avec beaucoup de compilateurs C++ on a des
donnes que l'on souhaite modifier. Pour cela il suffit de continuer associer les avertissements concernant les variables non initialises, mais avec Java ce sont des
points . Par exemple : erreurs).
myPlane.leftTank.capacity = 100;
La classe DataOnly ne peut pas faire grand chose part contenir des donnes car
Mthodes, paramtres et valeurs de
elle n'a pas de fonctions membres (mthodes). Pour comprendre comment celles-ci
fonctionnent il faut d'abord comprendre les notions de paramtres et de valeurs de
retour
retour, qui seront brivement dcrites.
Jusqu' prsent le terme fonction a t employ pour dsigner une sous-routine
nomme. Le terme qui est plus gnralement employ en Java est mthode, en tant
Valeurs par dfaut des membres primitifs que moyen de faire quelque chose . Il est possible, si on le souhaite, de continuer
raisonner en terme de fonctions. Il s'agit simplement d'une diffrence de syntaxe,
Quand une donne d'un type primitif est membre d'une classe on est assur qu'elle a mais partir de maintenant on utilisera mthode plutt que fonction, dans ce
une valeur par dfaut si on ne l'initialise pas : livre.
Type primitif Valeur par dfaut Les mthodes en Java dfinissent les messages qu'un objet peut recevoir. Dans cette
partie on verra quel point il est simple de dfinir une mthode.
boolean false
Les lments fondamentaux d'une mthode sont le nom, les paramtres, le type de
char `\u0000' (null) retour et le corps. Voici la forme de base :
byte (byte)0 returnType methodName( /* liste de paramtres */ ) {
short (short)0 /* corps de la mthode */
}
int 0
long 0L Le type de retour est le type de la valeur qui est retourne par la mthode aprs son
appel. La liste de paramtres donne le type et le nom des informations qu'on
float 0.0f souhaite passer la mthode. L'association du nom de la mthode et de la liste de
double 0.0d paramtres identifie de faon unique la mthode.
Par prudence, il faut remarquer que les valeurs par dfaut sont celles que Java En Java, les mthodes ne peuvent tre cres que comme une composante d'une
garantit quand la variable est utilise comme un membre d'une classe. Ceci assure classe. Une mthode ne peut tre appele que pour un objet [22] et cet objet doit
que les variables membres de type primitif sont toujours initialises (parfois C++ ne tre capable de raliser cet appel de mthode. Si on essaye d'appeler une mauvaise
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 56/459
mthode pour un objet, on obtient un message d'erreur lors de la compilation. On valeur, cette valeur est place juste aprs la dclaration du return. Dans le cas
appelle une mthode pour un objet en nommant l'objet suivi d'un point, suivi du prsent, la valeur de retour est produite en valuant l'expression s.length( ) * 2.
nom de la mthode et de sa liste d'arguments, comme a :
On peut retourner des valeurs de tous les types qu'on souhaite, mais si on souhaite
objectName.methodName(arg1, arg2, arg3). Par exemple, si on suppose
ne rien retourner du tout on peut le faire en indiquant que la mthode retourne
qu'on a une mthode f( ) qui ne prend aucun paramtre et qui retourne une valeur
void. Voici quelques exemples :
de type int. Alors, si on a un objet appel a pour lequel f( ) peut tre appel, on peut
crire : boolean flag() { return true; }
float naturalLogBase() { return 2.718f; }
int x = a.f(); void nothing() { return; }
void nothing2() {}
Le type de la valeur de retour doit tre compatible avec le type de x.
Quand le type de retour est void, alors le mot-clef return n'est utilis que pour
On appelle gnralement envoyer un message un objet cet acte d'appeler une
sortir de la mthode, il n'est donc pas ncessaire quand on atteint la fin de la
mthode. Dans l'exemple prcdent le message est f() et l'objet est a. La
mthode. On peut retourner d'une mthode n'importe quel endroit mais si on a
programmation oriente objet est souvent simplement ramene envoyer des
indiqu un type de retour qui n'est pas void alors le compilateur imposera (avec des
messages des objets .
messages d'erreur) un retour avec une valeur d'un type appropri sans tenir compte
de l'endroit auquel le retour se produit.
La liste de paramtres ce point, on peut penser qu'un programme n'est qu'un paquet d'objets avec des
mthodes qui prennent d'autres objets en paramtres pour transmettre des
La liste de paramtres de la mthode spcifie quelles informations on passe la messages ces autres objets. C'est effectivement l'essentiel de ce qui se passe mais
mthode. Comme on peut le supposer, ces informations -- comme tout le reste en dans les chapitres suivants on verra comment faire le travail de bas niveau en
Java -- sont sous la forme d'objets. On doit donc indiquer dans la liste de prenant des dcisions au sein d'une mthode. Pour ce chapitre, envoyer des
paramtres les types des objets transmettre et les noms employer pour chacun. messages est suffisant.
Comme dans toutes les situation o on a l'impression de manipuler des objets, en
Java on passe effectivement des rfrences name="fnB23">[23]. Toutefois, le type
de la rfrence doit tre correct. Si le paramtre est cens tre un objet de type Construction d'un programme Java
String, ce qu'on transmet doit tre de ce type.
Considrons une mthode qui prend un objet de classe String en paramtre. Voici Il y a plusieurs autres lments comprendre avant de voir le premier programme
la dfinition qui doit tre mise l'intrieur de la dfinition d'une classe pour qu'elle Java.
soit compile :
int storage(String s) { Visibilit des noms
return s.length() * 2;
}
Un problme commun tous les langages de programmation est le contrle des
noms. Si on utilise un nom dans un module du programme et si un autre
Cette mthode indique combien d'octets sont ncessaires pour contenir une String programmeur utilise le mme nom dans un autre module, comment distingue-t-on
donne (chaque char dans une String fait 16 bits, ou deux octets, pour permettre un nom d'un autre et comment empche-t-on les collisions de noms ? En C c'est
les caractres Unicode). Le paramtre est de type String et il est appel s. Une fois un problme particulier car un programme est souvent un ocan de noms
que s est pass une mthode, il peut tre trait comme n'importe quel autre objet incontrlable. Les classes C++ (sur lesquelles les classes Java sont bases)
(on peut lui envoyer des messages). Ici, on appelle la mthode length( ) qui est une imbriquent les fonctions dans les classes de telle sorte qu'elles ne peuvent pas entrer
des mthodes de la classe String ; elle retourne le nombre de caractres que en collision avec les noms de fonctions imbriqus dans d'autres classes. Toutefois,
contient la chane. C++ autorise toujours les donnes et les fonctions globales, donc les collisions sont
On peut aussi voir l'utilisation du mot-clef return qui fait deux choses. D'abord, il toujours possibles. Pour rsoudre ce problme, C++ a introduit les domaines de
signifie quitte la mthode, j'ai termin . Ensuite, si la mthode retourne une noms (namespace) en utilisant des mots-clefs supplmentaires.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 57/459
Java a pu viter tout cela en employant une approche originale. Pour gnrer sans sont fournies avec le compilateur. Avec celles-ci il n'y a pas se tracasser propos
ambigut un nom pour une bibliothque, le spcificateur utilis n'est pas trs des longs noms de domaines inverss ; il suffit de dire, par exemple :
diffrent d'un nom de domaine Internet. En fait, les crateurs de Java veulent qu'on import java.util.ArrayList;
utilise son propre nom de domaine Internet invers, puisqu'on est assur que ceux-
ci sont uniques. Puisque mon nom de domaine est BruceEckel.com, ma
bibliothque d'utilitaires (utility) pour mes marottes (foibles) devrait tre appele pour dire au compilateur que l'on veut utiliser la classe Java ArrayList. Toutefois,
com.bruceeckel.utility.foibles. Aprs avoir invers le nom de domaine, les util contient de nombreuses classes et on pourrait vouloir utiliser plusieurs d'entre
points sont destins reprsenter des sous-rpertoires. elles sans les dclarer explicitement. Ceci est facilement ralis en utilisant '*' pour
indiquer un joker :
Dans Java 1.0 et Java 1.1 les extensions de domaines com, edu, org, net, etc. taient import java.util.*;
mises en lettres capitales par convention, ainsi la bibliothque serait :
COM.bruceeckel.utility.foibles. Toutefois, au cours du dveloppement de Java
2, on s'est rendu compte que cela causait des problmes et par consquent les noms Il est plus courant d'importer une collection de classes de cette manire que
de packages sont entirement en lettres minuscules. d'importer les classes individuellement.
Ce mcanisme signifie que tous les fichiers existent automatiquement dans leur
propre domaine de nom et toutes les classe contenues dans un fichier donn doivent Le mot-clef static
avoir un identificateur unique. Ainsi, on n'a pas besoin d'apprendre de particularits
spcifiques au langage pour rsoudre ce problme -- le langage s'en occupe votre Normalement, quand on cre une classe, on dcrit ce quoi ressemblent les objets
place. de cette classe et comment ils se comportent. Rien n'existe rellement avant de crer
un objet de cette classe avec new ; ce moment la zone de donnes est cre et les
mthodes deviennent disponibles.
Utilisation d'autres composantes
Mais il y a deux situation pour lesquelles cette approche n'est pas suffisante. L'une,
Lorsqu'on souhaite utiliser une classe prdfinie dans un programme, le si on veut avoir une zone de stockage pour des donnes spcifiques, sans tenir
compilateur doit savoir comment la localiser. Bien entendu, la classe pourrait dj compte du nombre d'objets crs, ou mme si aucun objet n'a t cr. L'autre, si on
exister dans le mme fichier source que celui d'o elle est appele. Dans ce cas on a besoin d'une mthode qui n'est associe aucun objet particulier de la classe. C'est
utilise simplement la classe -- mme si la classe n'est dfinie que plus tard dans le dire si on a besoin d'une mthode qui puisse tre appele mme si aucun objet n'a
fichier. Java limine le problme des rfrence anticipes , il n'y a donc pas s'en t cr. On peut obtenir ces deux effets avec le mot-clef static. Dire que quelque
proccuper. chose est static signifie que la donne ou la mthode n'est pas spcifiquement
rattache un objet instance de cette classe. Donc, mme si aucun objet de cette
Qu'en est-il des classes qui existent dans un autre fichier ? On pourrait penser que le classe n'a jamais t cr il est possible d'appeler une mthode static ou d'accder
compilateur devrait tre suffisamment intelligent pour aller simplement la chercher une donne static. Avec des donnes et des mthodes non static ordinaires il faut
lui mme, mais il y a un problme. Imaginons que l'on veuille utiliser une classe connatre l'objet spcifique avec lequel elles fonctionnent. Bien entendu, tant
ayant un nom spcifique mais qu'il existe plus d'une classe ayant cette dfinition (il donn que les mthodes static n'ont pas besoin qu'un objet soit cr avant d'tre
s'agit probablement de dfinitions diffrentes). Ou pire, imaginons que l'on crive utilises, elles ne peuvent pas accder directement des membres ou des mthodes
un programme et qu'en le crant on ajoute sa bibliothque une nouvelle classe qui non static en appelant ces autres membres sans faire rfrence un objet nomm
entre en conflit avec le nom d'une classe dj existante. (puisque les membres et mthodes non static doivent tre rattachs un objet
Pour rsoudre ce problme il faut liminer les ambiguts potentielles. Ceci est spcifique).
ralis en disant exactement au compilateur Java quelles classes on souhaite, en Certains langages orients objet emploient les expressions donnes de classe et
utilisant le mot-clef import. import dit au compilateur d'introduire un package mthodes de classe, ce qui signifie que les donnes et les mthodes n'existent que
qui est une bibliothque de classes (dans d'autres langages, une bibliothque pour la classe en tant que tout et pas pour des objets particuliers de la classe. Parfois
pourrait comporter des fonctions et des donnes au mme titre que des classes mais la littrature Java utilise aussi ces expressions.
il faut se rappeler que tout le code Java doit tre crit dans des classes).
Pour rendre statique une mthode ou une donne membre il suffit de mettre le mot-
La plupart du temps on utilise des composantes des bibliothques Java standard qui
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 58/459
clef static avant la dfinition. Par exemple, le code suivant cre une donne Alors que static, lorsqu'il est appliqu une donne membre, change sans aucun
membre static et l'initialise : doute la faon dont la donne est cre (une pour chaque classe par opposition
class StaticTest { une pour chaque objet dans le cas des donnes non statiques), lorsqu'il est appliqu
static int i = 47; une mthode, le changement est moins significatif. Un cas important d'utilisation
} des mthodes static est de permettre d'appeler cette mthode sans crer d'objet.
C'est essentiel, comme nous le verrons, dans la dfinition de la mthode main( )
Maintenant, mme en crant deux objet StaticTest, il n'y aura qu'une seule zone de qui est le point d'entre pour excuter une application.
stockage pour StaticTest.i. Tous les objets partageront le mme i. Considrons : Comme pour toute mthode, une mthode statique peut crer ou utiliser des objets
StaticTest st1 = new StaticTest(); nomms de son type, ainsi les mthodes statiques sont souvent utilises comme
StaticTest st2 = new StaticTest(); berger pour un troupeau d'instances de son propre type.
ce point, st1.i et st2.i ont la mme valeur 47 puisqu'elles font rfrence la mme
zone mmoire. Votre premier programme Java
Il y a deux faons de faire rfrence une variable static. Comme indiqu ci-dessus,
Voici enfin notre premier programme . Il commence par crire une chane de
il est possible de la nommer via un objet, en disant par exemple st2.i. Il est aussi
caractres, puis il crit la date en utilisant la classe Date de la bibliothque standard
possible d'y faire rfrence directement par le nom de la classe, ce qui ne peut pas
de Java. Il faut remarquer qu'un style de commentaire supplmentaire est introduit
tre fait avec un membre non static (c'est le moyen de prdilection pour faire
ici : le '//' qui est un commentaire jusqu' la fin de la ligne.
rfrence une variable static puisque cela met en vidence la nature static de la
variable). // HelloDate.java
import java.util.*;
StaticTest.i++; public class HelloDate {
public static void main(String[] args) {
System.out.println("Hello, it's: ");
L'oprateur ++ incrmente la variable. ce point, st1.i et st2.i auront tous deux la System.out.println(new Date());
valeur 48. }
}
Une logique similaire s'applique aux mthodes statiques. On peut faire rfrence
une mthode statique soit par l'intermdiaire d'un objet, comme on peut le faire
avec n'importe quelle mthode, ou avec la syntaxe spcifique supplmentaire #/TIJ_PAGE02# #TIJ_PAGE03#
ClassName.method( ). Une mthode statique est dfinie de faon similaire : Au dbut de chaque fichier de programme il faut mettre la dclaration import pour
class StaticFun { importer toutes les classes supplmentaires qui seront ncessaires pour le code dans
static void incr() { StaticTest.i++; } ce fichier. Il faut noter que je dis supplmentaires ; c'est parce qu'il y a une
} bibliothque de classes qui est automatiquement importe dans tous les fichiers
Java : java.lang. En dmarrant un browser Web et en chargeant la documentation
On peut voir que la mthode incr( ) de StaticFun incrmente la donne static i. de Sun (si elle n'a pas t tlcharge de java.sun.com ou si la documentation Java
On peut appeler incr( ) de faon classique, par le biais d'un objet : n'a pas encore t installe, il faut le faire maintenant), si on regarde la liste des
StaticFun sf = new StaticFun(); package, on voit toutes les bibliothques de classes qui sont fournies avec Java.
sf.incr(); Slectionnons java.lang. Ceci fait apparatre la liste de toutes les classes contenues
dans cette bibliothque. tant donn que java.lang est implicitement inclus dans
Ou, parce que incr( ) est une mthode statique, il est possible de l'appeler tous les fichiers source Java, ces classes sont automatiquement disponibles. Il n'y a
directement par sa classe : pas de classe Date dans java.lang, ce qui veut dire qu'il faut importer une autre
bibliothque pour l'utiliser. Si on ne sait pas dans quelle bibliothque se trouve une
StaticFun.incr(); classe donne, ou si on veut voir toutes les classes, on peut slectionner Tree
dans la documentation Java. Maintenant on peut trouver n'importe laquelle des
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 59/459
classes fournies avec Java. On peut alors utiliser la fonction chercher du browser que vous utilisez le JDK de Sun qui est gratuit. Si vous utilisez un autre systme de
pour trouver Date. Une fois que c'est fait on voit qu'elle est connue en tant que dveloppement, vous devrez vous reporter la documentation de ce systme pour
java.util.Date, ce qui permet de savoir qu'elle se trouve dans la bibliothque util et savoir comment compiler et excuter les programmes.
qu'il faut dclarer import java.util.* de faon pouvoir utiliser Date.
Connectez vous Internet et allez sur http://java.sun.com. L, vous trouverez des
Si on retourne au dbut pour slectionner java.lang puis System, on voit que la informations et des liens qui vous guideront pour tlcharger et installer le JDK
classe System a plusieurs champs et si on slectionne out on dcouvre que c'est un pour votre plate-forme.
objet static PrintStream. Puisqu'il est statique, on n'a pas besoin de crer quoique
Une fois que le JDK est install et que vous avez configur les informations relatives
ce soit. L'objet out est toujours l et il suffit de l'utiliser. Ce qu'on peut faire avec
au chemin sur votre ordinateur afin qu'il puisse trouver javac et java, tlchargez et
out est dfini par son type : PrintStream. D'une faon trs pratique,
dcompressez le code source de ce livre (on peut le trouver sur le CD-ROM qui est
PrintStream est affich dans la description comme un hyper lien, ainsi, en
livr avec le livre ou sur www.BruceEckel.com). Ceci crera un sous rpertoire pour
cliquant dessus on voit la liste de toutes les mthodes qu'on peut appeler pour
chacun des chapitres de ce livre. Allez dans le sous-rpertoire c02 et tapez :
PrintStream. Il y en a un certain nombre et elles seront dcrites ultrieurement
dans ce livre. Pour l'instant nous ne nous intressons qu' println( ), qui veut dire javac HelloDate.java
crit ce que je te donne sur la console et passe la ligne . Ainsi, dans tout
programme Java on peut dire System.out.println("quelque chose") chaque Cette commande ne devrait produire aucune rponse. Si vous obtenez un message
fois qu'on souhaite crire quelque chose sur la console. d'erreur de quelque sorte que ce soit cela signifie que vous n'avez pas install le JDK
Le nom de la classe est le mme que celui du fichier. Quand on cre un programme correctement et que vous devez corriger le problme.
autonome comme celui-l une des classes du fichier doit avoir le mme nom que le Par contre, si vous obtenez simplement votre invite de commande vous pouvez
fichier (le compilateur se plaint si on ne le fait pas). Cette classe doit contenir une taper :
mthode appele main( ) avec la signature suivante :
java HelloDate
public static void main(String[] args);
et vous obtiendrez en sortie le message ainsi que la date.
Le mot-clef public signifie que la mthode est accessible au monde extrieur (dcrit
en dtail dans le chapitre 5). Le paramtre de main( ) est un tableau d'objets de C'est le procd que vous pouvez employer pour compiler et excuter chacun des
type String. Le paramtre args n'est pas utilis dans ce programme mais le programmes de ce livre. Toutefois, vous verrez qe le code source de ce livre a aussi
compilateur Java insiste pour qu'il soit l car il contient les paramtres invoqus sur un fichier appel makefile dans chaque chapitre, et celui-ci contient les
la ligne de commande. commandes make pour construire automatiquement les fichiers de ce chapitre.
Reportez-vous la page Web de ce livre sur www.BruceEckel.com pour plus de
La ligne qui crit la date est assez intressante : dtails sur la manire d'utiliser ces makefiles.
System.out.println(new Date());
Considrons le paramtre : un objet Date est cr juste pour transmettre sa valeur
Commentaires et documentation
println( ). Ds que cette instruction est termine, cette date est inutile et le intgre
ramasse-miettes peut venir le rcuprer n'importe quand. On n'a pas s'occuper de
s'en dbarrasser.
Il y a deux types de commentaires en Java. Le premier est le commentaire
traditionnel, style C, dont a hrit C++. Ces commentaires commencent par /* et
Compilation et excution continuent, ventuellement sur plusieurs lignes, jusqu' un */. Il faut remarquer que
de nombreux programmeurs commencent chaque ligne de continuation de
Pour compiler et excuter ce programme, et tous les autres programmes de ce livre, commentaire avec *, on voit donc souvent :
il faut d'abord avoir un environnement de programmation Java. Il y a un grand /* Ceci est un commentaire
nombre d'environnements de dveloppement mais dans ce livre nous supposerons * qui continue
* sur plusieurs lignes
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 60/459
*/
Syntaxe
Il faut toutefois se rappeler que tout ce qui se trouve entre /* et */ est ignor, il n'y a
donc aucune diffrence avec : Toutes les commandes javadoc n'apparaissent que dans les commentaires /**. Les
commentaires finissent avec */ comme d'habitude. Il y a deux principales faons
/* Ceci est un commentaire qui d'utiliser javadoc : du HTML intgr ou des onglets doc . Les onglets doc sont des
continue sur plusieurs lignes */
commandes qui commencent avec un '@' et qui sont places au dbut d'une ligne de
commentaire (toutefois, un '*' en tte est ignor).
La seconde forme de commentaires vient du C++. C'est le commentaire sur une
seule ligne qui commence avec // et continue jusqu' la fin de la ligne. Ce type de Il y a trois types de commentaires de documentation qui correspondent aux
commentaire est pratique et souvent rencontr car il est simple. Il n'y a pas se lments suivant le commentaire : classe, variable ou mthode. C'est dire qu'un
dmener sur le clavier pour trouver / puis * ( la place il suffit d'appuyer deux fois commentaire de classe apparat juste avant la dfinition de la classe, un
sur la mme touche) et il n'est pas ncessaire de fermer le commentaire. On trouve commentaire de variable apparat juste avant la dfinition de la variable et un
donc frquemment : commentaire de mthode apparat juste avant la dfinition de la mthode. Voici un
exemple simple :
// Ceci est un commentaire sur une seule ligne
/** Un commentaire de classe */
public class docTest {
Commentaires de documentation /** Un
public
commentaire de variable */
int i;
/** Un commentaire de mthode */
Un des plus solides lments de Java est que les concepteurs n'ont pas considr public void f() {}
que l'criture du code est la seule activit importante -- ils ont aussi pens sa }
documentation. Le plus gros problme avec la documentation de code est
probablement la maintenance de cette documentation. Si la documentation et le Il faut noter que javadoc ne traite les commentaires de documentation que pour les
code sont spars, a devient embtant de changer la documentation chaque fois membres public et protected. Les commentaires pour les membres private et
que le code change. La solution a l'air simple : relier le code et la documentation. Le amis (voir Chapitre 5) sont ignors et on ne verra aucune sortie (toutefois on
moyen le plus simple de le faire est de tout mettre dans le mme fichier. Toutefois, peut utiliser le flag private pour inclure aussi les membres private). Ceci est sens
pour complter le tableau il faut une syntaxe de commentaire particulire pour puisque seuls les membres public et protected sont accessibles en dehors du
marquer la documentation particulire et un outil pour extraire ces commentaires et fichier, ce qui est la perspective du client du programmeur. Toutefois, tous les
les mettre sous une forme exploitable. C'est ce que Java a fait. commentaires de classe sont inclus dans le fichier de sortie.
L'outil pour extraire les commentaires est appel javadoc. Il utilise certaines La sortie du code prcdent est un fichier HTML qui a le mme format standard que
technologies du compilateur Java pour rechercher les marqueurs spcifiques des tout le reste de la documentation Java, ainsi les utilisateurs seront l'aise avec le
commentaires qui ont t mis dans les programmes. Il ne se contente pas d'extraire format et pourront facilement naviguer dans les classes. a vaut la peine de taper le
les informations repres par ces marqueurs, mais il extrait aussi le nom de classe code prcdent, de le passer dans javadoc et d'tudier le fichier HTML rsultant
ou le nom de mthode adjoint au commentaire. Ainsi on parvient avec un travail pour voir le rsultat.
minimal gnrer une documentation de programme convenable.
La sortie de javadoc est un fichier HTML qui peut tre visualis avec un browser HTML intgr
Web. Cet outil permet de crer et maintenir un unique fichier source et gnrer
automatiquement une documentation utile. Grce javadoc on a un standard pour Javadoc passe les commandes HTML dans les documents HTML gnrs. Ceci
crer la documentation et il est suffisamment simple pour qu'on puisse esprer ou permet une utilisation complte de HTML, la motivation principale tant de
mme exiger une documentation avec toute bibliothque Java. permettre le formatage du code comme suit :
/**
* <pre>
* System.out.println(new Date());
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 61/459
* </pre>
*/
@version
On peut aussi utiliser HTML comme on pourrait le faire dans n'importe quel autre Voici le format :
document Web pour formater du texte courant dans les descriptions : @version version-information
/**
* On peut <em>mme</em> insrer une liste : dans lequel version-information est n'importe quelle information significative
* <ol> que l'on souhaite inclure. Quand le flag -version est mis sur la ligne de commande
* <li> lment un de javadoc, les informations de version seront exploites, particulirement dans la
* <li> lment deux
* <li> lment trois documentation HTML.
* </ol>
*/ @author
Il faut noter que dans les commentaires de documentation, les astrisques en dbut Voici le format :
de ligne sont limins par javadoc, ainsi que les espaces en tte de ligne. Javadoc
reformate tout pour assurer la conformit avec l'apparence des documentations @author author-information
standard. Il ne faut pas utiliser des titres tels que <h1> ou <hr> dans le HTML
intgr car javadoc insre ses propres titres et il y aurait des interfrences. dans lequel author-information est, a priori, votre nom mais il peut aussi
contenir une adresse email ou toute autre information approprie. Quand le flag
Tous les types de commentaires de documentation -- classes, variables et mthodes -author est mis sur la ligne de commande javadoc, les informations sur l'auteur
-- acceptent l'intgration de HTML. seront exploites, particulirement dans la documentation HTML.
On peut avoir plusieurs onglets d'auteur pour une liste d'auteurs mais ils doivent
@see : faire rfrence aux autres classes tre placs conscutivement. Toutes les informations d'auteurs seront regroupes
dans un unique paragraphe dans le code HTML gnr.
Les trois types de commentaires de documentation (classes, variables et mthodes)
peuvent contenir des onglets @see, qui permettent de faire rfrence de la @since
documentation dans d'autres classes. Javadoc gnrera du HTML o les onglets
@see seront des hyper liens vers d'autres documentations. Les diffrentes formes
sont : Cet onglet permet d'indiquer la version du code qui a commenc utiliser une
caractristique particulire. On la verra apparatre dans la documentation HTML de
@see classname Java pour indiquer quelle version de JDK erst utilise.
@see fully-qualified-classname
@see fully-qualified-classname#method-name
Les onglets de documentation de variables
Chacune d'entre elles ajoute un hyper lien de type Voir aussi la documentation
gnre. Javadoc ne vrifie pas si l'hyper lien indiqu est valide. Les documentations de variables ne peuvent contenir que du HTML intgr et des
rfrences @see.
Class documentation tags
Les onglets de documentation de mthodes
En plus du HTML intgr et des rfrences @see, les documentations de classe
peuvent inclure des onglets pour les informations de version et pour le nom de En plus du HTML intgr et des rfrences @see, les mthodes acceptent des
l'auteur. Les documentations de classe peuvent aussi tre utilises pour les onglets de documentation pour les paramtres, les valeurs de retour et les
interfaces (voir Chapitre 8). exceptions.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 62/459
@param @deprecated
Voici le format : Ceci est utilis pour marquer des fonctionnalits qui ont t remplaces par d'autres
@param parameter-name description qui sont meilleures. L'onglet deprecated suggre de ne plus utiliser cette
fonctionnalit particulire tant donn qu'elle sera probablement supprime
ultrieurement. Une mthode marque @deprecated fait produire un warning par
dans lequel parameter-name est l'identificateur dans la liste de paramtres et le compilateur si elle est utilise.
description est du texte qui peut se prolonger sur les lignes suivantes. La
description est considre comme termine quand un nouvel onglet de
documentation est trouv. On peut en avoir autant qu'on veut, a priori un pour Exemple de documentation
chaque paramtre.
Voici nouveau le premier programme Java, cette fois aprs avoir ajout les
@return commentaires de documentation :
//: c02:HelloDate.java
Voici le format : import java.util.*;
/** Le premier exemple de programme de Thinking in Java.
@return description * Affiche une chane de caractres et la date du jour.
* @author Bruce Eckel
* @author
dans lequel description indique la signification de la valeur de retour. Le texte http://
peut se prolonger sur les lignes suivantes. www.BruceEckel.com
* @version 2.0
@throws */
public class HelloDate {
/** Unique point d'entre de la classe et de l'application
Les exceptions seront introduites dans le Chapitre 10 mais, brivement, ce sont des * @param args tableau de paramtres sous forme de chanes
objets qui peuvent tre mis (thrown) par une mthode si cette mthode choue. de caractres
* @return Pas de valeur de retour
Bien qu'une seule exception puisse surgir lors de l'appel d'une mthode, une * @exception exceptions Pas d'exceptions mises
mthode donne est susceptible de produire n'importe quel nombre d'exceptions de */
types diffrents, chacune d'entre elles ncessitant une description. Ainsi, le format public static void main(String[] args) {
de l'onglet d'exception est : System.out.println("Hello, it's: ");
System.out.println(new Date());
@throws fully-qualified-class-name description }
} ///:~
dans lequel fully-qualified-class-name indique sans ambiguit un nom de classe
d'exception qui est dfinie quelque part, et description (qui peut se prolonger sur La premire ligne du fichier utilise une technique personnelle qui consiste mettre
les lignes suivantes) prcise pourquoi ce type particulier d'exception peut survenir un ':' comme marqueur spcifique pour la ligne de commentaire contenant le nom
lors de l'appel de la mthode. du fichier source. Cette ligne contient le chemin du fichier (dans ce cas, c02 indique
le Chapitre 2) suivi du nom de fichier [25]. La dernire ligne finit aussi avec un
commentaire et celui-ci indique la fin du listing du code source, ce qui permet de
l'extraire automatiquement du texte de ce livre et de le contrler avec un
compilateur.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 63/459
Style de programmation hello, world qui affiche simplement cette phrase. Vous n'avez besoin que
d'une seule mthode dans la classe (la mthode main qui est excute
quand le programme dmarre). Pensez la rendre static et indiquer la
Le standard non officiel de Java consiste mettre en majuscule la premire lettre liste de paramtres, mme si la liste de paramtres n'est pas utilise.
des noms de classes. Si le nom de classe est compos de plusieurs mots, ils sont Compilez ce programme avec javac. Si vous utilisez un environnement de
accols (c'est dire qu'on ne spare pas les noms avec un trait bas) et la premire dveloppement autre que JDK, apprenez compiler et excuter les
lettre de chaque mot est mise en majuscule ainsi : programmes dans cet environnement.
2. Trouver le morceau de code concernant ATypeName et faites-en un
class AllTheColorsOfTheRainbow { // ...
programme qui compile et s'excute.
3. Transformez le morceau de code DataOnly en un programme qui compile et
Pour pratiquement tout les reste : mthodes, champs (variables membres) et les qui s'excute.
noms des rfrences d'objets, le style retenu est comme pour les classes sauf que la 4. Modifiez l'exercice 3 de telle sorte que les valeurs des donnes dans
premire lettre de l'identificateur est une minuscule. Par exemple : DataOnly soient affectes et affiches dans main( ).
class AllTheColorsOfTheRainbow { 5. crivez un programme qui inclus et appelle la mthode storage( ) dfinie
int anIntegerRepresentingColors; comme morceau de code dans ce chapitre.
void changeTheHueOfTheColor(int newHue) { 6. Transformez le morceau de code StaticFun en un programme qui
// ...
} fonctionne.
// ... 7. crivez un programme qui imprime trois paramtres saisis sur la ligne de
} commande. Pour faire ceci il faut indexer le tableau de String reprsentant
la ligne de commande.
Bien entendu il faut se rappeler que l'utilisateur doit aussi taper tous ces longs 8. Transformez l'exemple AllTheColorsOfTheRainbow en un programme
noms, donc soyez clment. qui compile et s'excute.
9. Trouvez le code de la seconde version de HelloDate.java qui est le petit
Le code Java qu'on voit dans les bibliothques de Sun respecte aussi le placement exemple de commentaire de documentation. Excutez javadoc sur le fichier
des accolades ouvrantes et fermantes qui est utilis dans ce livre. et visualisez le rsultat avec votre browser Web.
#/TIJ_PAGE03# #TIJ_PAGE04# 10. Transformez docTest en un fichier qui compile et excutez javadoc dessus.
Contrlez la documentation qui en rsulte avec votre browser Web.
11. Ajoutez une liste d'lments en HTML, la documentation de l'exercice 10.
Sommaire 12. Prenez le programme de l'exercice 1 et ajoutez lui une documentation.
Sortez cette documentation dans un fichier HTML l'aide de javadoc et
visualisez la avec votre browser Web.
Dans ce chapitre on en a vu suffisamment sur la programmation Java pour
comprendre comment crire un programme simple et on a eu une vue d'ensemble [21] Ceci peut tre une poudrire. Il y a ceux qui disent c'est clairement un
du langage et de certaines des ides de base. Toutefois, les exemples vus jusqu' pointeur , mais ceci suppose une implmentation sous-jacente. De plus, les
prsent ont tous t du type faire ceci, puis faire cela, puis faire autre chose . rfrences Java sont plutt apparentes aux rfrences C++ qu'aux pointeurs dans
Qu'en advient-il si on veut faire un programme pour raliser des choix, comme dans leur syntaxe. Dans la premire dition de ce livre, j'ai choisi d'inventer un nouveau
si le rsultat de ceci est rouge, faire cela, sinon faire autre chose ? Les outils terme, manipulateur (handle), car les rfrences C++ et les rfrences Java ont
disponibles en Java pour cette activit de programmation fondamentale seront vus des diffrences importantes. Je venais du C++ et je ne voulais pas embrouiller les
dans le prochain chapitre. programmeurs C++ que je supposais tre le principal public de Java. Dans la
seconde dition, j'ai dcid que rfrence tait le terme le plus gnralement
utilis et que tous ceux qui venaient du C++ auraient s'occuper de bien d'autres
Exercices choses que de la terminologie de rfrence, donc qu'ils pourraient aussi bien y
plonger les deux pieds en avant. Toutefois, il y a des gens qui ne sont pas d'accord,
1. En suivant l'exemple HelloDate.java de ce chapitre, crez un programme mme avec le terme rfrence . J'ai lu dans un livre qu'il tait compltement
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 64/459
faux de dire que Java supportait les passages par rfrences , parce que les 2000 by Bruce Eckel
identificateurs des objets Java (selon cet auteur) sont en fait des rfrences des
objets . Et (continue-t-il) tout est en fait pass par valeur. Donc on ne passe pas
une rfrence, on passe une rfrence un objet, par valeur . On pourrait 3 : Contrle du Flux de
discuter de la prcision d'une explication si alambique mais je pense que mon
approche simplifie la comprhension du concept sans blesser qui que ce soit Programme
(d'accord, les avocats du langage pourraient prtendre que je mens, mais je
rpondrai que je fournis une abstraction approprie).
Tout comme une crature sensible, un programme doit agir
[22] Les mthodes static, que nous dcouvrirons ultrieurement, peuvent tre
appeles pour la classe, sans passer par un objet. sur son environnement et faire des choix durant sa vie.
[23] Avec les exceptions habituelles pour les types de donnes prcits boolean, En Java les objets et les donnes sont manipuls au moyen d'oprateurs, et les choix
char, byte, short, int, long, float, et double. En gnral, toutefois, on passe des sont faits au moyen des instructions de contrle d'excution. Java a hrit de C++,
objets, ce qui veut dire qu'en ralit on passe des rfrences des objets. c'est pourquoi beaucoup d'instructions seront familires aux programmeurs C et
C++. Java a galement amen quelques amliorations et aussi quelques
[24] Certains environnements de programmations feront apparatre brivement le simplifications.
programme l'cran et le fermeront avant d'avoir eu une chance de voir le rsultat.
On peut mettre le morceau de code suivant la fin du main( ) pour obtenir une Si vous avez l'impression de patauger quelque peu dans ce chapitre, voyez le CD
pause sur la sortie : ROM multimdia fourni avec le livre : Thinking in C : Foundations for Java and
C++. Il contient des cours audio, des diapositives, des exercices, et des solutions, le
try {
System.in.read();
tout spcialement conu pour vous familiariser rapidement avec la syntaxe C
} catch(Exception e) {} ncessaire pour apprendre Java.
Cette pause durera jusqu' ce qu'on appuye sur Entre (ou toute autre touche).
Ce code met en jeu des concepts qui ne seront introduits que bien plus tard dans ce
Utilisation des oprateurs Java
livre, donc vous ne le comprendrez pas d'ici l, mais il fera l'affaire.
Un oprateur agit sur un ou plusieurs arguments pour produire une nouvelle valeur.
[25] Un outil que j'ai cr avec Python (voir www.Python.org) utilise cette Les arguments se prsentent sous une forme diffrente de celle d'un appel de
information pour extraire les fichiers sources, les mettre dans les sous-rpertoires mthode standard, mais le rsultat est le mme. Votre exprience de
appropris et crer les makefiles. programmation antrieure a d vous familiariser avec les concepts gnraux des
#/TIJ_PAGE04# oprateurs. L'addition (+), la soustraction et le moins unaire (-), la multiplication
(*), la division (/), et l'affectation (=) fonctionnent de la mme manire dans tous les
"HTTP://WWW.W3.ORG/TR/HTML4/LOOSE.DTD"> #TIJ_PAGE01# langages de programmation.
05.07.01 - version 2.3 [Armel] Tous les oprateurs produisent une valeur partir de leurs oprandes. En outre, un
- Ajout des tags de sparation de pages pour le site.
15.06.2001 - version 2.2 [J-P Vidal] oprateur peut changer la valeur de l'un de ses oprandes. C'est ce qu'on appelle un
- prise en compte des corrections demandes par lsom@... effet de bord. L'utilisation la plus frquente des oprateurs modifiant leurs
28.04.2001 - version 2.1 [Armel] oprandes est justement de gnrer un effet de bord, mais dans ce cas il faut garder
- Remise en forme du code html (titres-hx[verdana], l'esprit que la valeur produite est disponible tout comme si on avait utilis
paragraphes-p[Georgia], code-blockquote). l'oprateur sans chercher utiliser son effet de bord.
25/06/2000 - version 2.0 [J-P Vidal]
- Dernire mise jour de la version franaise. Presque tous les oprateurs travaillent uniquement avec les types primitifs. Les
Traducteur : exceptions sont = , == et != , qui fonctionnent avec tous les objets (ce qui
- Jean-Pierre VIDAL
Texte original : est parfois droutant lorsqu'on traite des objets). De plus, la classe String admet les
-Thinking in Java, 2nd edition, Revision 10 oprateurs + et += .
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 65/459
Priorit int i;
}
public class Assignment {
public static void main(String[] args) {
La priorit des oprateurs rgit la manire d'valuer une expression comportant
Number n1 = new Number();
plusieurs oprateurs. Java a des rgles spcifiques qui dterminent l'ordre Number n2 = new Number();
d'valuation. La rgle la plus simple est que la multiplication et la division passent n1.i = 9;
avant l'addition et la soustraction. Souvent les programmeurs oublient les autres n2.i = 47;
rgles de priorit, aussi vaut-il mieux utiliser les parenthses afin que l'ordre System.out.println("1: n1.i: " + n1.i +
d'valuation soit explicite. Par exemple : ", n2.i: " + n2.i);
n1 = n2;
A = X + Y - 2/2 + Z; System.out.println("2: n1.i: " + n1.i +
", n2.i: " + n2.i);
n1.i = 27;
a une signification diffrente de la mme instruction dans laquelle certains termes System.out.println("3: n1.i: " + n1.i +
sont groups entre parenthses : ", n2.i: " + n2.i);
}
A = X + (Y - 2)/(2 + Z); } ///:~
L'affectation La classe Number est simple, main( ) en cre deux instances (n1 etand n2). La
valeur i de chaque Number est initialise diffremment, puis n2 est affect n1.
L'affectation est ralise au moyen de l'oprateur = . Elle signifie prendre la Dans beaucoup de langages de programmation on s'attendrait ce que n1 et n2
valeur se trouvant du ct droit (souvent appele rvalue) et la copier du ct gauche restent toujours indpendants, mais voici le rsultat de ce programme, d au fait
(souvent appele lvalue) . Une rvalue reprsente toute constante, variable ou qu'on a affect une rfrence :
expression capable de produire une valeur, mais une lvalue doit tre une variable 1: n1.i: 9, n2.i: 47
distincte et nomme (autrement dit, il existe un emplacement physique pour ranger 2: n1.i: 47, n2.i: 47
le rsultat). Par exemple, on peut affecter une valeur constante une variable (A = 3: n1.i: 27, n2.i: 27
4;), mais on ne peut pas affecter quoi que ce soit une valeur constante - elle ne
peut pas tre une lvalue (on ne peut pas crire 4 =A;). Si on modifie l'objet n1, l'objet n2 est lui aussi modifi ! Ceci parce que n1 et n2
contiennent une mme rfrence pointant vers le mme objet. (la rfrence originale
L'affectation des types primitifs est trs simple. Puisque les donnes de type primitif qui se trouvait dans n1 et qui pointait sur un objet contenant la valeur 9 a t
contiennent une valeur relle et non une rfrence un objet, en affectant une crase lors de l'affectation et a t perdue ; l'objet sur lequel elle pointait sera
valeur une variable de type primitif on copie le contenu d'un endroit un autre. nettoy par le ramasse-miettes).
Par exemple, si on crit A = B pour des types primitifs, alors le contenu de B est
copi dans A. Si alors on modifie A, bien entendu B n'est pas affect par cette Ce phnomne est souvent appel aliasing (fausse dsignation) et c'est la manire
modification. C'est ce qu'on rencontre gnralement en programmation. fondamentale de grer les objets en Java. Bien. Et si on ne veut pas de l'aliasing ?
Alors il ne faut pas utiliser l'affectation directe n1 = n2, il faut crire :
Toutefois, les choses se passent diffremment lorsqu'on affecte des objets. Quand on
manipule un objet, on manipule en fait sa rfrence, ce qui fait que lorsqu'on n1.i = n2.i;
effectue une affectation depuis un objet vers un autre , en ralit on copie une
rfrence d'un endroit un autre. En d'autres termes, si on crit C = D pour des Les deux objets restent indpendants plutt que d'en perdre un et de faire pointer
objets, aprs l'excution C et D pointeront tous deux vers l'objet qui, l'origine, tait n1et n2 vers le mme objet ; mais on s'aperoit trs vite que manipuler les champs
point uniquement par D. L'exemple suivant dmontre cela. des objets ne donne pas un code lisible et va l'encontre des bons principes de la
conception oriente objet. C'est un sujet non trivial, je le laisserai de ct et je le
Voici l'exemple :
traiterai dans l'Annexe A, consacre l'aliasing. En attendant, gardons l'esprit que
//: c03:Assignment.java l'affectation des objets peut entraner des surprises.
// l'affectation avec des objets n'est pas triviale.
class Number {
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 66/459
L'aliasing pendant l'appel des mthodes (lorsque cela a un sens), on le note au moyen d'un oprateur suivi d'un signe gal.
Par exemple, pour ajouter 4 la variable x et affecter le rsultat x, on crit : x +=
4.
L'aliasing peut galement se produire en passant un objet une mthode :
//: c03:PassObject.java Cet exemple montre l'utilisation des oprateurs mathmatiques :
// Le passage d'objets une mthodes peut avoir //: c03:MathOps.java
// un effet diffrent de celui qu'on espre // Dmonstration des oprateurs mathmatiques.
class Letter { import java.util.*;
char c; public class MathOps {
} // raccourci pour viter des frappes de caractres :
public class PassObject { static void prt(String s) {
static void f(Letter y) { System.out.println(s);
y.c = 'z'; }
} // raccourci pour imprimer une chane et un entier :
public static void main(String[] args) { static void pInt(String s, int i) {
Letter x = new Letter(); prt(s + " = " + i);
x.c = 'a'; }
System.out.println("1: x.c: " + x.c); // raccourci pour imprimer une chane et un nombre en
f(x); virgule flottante :
System.out.println("2: x.c: " + x.c); static void pFlt(String s, float f) {
} prt(s + " = " + f);
} ///:~ }
public static void main(String[] args) {
Dans beaucoup de langages de programmation, la mthode f( ) est cense faire une // Cre un gnrateur de nombres alatoires,
// initialis par dfaut avec l'heure actuelle :
copie de son argument Letter y dans la zone de visibilit de la mthode. Mais, Random rand = new Random();
encore une fois, c'est une rfrence qui est passe et donc la ligne : int i, j, k;
y.c = 'z'; // '%' limite la valeur maximale 99 :
j = rand.nextInt() % 100;
k = rand.nextInt() % 100;
modifie en ralit l'objet se trouvant au-dehors de f( ). Voici la sortie : pInt("j",j);pInt("k",k);
i = j + k; pInt("j + k", i);
1: x.c: a i = j - k; pInt("j - k", i);
2: x.c: z i = k / j; pInt("k / j", i);
i = k * j; pInt("k * j", i);
L'aliasing et ses consquences sont un sujet complexe, toutes les rponses ces i = k % j; pInt("k % j", i);
j %= k; pInt("j %= k", j);
questions seront donnes dans l'Annexe A, mais il vous faut ds maintenant prendre // tests sur les nombres en virgule flottante :
conscience de son existence afin d'en viter les piges. float u,v,w;// s'applique aussi aux nombres en double
prcision
Les oprateurs mathmatiques
v = rand.nextFloat();
w = rand.nextFloat();
pFlt("v", v); pFlt("w", w);
u = v + w; pFlt("v + w", u);
Les oprateurs mathmatiques de base sont les mmes que ceux qu'on trouve dans u = v - w; pFlt("v - w", u);
beaucoup de langages de programmation : l'addition (+), la soustraction (-), la u = v * w; pFlt("v * w", u);
division (/), la multiplication (*) et le modulo (%, le reste de la division entire). La u = v / w; pFlt("v / w", u);
division entire tronque le rsultat sans l'arrondir. // ce qui suit fonctionne galement avec les types
// char, byte, short, int, long et double :
Java utilise galement une notation abrge pour effectuer en un seul temps une u += v; pFlt("u += v", u);
opration et une affectation. Ceci est compatible avec tous les oprateurs du langage u -= v; pFlt("u -= v", u);
u *= v; pFlt("u *= v", u);
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 67/459
u /= v; pFlt("u /= v", u); dcrmentation (souvent cits en tant qu'oprateur d'auto-incrmentation et d'auto-
} dcrmentation). L'oprateur de dcrmentation est -- et signifie diminuer
} ///:~
d'une unit . L'oprateur d'incrmentation est ++ et signifie augmenter d'une
unit . Si a est un int, par exemple, l'expression ++a est quivalente (a = a + 1).
Tout d'abord on remarque quelques mthodes servant de raccourcis pour Le rsultat des oprateurs d'incrmentation et de dcrmentation est la variable
imprimer : la mthode prt( ) imprime une String, pInt( ) imprime une String elle-mme.
suivie d'un int et pFlt( ) imprime une String suivie d'un float. Bien entendu
toutes se terminent par un appel System.out.println( ). Il existe deux versions de chaque type d'oprateur, souvent nommes version
prfixe et version postfixe. Pour les deux oprateurs, incrmentation et
Pour gnrer des nombres, le programme cre un objet de type Random. Aucun dcrmentation, prfixe signifie que l'oprateur ( ++ ou -- ) se trouve juste
argument n'tant pass la cration, Java utilise l'heure courante comme semence avant la variable ou l'expression, postfixe que l'oprateur se trouve aprs la variable
d'initialisation pour le gnrateur de nombres alatoires. Pour gnrer des nombres ou l'expression. Pour la pr-incrmentation et la pr-dcrmentation, (c'est dire,
de diffrents types, le programme appelle tout simplement diffrentes mthodes de ++a ou --a), l'opration est ralise en premier, puis la valeur est produite. Pour la
l'objet Random : nextInt( ), nextLong( ), nextFloat( ) ou nextDouble( ). post-incrmentation et la post-dcrmentation (c'est dire a++ ou a--), la valeur
L'oprateur modulo, appliqu au rsultat du gnrateur de nombres alatoires, est produite, puis l'opration est ralise. En voici un exemple :
limite le rsultat un maximum correspondant la valeur de l'oprande moins un //: c03:AutoInc.java
(dans ce cas, 99). // Dmonstration des oprateurs ++ et --.
public class AutoInc {
public static void main(String[] args) {
Les oprateurs unaires ( un oprande) moins et plus int i = 1;
prt("i : " + i);
prt("++i : " + ++i); // Pr-incrmentation
Le moins unaire (-) et le plus unaire (+) sont identiques au moins binaire et au plus prt("i++ : " + i++); // Post-incrmentation
binaire. Le compilateur les reconnat par le contexte de l'expression. Par exemple, prt("i : " + i);
l'instruction : prt("--i : " + --i); // Pr-dcrmentation
prt("i-- : " + i--); // Post-dcrmentation
x = -a;
prt("i : " + i);
}
a une signification vidente. Le compilateur est capable d'interprter correctement : static void prt(String s) {
System.out.println(s);
x = a * -b; }
} ///:~
mais le lecteur pourrait tre dconcert, aussi est-il plus clair d'crire :
x = a * (-b); Voici le rsultat de ce programme :
i : 1
++i : 2
Le moins unaire a pour rsultat la ngation de la valeur. Le plus unaire existe pour i++ : 2
des raisons de symtrie, toutefois il n'a aucun effet. i : 3
--i : 2
Incrmentation et dcrmentation i--
i :
:
1
2
automatique
On constate qu'avec la forme prfixe on obtient la valeur de la variable aprs que
Java, tout comme C, possde beaucoup de raccourcis. Les raccourcis autorisent un l'opration ait t excute, et qu'avec la forme postfixe on obtient la valeur de la
code plus concis, ce qui le rend plus facile ou difficile lire suivant les cas. variable avant que l'opration ne soit ralise. Ce sont les seuls oprateurs ayant des
effets de bord, mis part ceux qui impliquent l'affectation : en d'autres termes, ils
Les deux raccourcis les plus agrables sont les oprateurs d'incrmentation et de modifient l'oprande au lieu de simplement utiliser sa valeur.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 68/459
L'oprateur d'incrmentation explique le nom C++, qui voudrait signifier un pas //: c03:EqualsMethod.java
de plus au-del de C . Dans un ancien discours sur Java, Bill Joy (l'un des public class EqualsMethod {
public static void main(String[] args) {
crateurs), disait que Java = C++-- (C plus plus moins moins), suggrant que Integer n1 = new Integer(47);
Java serait C++ auquel on aurait t les parties difficiles et non ncessaires, et qu'il Integer n2 = new Integer(47);
serait donc un langage bien plus simple. Au fil de votre lecture, vous dcouvrirez ici System.out.println(n1.equals(n2));
que beaucoup de choses sont plus simples, bien que Java ne soit pas tellement plus }
simple que C++. } ///:~
#/TIJ_PAGE01# #TIJ_PAGE02#
Les oprateurs relationnels
Le rsultat sera true, comme on le souhaitait. Mais ce serait trop facile. Si on cre
Les oprateurs relationnels crent un rsultat de type boolean. Ils valuent les une classe, comme ceci :
rapports entre les valeurs des oprandes. Une expression relationnelle renvoie true //: c03:EqualsMethod2.java
si le rapport est vrai, false dans le cas oppos. Les oprateurs relationnels sont : class Value {
plus petit que (<), plus grand que (>), plus petit que ou gal (<=), plus grand que int i;
}
ou gal (>=), quivalent (==) et non quivalent (!=). Le type boolean n'accepte public class EqualsMethod2 {
comme oprateur relationnel que les oprateurs d'quivalence (==) et de non public static void main(String[] args) {
quivalence (!=), lesquels peuvent tre utiliss avec tous les types de donnes Value v1 = new Value();
disponibles dans le langage. Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));
Tester l'quivalence des objets }
} ///:~
Les oprateurs relationnels == et != fonctionnent avec tous les objets, mais leur
utilisation droute souvent le programmeur Java novice. Voici un exemple : nous voici revenus la case dpart : le rsultat est false. Ceci parce que, par dfaut,
//: c03:Equivalence.java
equals( ) compare des rfrences. Aussi, faute de redfinir equals( ) dans la
public class Equivalence { nouvelle classe, nous n'obtiendrons pas le rsultat dsir. Mais la redfinition des
public static void main(String[] args) { mthodes ne sera expose que dans le Chapitre 7, aussi d'ici l il nous faudra garder
Integer n1 = new Integer(47); l'esprit que l'utilisation de equals( ) peut poser des problmes.
Integer n2 = new Integer(47);
System.out.println(n1 == n2); Beaucoup de classes des bibliothques Java implmentent la mthode equals( )
System.out.println(n1 != n2); afin de comparer le contenu des objets plutt que leurs rfrences.
}
} ///:~
Les oprateurs logiques
L'expression System.out.println(n1 == n2) imprimera le rsultat de la
comparaison de type boolean. Il semble priori vident que la sortie sera true puis Les oprateurs logiques AND (&&), OR (||) et NOT (!) produisent une valeur
false, puisque les deux objets de type Integer sont identiques. Mais, bien que le boolean qui prend la valeur true ou false en fonction des arguments. Cet exemple
contenu des objets soit le mme, les rfrences sont diffrentes, et il se trouve que utilise les oprateurs relationnels et logiques :
les oprateurs == and != comparent des rfrences d'objet. En ralit la sortie sera //: c03:Bool.java
false puis true. Naturellement, cela en surprendra plus d'un. // Oprateurs relationnels et logiques.
import java.util.*;
Que faire si on veut comparer le contenu rel d'un objet ? Il faut utiliser la mthode public class Bool {
spciale equals( ) qui existe pour tous les objets (mais non pour les types primitifs, public static void main(String[] args) {
qui s'accommodent mieux de == et !=). Voici comment l'utiliser : Random rand = new Random();
int i = rand.nextInt() % 100;
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 69/459
int j = rand.nextInt() % 100; Un nombre qui diffre trs lgrement d'un autre est toujours diffrent . Un
prt("i = " + i); nombre reprsent par le plus petit bit significatif au-dessus de zro est diffrent de
prt("j = " + j);
prt("i > j is " + (i > j)); zro.
prt("i < j is " + (i < j));
prt("i >= j is " + (i >= j)); Court-circuit
prt("i <= j is " + (i <= j));
prt("i == j is " + (i == j));
prt("i != j is " + (i != j)); En travaillant avec les oprateurs logiques on rencontre un comportement appel
// Traiter un int comme un boolean court-circuit . Cela signifie que l'valuation de l'expression sera poursuivie
// n'est pas lgal en Java jusqu' ce que la vrit ou la fausset de l'expression soit dtermine sans
//! prt("i && j is " + (i && j));
//! prt("i || j is " + (i || j)); ambigut. En consquence, certaines parties d'une expression logique peuvent ne
//! prt("!i is " + !i); pas tre values. Voici un exemple montrant une valuation court-circuite :
prt("(i < 10) && (j < 10) is " //: c03:ShortCircuit.java
+ ((i < 10) && (j < 10)) ); // Dmonstration du fonctionnement du "court-circuit"
prt("(i < 10) || (j < 10) is " // avec les oprateurs logiques.
+ ((i < 10) || (j < 10)) ); public class ShortCircuit {
} static boolean test1(int val) {
static void prt(String s) { System.out.println("test1(" + val + ")");
System.out.println(s); System.out.println("result: " + (val < 1));
} return val < 1;
} ///:~ }
static boolean test2(int val) {
On ne peut appliquer AND, OR, et NOT qu'aux valeurs boolean. On ne peut pas System.out.println("test2(" + val + ")");
utiliser une variable non boolenne comme si elle tait boolenne, comme on le fait System.out.println("result: " + (val < 2));
return val < 2;
en C et C++. Les tentatives (errones) de le faire ont t mises en commentaires avec }
le marqueur //!. Les expressions qui suivent, toutefois, produisent des valeurs static boolean test3(int val) {
boolean en utilisant les oprateurs de comparaisons relationnels, puis appliquent System.out.println("test3(" + val + ")");
des oprations logiques sur les rsultats. System.out.println("result: " + (val < 3));
return val < 3;
Exemple de listing de sortie : }
public static void main(String[] args) {
i = 85 if(test1(0) && test2(2) && test3(2))
j = 4 System.out.println("expression is true");
i > j is true else
i < j is false System.out.println("expression is false");
i >= j is true }
i <= j is false } ///:~
i == j is false
i != j is true
(i < 10) && (j < 10) is false Chaque fonction test effectue une comparaison sur l'argument et renvoie true ou
(i < 10) || (j < 10) is true false. De plus elle imprime cette valeur pour montrer qu'elle est appele. Les tests
sont utiliss dans l'expression :
Notez qu'une valeur boolean est automatiquement convertie en texte appropri if(test1(0) && test2(2) && test3(2))
lorsqu'elle est utilise dans un contexte o on attend une String.
Dans le programme prcdent, on peut remplacer la dfinition int par n'importe On pourrait naturellement penser que les trois tests sont excuts, mais la sortie
quelle autre donne de type primitif except boolean. Toutefois il faut rester montre le contraire :
attentif au fait que la comparaison de nombres en virgule flottante est trs stricte. test1(0)
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 70/459
result: true Il est possible de raliser des oprations AND, OR et XOR bit bit , mais il est
test2(2) interdit d'effectuer un NOT bit bit (vraisemblablement pour ne pas faire de
result: false
expression is false confusion avec le NOT logique). Pour le type boolean les oprateurs bit bit ont le
mme effet que les oprateurs logiques, sauf qu'il n'y a pas de court-circuit . De
plus, parmi les oprations bit bit effectues sur des types boolean il existe un
Le premier test produit un rsultat true, et l'valuation de l'expression se poursuit. oprateur XOR logique qui ne fait pas partie de la liste des oprateurs logiques .
Toutefois, le second test produit un rsultat false. Puisque cela signifie que Enfin, le type boolean ne doit pas tre utilis dans les expressions de dcalage
l'expression complte sera false, pourquoi poursuivre l'valuation du reste de dcrites ci-aprs.
l'expression ? Cela pourrait avoir un cot. C'est de fait la justification du court-
circuit : gagner potentiellement en performance s'il n'est pas ncessaire d'valuer
compltement l'expression logique. Les oprateurs de dcalage
Les oprateurs bit bit Les oprateurs de dcalage manipulent eux aussi des bits. On ne peut les utiliser
qu'avec les types primitifs entiers. L'oprateur de dcalage gauche (<<) a pour
rsultat la valeur de l'oprande situ gauche de l'oprateur, dcale vers la gauche
Les oprateurs bit bit permettent de manipuler les bits individuels d'une donne du nombre de bits spcifi droite de l'oprateur (en insrant des zros dans les bits
de type primitif. Les oprateurs bit bit effectuent des oprations d'algbre de poids faible). L'oprateur sign de dcalage droite (>>) a pour rsultat la valeur
boolenne sur les bits en correspondance dans les deux arguments afin de produire de l'oprande situ gauche de l'oprateur, dcale vers la droite du nombre de bits
un rsultat. spcifi droite de l'oprateur. L'oprateur sign de dcalage droite >> tend le
L'origine des oprateurs bit bit est rechercher dans l'orientation bas niveau du signe : si la valeur est positive, des zros sont insrs dans les bits de poids fort ; si la
langage C ; il fallait alors manipuler directement le hardware ainsi que les bits des valeur est ngative, des uns sont insrs dans les bits de poids fort. Java comprend
registres hardware. Java a t conu l'origine pour tre embarqu dans les galement un oprateur de dcalage droite non sign >>>, qui tend les zros :
dcodeurs TV, ce qui explique cette orientation bas niveau. Vous n'utiliserez quel que soit le signe, des zros sont insrs dans les bits de poids fort. Cet oprateur
vraisemblablement pas beaucoup ces oprateurs. n'existe pas en C ou C++.
L'oprateur AND (&) bit bit retourne la valeur un si les deux bits correspondants Si on dcale un char, byte, ou short, il sera promu en int avant le dcalage, et le
des oprandes d'entre sont un ; sinon il retourne la valeur zro. L'oprateur OR rsultat sera un int. Seuls seront utiliss les cinq bits de poids faible de la valeur de
(|) bit bit retourne la valeur un si l'un des deux bits correspondants des oprandes dcalage, afin de ne pas dcaler plus que le nombre de bits dans un int. Si on opre
d'entre est un et retourne la valeur zro dans le cas o les deux bits sont zro. avec un long, le rsultat sera un long. Seuls les six bits de poids faible de la valeur
L'oprateur EXCLUSIVE OR, ou XOR (^), retourne la valeur un si l'un des deux bits de dcalage seront utiliss, on ne peut donc dcaler un long d'un nombre de bits
correspondants des oprandes est un, mais pas les deux. L'oprateur NOT bit bit suprieur celui qu'il contient.
(~ , appel galement oprateur de complment un) est un oprateur unaire, il a Les dcalages peuvent tre combins avec le signe gal (<<=, >>= ou >>>=). La
un seul argument (tous les autres oprateurs bit bit sont des oprateurs binaires), lvalue est remplace par la lvalue dcale de la valeur rvalue. Il y a un problme,
il renvoie l'oppos de l'argument - un si le bit de l'argument est zro, zro si le bit toutefois, avec le dcalage droite non sign combin une affectation. Son
est un. utilisation avec un byte ou un short ne donne pas un rsultat correct. En ralit,
Les oprateurs bit bit et les oprateurs logiques tant reprsents par les mmes l'oprande est promu en int, dcal droite, puis tronqu comme s'il devait tre
caractres, je vous propose un procd mnmotechnique pour vous souvenir de leur affect dans sa propre variable, et dans ce cas on obtient -1. L'exemple suivant
signification : les bits tant petits , les oprateurs bit bit comportent un seul dmontre cela :
caractre. //: c03:URShift.java
// Test du dcalage droite non sign.
Les oprateurs bit bit peuvent tre combins avec le signe = pour raliser en une public class URShift {
seule fois opration et affectation : &=, |= et ^= sont tous lgitimes. (~ tant un public static void main(String[] args) {
oprateur unaire, il ne peut tre combin avec le signe =). int i = -1;
i >>>= 10;
Le type boolean est trait comme une valeur binaire et il est quelque peu diffrent. System.out.println(i);
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 71/459
long l = -1; long lln = -9223372036854775808L;
l >>>= 10; pBinLong("maxneg", lln);
System.out.println(l); pBinLong("l", l);
short s = -1; pBinLong("~l", ~l);
s >>>= 10; pBinLong("-l", -l);
System.out.println(s); pBinLong("m", m);
byte b = -1; pBinLong("l & m", l & m);
b >>>= 10; pBinLong("l | m", l | m);
System.out.println(b); pBinLong("l ^ m", l ^ m);
b = -1; pBinLong("l << 5", l << 5);
System.out.println(b>>>10); pBinLong("l >> 5", l >> 5);
} pBinLong("(~l) >> 5", (~l) >> 5);
} ///:~ pBinLong("l >>> 5", l >>> 5);
pBinLong("(~l) >>> 5", (~l) >>> 5);
}
Dans la dernire ligne, la valeur rsultante n'est pas raffecte b, mais directement static void pBinInt(String s, int i) {
imprime et dans ce cas le comportement est correct. System.out.println(
s + ", int: " + i + ", binary: ");
Voici un exemple montrant l'utilisation de tous les oprateurs travaillant sur des System.out.print(" ");
bits : for(int j = 31; j >=0; j--)
if(((1 << j) &i) != 0)
//: c03:BitManipulation.java
System.out.print("1");
// Utilisation des oprateurs bit bit.
else
import java.util.*;
System.out.print("0");
public class BitManipulation {
System.out.println();
public static void main(String[] args) {
}
Random rand = new Random();
static void pBinLong(String s, long l) {
int i = rand.nextInt();
System.out.println(
int j = rand.nextInt();
s + ", long: " + l + ", binary: ");
pBinInt("-1", -1);
System.out.print(" ");
pBinInt("+1", +1);
for(int i = 63; i >=0; i--)
int maxpos = 2147483647;
if(((1L << i) & l) != 0)
pBinInt("maxpos", maxpos);
System.out.print("1");
int maxneg = -2147483648;
else
pBinInt("maxneg", maxneg);
System.out.print("0");
pBinInt("i", i);
System.out.println();
pBinInt("~i", ~i);
}
pBinInt("-i", -i);
} ///:~
pBinInt("j", j);
pBinInt("i & j", i & j);
pBinInt("i | j", i | j); Les deux dernires mthodes, pBinInt( ) et pBinLong( ) sont appeles
pBinInt("i ^ j", i ^ j); respectivement avec un int et un long, et l'impriment en format binaire avec une
pBinInt("i << 5", i << 5);
pBinInt("i >> 5", i >> 5); description. Nous ne parlerons pas de cette implmentation pour le moment.
pBinInt("(~i) >> 5", (~i) >> 5); Remarquez l'utilisation de System.out.print( ) au lieu de System.out.println
pBinInt("i >>> 5", i >>> 5);
pBinInt("(~i) >>> 5", (~i) >>> 5); ( ). La mthode print( ) n'met pas de retour-chariot, et permet ainsi d'imprimer
long l = rand.nextLong(); une ligne en plusieurs fois.
long m = rand.nextLong();
pBinLong("-1L", -1L); Cet exemple montre l'effet de tous les oprateurs bit bit pour les int et les long,
pBinLong("+1L", +1L); mais aussi ce qui se passe avec les valeurs minimale, maximale, +1 et -1, pour un int
long ll = 9223372036854775807L; et pour un long. Noter que le bit de poids le plus fort reprsente le signe : 0 signifie
pBinLong("maxpos", ll); positif, 1 ngatif. Voici la sortie pour la partie int :
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 72/459
-1, int: -1, binary: Si le rsultat de expression-boolenne est true, l'expression valeur0 est value et
11111111111111111111111111111111 son rsultat devient le rsultat de l'oprateur. Si expression-boolenne est false,
+1, int: 1, binary:
00000000000000000000000000000001 c'est l'expression valeur1 qui est value et son rsultat devient le rsultat de
maxpos, int: 2147483647, binary: l'oprateur.
01111111111111111111111111111111
maxneg, int: -2147483648, binary: Bien entendu, il est possible d'utiliser la place une instruction if-else (qui sera
10000000000000000000000000000000 dcrite plus loin), mais l'oprateur ternaire est plus concis. Bien que C (d'o est issu
i, int: 59081716, binary: cet oprateur) s'enorgueillit d'tre lui-mme un langage concis, et que l'oprateur
00000011100001011000001111110100 ternaire ait t introduit, entre autres choses, pour des raisons d'efficacit, il faut se
~i, int: -59081717, binary: garder de l'utiliser tout bout de champ car on aboutit trs facilement un code
11111100011110100111110000001011
-i, int: -59081716, binary: illisible.
11111100011110100111110000001100 Cet oprateur conditionnel peut tre utilis, soit pour ses effets de bord, soit pour la
j, int: 198850956, binary:
00001011110110100011100110001100 valeur produite, mais en gnral on recherche la valeur puisque c'est elle qui rend
i & j, int: 58720644, binary: cet oprateur distinct du if-else. En voici un exemple :
00000011100000000000000110000100 static int ternary(int i) {
i | j, int: 199212028, binary: return i < 10 ? i * 100 : i * 10;
00001011110111111011101111111100 }
i ^ j, int: 140491384, binary:
00001000010111111011101001111000
i << 5, int: 1890614912, binary: Ce code est plus compact que celui qu'on aurait crit sans l'oprateur ternaire :
01110000101100000111111010000000
i >> 5, int: 1846303, binary: static int alternative(int i) {
00000000000111000010110000011111 if (i < 10)
(~i) >> 5, int: -1846304, binary: return i * 100;
11111111111000111101001111100000 else
i >>> 5, int: 1846303, binary: return i * 10;
00000000000111000010110000011111 }
(~i) >>> 5, int: 132371424, binary:
00000111111000111101001111100000 La deuxime forme est plus comprhensible, et ne ncessite pas de commentaire. Il
est donc ncessaire de bien peser tous les arguments avant d'opter pour l'oprateur
La reprsentation binaire des nombres est dite en complment deux sign. ternaire.
#/TIJ_PAGE02# #TIJ_PAGE03#
L'oprateur virgule
Oprateur ternaire if-else
La virgule est utilise en C et C++ non seulement comme sparateur dans la liste des
Cet oprateur est inhabituel parce qu'il a trois oprandes. C'est un vritable argument des fonctions, mais aussi en tant qu'oprateur pour une valuation
oprateur dans la mesure o il produit une valeur, l'inverse de l'instruction squentielle. L'oprateur virgule est utilis en Java uniquement dans les boucles
habituelle if-else que nous tudierons dans la prochaine section de ce chapitre. for, qui seront tudies plus loin dans ce chapitre.
L'expression est de la forme :
expression-boolenne ? valeur0 : valeur1 L'oprateur + pour les String
Un des oprateurs a une utilisation spciale en Java : l'oprateur + peut tre utilis
pour concatner des chanes de caractres, comme on l'a dj vu. Il semble que ce
soit une utilisation naturelle de l'oprateur +, mme si cela ne correspond pas son
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 73/459
utilisation traditionnelle. tendre cette possibilit semblait une bonne ide en C++, erreur de compilation que dans le seul cas o x et y sont des boolean, pour lequel x
aussi la surcharge d'oprateurs fut ajoute au C++ afin de permettre au = y est une expression lgale ; mais il s'agirait probablement d'une erreur dans
programmeur d'ajouter des significations diffrentes presque tous les oprateurs. l'exemple ci-dessus.
En fait, la surcharge d'oprateurs, combine d'autres restrictions du C++, s'est
Un problme similaire en C et C++ consiste utiliser les AND et OR bit bit au lieu
trouve tre trs complique mettre en oeuvre par les programmeurs pour la
de leurs versions logiques. Les AND et OR bit bit utilisent un des caractres (& ou
conception de leurs classes. En Java, la surcharge d'oprateurs aurait t plus
|) alors que les AND et OR logique en utilisent deux (&& et ||). Tout comme avec =
simple implmenter qu'elle ne l'a t en C++ ; mais cette fonctionnalit a t juge
et ==, il est facile de ne frapper qu'un caractre au lieu de deux. En Java, le
trop complexe, et les programmeurs Java, la diffrence des programmeurs C++, ne
compilateur interdit cela et ne vous laissera pas utiliser cavalirement un type l o
peuvent implmenter leurs propres surcharges d'oprateurs.
il n'a pas lieu d'tre.
L'utilisation de l'oprateur + pour les String prsente quelques caractristiques
intressantes. Si une expression commence par une String, alors tous les oprandes
qui suivent doivent tre des String (souvenez-vous que le compilateur remplace
Les oprateurs de transtypage
une squence de caractres entre guillemets par une String) :
Le mot transtypage est utilis dans le sens de couler dans un moule . Java
int x = 0, y = 1, z = 2;
String sString = "x, y, z ";
transforme automatiquement un type de donnes dans un autre lorsqu'il le faut. Par
System.out.println(sString + x + y + z); exemple, si on affecte une valeur entire une variable en virgule flottante, le
compilateur convertira automatiquement l'int en float. Le transtypage permet
d'effectuer cette conversion explicitement, ou bien de la forcer lorsqu'elle ne serait
Ici, le compilateur Java convertit x, y, et z dans leurs reprsentations String au lieu
pas effectue implicitement.
d'ajouter d'abord leurs valeurs. Et si on crit :
System.out.println(x + sString); Pour effectuer un transtypage, il suffit de mettre le type de donnes voulu (ainsi que
tous ses modificateurs) entre parenthses gauche de n'importe quelle valeur. Voici
un exemple :
Java remplacera x par une String.
void casts() {
int i = 200;
Les piges classiques dans l'utilisation des long l = (long)i;
oprateurs
long l2 = (long)200;
}
L'un des piges ds aux oprateurs est de vouloir se passer des parenthses alors Comme on peut le voir, il est possible de transtyper une valeur numrique aussi bien
qu'on n'est pas tout fait certain de la manire dont sera value l'opration. Ceci qu'une variable. Toutefois, dans les deux exemples prsents ici, le transtypage est
reste vrai en Java. superflu puisque le compilateur promouvra une valeur int en long si ncessaire. Il
Une erreur trs classique en C et C++ ressemble celle-ci : est tout de mme possible d'effectuer un tel transtypage, soit pour le souligner, soit
pour rendre le code plus clair. Dans d'autres situations, un transtypage pourrait tre
while(x = y) { utilis afin d'obtenir un code compilable.
// ....
} En C et C++, le transtypage est parfois la source de quelques migraines. En Java, le
transtypage est sr, avec l'exception suivante : lorsqu'on fait ce qu'on appelle une
Le programmeur voulait tester l'quivalence (==) et non effectuer une affectation. conversion rtrcissante (c'est dire lorsqu'on transtype depuis un type de donnes
En C et C++ le rsultat de cette affectation est toujours true si y est diffrent de vers un autre, le premier pouvant contenir plus d'information que le second) on
zro, et on a toutes les chances de partir dans une boucle infinie. En Java, le rsultat court le risque de perdre de l'information. Dans ce cas le compilateur demande un
de cette expression n'est pas un boolean ; le compilateur attendant un boolean, et transtypage explicite, en mettant un message peu prs formul ainsi ceci peut
ne transtypant pas l'int, gnrera une erreur de compilation avant mme l'excution tre dangereux - nanmoins, si c'est ce que vous voulez vraiment faire, je vous en
du programme. Par suite cette erreur n'apparatra jamais en Java. Il n'y aura aucune laisse la responsabilit . Avec une conversion largissante, le transtypage explicite
n'est pas obligatoire car il n'y a pas de risque de perte d'information, le nouveau type
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 74/459
pouvant contenir plus d'information que l'ancien. maximale, le compilateur cre automatiquement une valeur int et met un message
nous demandant d'utiliser un transtypage rtrcissant afin de raliser l'affectation :
Java permet de transtyper n'importe quel type primitif vers n'importe quel autre
Java nous avertit lorsqu'on franchit la ligne.
type primitif, except le type boolean, pour lequel il n'existe aucun transtypage. Les
types Class ne peuvent tre transtyps. Pour convertir une classe en une autre il faut L'octal (base 8) est reprsent par un nombre dont le premier digit est 0 (zro) et les
utiliser des mthodes spciales. (String est un cas part, et on verra plus loin dans autres 0-7. Il n'existe pas de reprsentation littrale des nombres binaires en C, C++
ce livre que les objets peuvent tre transtyps l'intrieur d'une famille de types ; un ou Java.
Chne peut tre transtyp en Arbre et vice versa, mais non dans un type tranger
Un caractre suivant immdiatement une valeur littrale tablit son type : L,
tel que Roche).
majuscule ou minuscule, signifie long ; F, majuscule ou minuscule, signifie float, et
D, majuscule ou minuscule, double.
Les littraux
Les exposants utilisent une notation qui m'a toujours passablement constern : 1.39
e-47f. En science et en ingnierie, e reprsente la base des logarithmes naturels,
Habituellement le compilateur sait exactement quel type affecter aux valeurs
approximativement 2.718 (une valeur double plus prcise existe en Java, c'est
littrales insres dans un programme. Quelquefois, cependant, le type est ambigu.
Math.E). e est utilis dans les expressions d'exponentiation comme 1.39 x e-47, qui
Dans de tels cas il faut guider le compilateur en ajoutant une information
signifie 1.39 x 2.718-47. Toutefois, lorsque FORTRAN vit le jour il fut dcid que e
supplmentaire sous la forme de caractres associs la valeur littrale. Le code
signifierait naturellement dix puissance , dcision bizarre puisque FORTRAN a
suivant montre l'utilisation de ces caractres :
t conu pour rsoudre des problmes scientifiques et d'ingnierie, et on aurait pu
//: c03:Literals.java penser que ses concepteurs auraient fait preuve de plus de bons sens avant
class Literals { d'introduire une telle ambigut.[25] Quoi qu'il en soit, cette habitude a continu
char c = 0xffff; // plus grande valeur char en hexadcimal
byte b = 0x7f; // plus grande valeur byte en hexadcimal avec C, C++ et maintenant Java. Ceux d'entre vous qui ont utilis e en tant que base
short s = 0x7fff; // plus grande valeur short en des logarithmes naturels doivent effectuer une translation mentale en rencontrant
hexadcimal une expression telle que 1.39 e-47f en Java ; elle signifie 1.39 x 10-47.
int i1 = 0x2f; // Hexadcimal (minuscules)
int i2 = 0X2F; // Hexadcimal (majuscules) Noter que le caractre de fin n'est pas obligatoire lorsque le compilateur est capable
int i3 = 0177; // Octal (avec zro en tte) de trouver le type appropri. Avec :
// Hexadcimal et Octal avec des long.
long n1 = 200L; // suffixe long long n3 = 200;
long n2 = 200l; // suffixe long
long n3 = 200; il n'y a pas d'ambigut, un L suivant le 200 serait superflu. Toutefois, avec :
//! long l6(200); // non autoris
float f1 = 1; float f4 = 1e-47f; // 10 puissance
float f2 = 1F; // suffixe float
float f3 = 1f; // suffixe float
float f4 = 1e-45f; // 10 puissance le compilateur traite normalement les nombres en notation scientifique en tant que
float f5 = 1e+9f; // suffixe float double, et en l'absence du f final gnrerait un message d'erreur disant qu'on doit
double d1 = 1d; // suffixe double effectuer un transtypage explicite afin de convertir un double en float.
double d2 = 1D; // suffixe double
double d3 = 47e47d; // 10 puissance
} ///:~ La promotion
L'hexadcimal (base 16), utilisable avec tous les types entier, est reprsent par 0x Lorsqu'on effectue une opration mathmatique ou bit bit sur des types de
ou 0X suivi de caractres 0-9 et/ou a-f en majuscules ou en minuscules. Si on tente donnes primitifs plus petits qu'un int (c'est dire char, byte, ou short), on
d'initialiser une variable avec une valeur plus grande que celle qu'elle peut contenir dcouvre que ces valeurs sont promues en int avant que les oprations ne soient
(indpendamment de la forme numrique de la valeur), le compilateur mettra un effectues, et que le rsultat est du type int. Par suite, si on affecte ce rsultat une
message d'erreur. Le code ci-dessus montre entre autres la valeur hexadcimale variable d'un type plus petit, il faut effectuer un transtypage explicite qui peut
maximale possible pour les types char, byte, et short. Si on dpasse leur valeur d'ailleurs entraner une perte d'information. En gnral, dans une expression, la
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 75/459
donne du type le plus grand est celle qui dtermine le type du rsultat de cette
expression ; en multipliant un float et un double, le rsultat sera un double ; en
Rsum sur les oprateurs
ajoutant un int et un long, le rsultat sera un long.
L'exemple suivant montre les types de donnes primitifs qu'on peut associer avec
certains oprateurs. Il s'agit du mme exemple de base rpt plusieurs fois, en
Java n'a pas de sizeof utilisant des types de donnes primitifs diffrents. Le fichier ne doit pas gnrer
d'erreur de compilation dans la mesure o les lignes pouvant gnrer de telles
En C and C++, l'oprateur sizeof( ) satisfait un besoin spcifique : il renseigne sur erreurs ont t mises en commentaires avec //! :
le nombre d'octets allous pour les donnes individuelles. En C et C++, la principale
#/TIJ_PAGE03# #TIJ_PAGE04#
raison d'tre de l'oprateur sizeof( ) est la portabilit. Plusieurs types de donnes
peuvent avoir des tailles diffrentes sur des machines diffrentes, et le programmeur //: c03:AllOps.java
doit connatre la taille alloue pour ces types lorsqu'il effectue des oprations // Test de tous les oprateurs en liaison avec
// tous les types de donnes primitifs afin de montrer
sensibles la taille des donnes. Par exemple, un ordinateur peut traiter les entiers // les associations acceptes par le compilateur Java.
sur 32 bits, alors qu'un autre les traitera sur 16 bits : les programmes peuvent ranger class AllOps {
de plus grandes valeurs sur la premire machine. Comme on peut l'imaginer, la // Accepter les rsultats d'un test boolen :
portabilit est un norme casse-tte pour les programmeurs C et C++. void f(boolean b) {}
void boolTest(boolean x, boolean y) {
Java n'a pas besoin d'un oprateur sizeof( ) car tous les types de donnes ont la // Oprateurs arithmtiques :
mme taille sur toutes les machines. Il n'est absolument pas besoin de parler de //! x = x * y;
portabilit ce niveau - celle-ci est dj intgre au langage. //! x = x / y;
//! x = x % y;
//! x = x + y;
Retour sur la priorit des oprateurs //! x = x - y;
//! x++;
//! x--;
Lors d'un sminaire, entendant mes jrmiades au sujet de la difficult de se //! x = +y;
souvenir de la priorit des oprateurs, un tudiant suggra un procd //! x = -y;
// Oprateurs relationnels et logiques :
mnmotechnique qui est galement un commentaire : Ulcer Addicts Really Like C //! f(x > y);
A lot . ( Les Accros de l'Ulcre Adorent Rellement C ) //! f(x >= y);
//! f(x < y);
Mnmonique Type d'oprateur Oprateurs //! f(x <= y);
f(x == y);
Ulcer Unaire + - ++-- f(x != y);
f(!y);
Addicts Arithmtique (et * / % + - << >> x = x && y;
dcalage) x = x || y;
Really Relationnel > < >= <= == != // Oprateurs bit bit :
//! x = ~y;
Like Logique (et bit bit) && || & | ^ x = x & y;
x = x | y;
C Conditionnel (ternaire) A>B?X:Y x = x ^ y;
//! x = x << 1;
A Lot Affectation = (et affectation compose //! x = x >> 1;
comme*=) //! x = x >>> 1;
// Affectation compose :
Bien entendu, ce n'est pas un moyen mnmotechnique parfait puisque les //! x += y;
oprateurs de dcalage et les oprateurs bit bit sont quelque peu parpills dans le //! x -= y;
tableau, mais il fonctionne pour les autres oprateurs. //! x *= y;
//! x /= y;
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 76/459
//! x %= y; x >>>= 1;
//! x <<= 1; x &= y;
//! x >>= 1; x ^= y;
//! x >>>= 1; x |= y;
x &= y; // Changement de type :
x ^= y; //! boolean b = (boolean)x;
x |= y; byte B = (byte)x;
// Changement de type : short s = (short)x;
//! char c = (char)x; int i = (int)x;
//! byte B = (byte)x; long l = (long)x;
//! short s = (short)x; float f = (float)x;
//! int i = (int)x; double d = (double)x;
//! long l = (long)x; }
//! float f = (float)x; void byteTest(byte x, byte y) {
//! double d = (double)x; // Oprateurs arithmtiques :
} x = (byte)(x* y);
void charTest(char x, char y) { x = (byte)(x / y);
// Oprateurs arithmtiques : x = (byte)(x % y);
x = (char)(x * y); x = (byte)(x + y);
x = (char)(x / y); x = (byte)(x - y);
x = (char)(x % y); x++;
x = (char)(x + y); x--;
x = (char)(x - y); x = (byte)+ y;
x++; x = (byte)- y;
x--; // Oprateurs relationnels et logiques :
x = (char)+y; f(x > y);
x = (char)-y; f(x >= y);
// Oprateurs relationnels et logiques : f(x < y);
f(x > y); f(x <= y);
f(x >= y); f(x == y);
f(x < y); f(x != y);
f(x <= y); //! f(!x);
f(x == y); //! f(x && y);
f(x != y); //! f(x || y);
//! f(!x); // Oprateurs bit bit :
//! f(x && y); x = (byte)~y;
//! f(x || y); x = (byte)(x & y);
// Oprateurs bit bit : x = (byte)(x | y);
x= (char)~y; x = (byte)(x ^ y);
x = (char)(x & y); x = (byte)(x << 1);
x= (char)(x | y); x = (byte)(x >> 1);
x = (char)(x ^ y); x = (byte)(x >>> 1);
x = (char)(x << 1); // Affectation compose :
x = (char)(x >> 1); x += y;
x = (char)(x >>> 1); x -= y;
// Affectation compose : x *= y;
x += y; x /= y;
x -= y; x %= y;
x *= y; x <<= 1;
x /= y; x >>= 1;
x %= y; x >>>= 1;
x <<= 1; x &= y;
x >>= 1; x ^= y;
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 77/459
x |= y; char c = (char)x;
// Changement de type : byte B = (byte)x;
//! boolean b = (boolean)x; int i = (int)x;
char c = (char)x; long l = (long)x;
short s = (short)x; float f = (float)x;
int i = (int)x; double d = (double)x;
long l = (long)x; }
float f = (float)x; void intTest(int x, int y) {
double d = (double)x; // Oprateurs arithmtiques :
} x = x * y;
void shortTest(short x, short y) { x = x / y;
// Oprateurs arithmtiques : x = x % y;
x = (short)(x * y); x = x + y;
x = (short)(x / y); x = x - y;
x = (short)(x % y); x++;
x = (short)(x + y); x--;
x = (short)(x - y); x = +y;
x++; x = -y;
x--; // Oprateurs relationnels et logiques :
x = (short)+y; f(x > y);
x = (short)-y; f(x >= y);
// Oprateurs relationnels et logiques : f(x < y);
f(x > y); f(x <= y);
f(x >= y); f(x == y);
f(x < y); f(x != y);
f(x <= y); //! f(!x);
f(x == y); //! f(x && y);
f(x != y); //! f(x || y);
//! f(!x); // Oprateurs bit bit :
//! f(x && y); x = ~y;
//! f(x || y); x = x & y;
// Oprateurs bit bit : x = x | y;
x = (short)~y; x = x ^ y;
x = (short)(x & y); x = x << 1;
x = (short)(x | y); x = x >> 1;
x = (short)(x ^ y); x = x >>> 1;
x = (short)(x << 1); // Affectation compose :
x = (short)(x >> 1); x += y;
x = (short)(x >>> 1); x -= y;
// Affectation compose : x *= y;
x += y; x /= y;
x -= y; x %= y;
x *= y; x <<= 1;
x /= y; x >>= 1;
x %= y; x >>>= 1;
x <<= 1; x &= y;
x >>= 1; x ^= y;
x >>>= 1; x |= y;
x &= y; // Changement de type :
x ^= y; //! boolean b = (boolean)x;
x |= y; char c = (char)x;
// Changement de type : byte B = (byte)x;
//! boolean b = (boolean)x; short s = (short)x;
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 78/459
long l = (long)x; }
float f = (float)x; void floatTest(float x, float y) {
double d = (double)x; // Oprateurs arithmtiques :
} x = x * y;
void longTest(long x, long y) { x = x / y;
// Oprateurs arithmtiques : x = x % y;
x = x * y; x = x + y;
x = x / y; x = x - y;
x = x % y; x++;
x = x + y; x--;
x = x - y; x = +y;
x++; x = -y;
x--; // Oprateurs relationnels et logiques :
x = +y; f(x > y);
x = -y; f(x >= y);
// Oprateurs relationnels et logiques : f(x < y);
f(x > y); f(x <= y);
f(x >= y); f(x == y);
f(x < y); f(x != y);
f(x <= y); //! f(!x);
f(x == y); //! f(x && y);
f(x != y); //! f(x || y);
//! f(!x); // Oprateurs bit bit :
//! f(x && y); //! x = ~y;
//! f(x || y); //! x = x & y;
// Oprateurs bit bit : //! x = x | y;
x = ~y; //! x = x ^ y;
x = x & y; //! x = x << 1;
x = x | y; //! x = x >> 1;
x = x ^ y; //! x = x >>> 1;
x = x << 1; // Affectation compose :
x = x >> 1; x += y;
x = x >>> 1; x -= y;
// Affectation compose : x *= y;
x += y; x /= y;
x -= y; x %= y;
x *= y; //! x <<= 1;
x /= y; //! x >>= 1;
x %= y; //! x >>>= 1;
x <<= 1; //! x &= y;
x >>= 1; //! x ^= y;
x >>>= 1; //! x |= y;
x &= y; // Changement de type :
x ^= y; //! boolean b = (boolean)x;
x |= y; char c = (char)x;
// Changement de type : byte B = (byte)x;
//! boolean b = (boolean)x; short s = (short)x;
char c = (char)x; int i = (int)x;
byte B = (byte)x; long l = (long)x;
short s = (short)x; double d = (double)x;
int i = (int)x; }
float f = (float)x; void doubleTest(double x, double y) {
double d = (double)x; // Oprateurs arithmtiques :
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 79/459
x = x * y; Noter que le type boolean est totalement limit. On peut lui assigner les valeurs
x = x / y; true et false, on peut tester sa vrit ou sa fausset, mais on ne peut ni additionner
x = x % y;
x = x + y; des boolens ni effectuer un autre type d'opration avec eux.
x = x - y; On peut observer l'effet de la promotion des types char, byte, et short avec
x++;
x--; l'application d'un oprateur arithmtique sur l'un d'entre eux. Le rsultat est un int,
x = +y; qui doit tre explicitement transtyp vers le type original (c'est dire une conversion
x = -y; rtrcissante qui peut entraner une perte d'information) afin de l'affecter une
// Oprateurs relationnels et logiques : variable de ce type. Avec les valeurs int, toutefois, il n'est pas besoin de transtyper,
f(x > y); puisque tout ce qu'on obtient est toujours un int. N'allez cependant pas croire qu'on
f(x >= y);
f(x < y); peut faire n'importe quoi en toute impunit. Le rsultat de la multiplication de deux
f(x <= y); ints un peu trop grands peut entraner un dbordement. L'exemple suivant en fait la
f(x == y); dmonstration :
f(x != y);
//! f(!x); //: c03:Overflow.java
//! f(x && y); // Surprise! Java ne contrle pas vos dbordements.
//! f(x || y); public class Overflow {
// Oprateurs bit bit : public static void main(String[] args) {
//! x = ~y; int big = 0x7fffffff; // plus grande valeur int
//! x = x & y; prt("big = " + big);
//! x = x | y; int bigger = big * 4;
//! x = x ^ y; prt("bigger = " + bigger);
//! x = x << 1; }
//! x = x >> 1; static void prt(String s) {
//! x = x >>> 1; System.out.println(s);
// Affectation compose : }
x += y; } ///:~
x -= y;
x *= y; Voici le rsultat :
x /= y;
x %= y; big = 2147483647
//! x <<= 1; bigger = -4
//! x >>= 1;
//! x >>>= 1;
//! x &= y; La compilation se droule sans erreur ni avertissement ; il n'y a pas d'exception lors
//! x ^= y; de l'excution : Java est puissant, mais tout de mme pas ce point-l.
//! x |= y;
// Changement de type : Les affectations composes ne ncessitent pas de transtypage pour les types char,
//! boolean b = (boolean)x; byte, ou short, bien qu'elles entranent des promotions qui ont le mme rsultat
char c = (char)x; que les oprations arithmtiques directes. Cette absence de transtypage simplifie
byte B = (byte)x; certainement le code.
short s = (short)x;
int i = (int)x; On remarque qu' l'exception du type boolean, tous les types primitifs peuvent tre
long l = (long)x; transtyps entre eux. Il faut rester attentif l'effet des conversions rtrcissantes en
float f = (float)x; transtypant vers un type plus petit, sous peine de perdre de l'information sans en
}
} ///:~ tre averti.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 80/459
Le Contrle d'excution virgule, soit une instruction compose, c'est dire un groupe d'instructions simples
places entre deux accolades. Par la suite, chaque utilisation du mot instruction
sous-entendra que l'instruction peut tre simple ou compose.
Java utilisant toutes les instructions de contrle de C, bien des choses seront Voici un exemple d'instruction if-else : la mthode test( ) dtermine si une
familires au programmeur C ou C++. La plupart des langages de programmation estimation est suprieure, infrieure ou quivalente une valeur donne :
procduraux possdent le mme type d'instructions de contrle, et on retrouve
beaucoup de choses d'un langage un autre. En Java, les mots clefs sont if-else, //: c03:IfElse.java
public class IfElse {
while, do-while, for, et une instruction de slection appele switch. Toutefois static int test(int testval, int target) {
Java ne possde pas le goto trs pernicieux (lequel reste le moyen le plus expditif int result = 0;
pour traiter certains types de problmes). Il est possible d'effectuer un saut if(testval > target)
ressemblant au goto, mais bien plus contraignant qu'un goto classique. result = +1;
else if(testval < target)
result = -1;
true et false else
result = 0; // Identique
return result;
Toutes les instructions conditionnelles utilisent la vrit ou la fausset d'une }
expression conditionnelle pour dterminer le chemin d'excution. Exemple d'une public static void main(String[] args) {
expression conditionnelle : A == B. Elle utilise l'oprateur conditionnel == pour System.out.println(test(10, 5));
dterminer si la valeur A est quivalente la valeur B. L'expression renvoie la valeur System.out.println(test(5, 10));
System.out.println(test(5, 5));
true ou false. Tous les oprateurs relationnels vus plus haut dans ce chapitre }
peuvent tre utiliss pour crer une instruction conditionnelle. Il faut garder } ///:~
l'esprit que Java ne permet pas d'utiliser un nombre la place d'un boolean, mme
si c'est autoris en C et C++ (pour lesquels la vrit est diffrent de zro et la Par convention, on indente le corps d'une instruction de contrle de flux, afin que le
fausset zro ). Pour utiliser un non-boolean dans un test boolean, tel que if lecteur dtermine plus facilement son dbut et sa fin.
(a), il faut d'abord le convertir en une valeur boolean en utilisant une expression
boolenne, par exemple if(a != 0).
return
if-else Le mot clef return a deux buts : il spcifie la valeur que la mthode doit retourner
(si elle n'a pas un type de retour void) et provoque le renvoi immdiat de cette
L'instruction if-else est sans doute le moyen le plus simple de contrler le valeur. Voici la mthode test( ) ci-dessus, rcrite en utilisant cette proprit :
droulement du programme. La clause else est optionnelle, et par suite l'instruction
//: c03:IfElse2.java
if possde deux formes : public class IfElse2 {
if(expression boolenne) static int test(int testval, int target) {
instruction int result = 0;
if(testval > target)
return +1;
ou bien : else if(testval < target)
if(expression boolenne) return -1;
instruction else
else return 0; // Identique
instruction }
public static void main(String[] args) {
System.out.println(test(10, 5));
L'expression conditionnelle expression boolenne doit fournir un rsultat de type System.out.println(test(5, 10));
boolean. instruction dsigne soit une instruction simple termine par un point- System.out.println(test(5, 5));
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 81/459
} instruction
} ///:~ while(expression boolenne);
#/TIJ_PAGE04# #TIJ_PAGE05# La seule diffrence entre while et do-while est que dans une boucle do-while,
instruction est excute au moins une fois, mme si l'expression est fausse la
En fait les clauses else sont inutiles car les instructions return terminent
premire fois. Dans une boucle while, si l'expression conditionnelle est fausse la
l'excution de la mthode.
premire fois, l'instruction n'est jamais excute. En pratique, la boucle do-while
est moins utilise que while.
Itration
for
Les instructions de contrle de boucle while, do-while et for sont souvent appels
instructions d'itration. Une instruction est rpte jusqu' ce que l'expression
La boucle for effectue une initialisation avant la premire itration. Puis elle
boolenne de contrle devienne fausse. Voici la forme d'une boucle while :
effectue un test conditionnel et, la fin de chaque itration, une instruction
while(expression boolenne) d'itration . Voici la forme d'une boucle for :
instruction
for(instruction d'initialisation; expression boolenne;
instruction d'itration)
expression boolenne est value l'entre de la boucle, puis aprs chaque itration instruction
ultrieure d'instruction.
Voici un exemple simple qui gnre des nombres alatoires jusqu' l'arrive d'une Chacune des expressions instruction d'initialisation, expression boolenne et
condition particulire : instruction d'itration peut tre vide. expression boolenne est teste avant chaque
itration, et ds qu'elle est value false l'excution continue la ligne suivant
//: c03:WhileTest.java
// Dmonstration de la boucle while. l'instruction for. la fin de chaque boucle, instruction d'itration est excute.
public class WhileTest { Les boucles for sont gnralement utilises pour les tches impliquant un
public static void main(String[] args) {
double r = 0; dcompte :
while(r < 0.99d) { //: c03:ListCharacters.java
r = Math.random(); // Dmonstration de la boucle "for" listant
System.out.println(r); // tous les caractres ASCII.
} public class ListCharacters {
} public static void main(String[] args) {
} ///:~ for( char c = 0; c < 128; c++)
if (c != 26 )// Effacement de l'cran ANSI
System.out.println(
Ce test utilise la mthode static random( ) de la bibliothque Math, qui gnre "value: " + (int)c +
une valeur double comprise entre 0 et 1. (0 inclus, 1 exclu). L'expression " character: " + c);
conditionnelle de la boucle while signifie continuer l'excution de cette boucle }
jusqu' ce que le nombre gnr soit gal ou suprieur 0.99 . Le rsultat est une } ///:~
liste de nombre, et la taille de cette liste est diffrente chaque excution du
programme. Remarquons que la variable c est dfinie l'endroit o elle est utilise, l'intrieur
de l'expression de contrle de la boucle for, plutt qu'au dbut du bloc commenant
do-while l'accolade ouvrante. La porte de c est l'expression contrle par la boucle for.
Les langages procduraux traditionnels tels que C exigent que toutes les variables
Voici la forme de la boucle do-while : soient dfinies au dbut d'un bloc afin que le compilateur leur alloue de l'espace
do
mmoire lorsqu'il cre un bloc. En Java et C++ les dclarations de variables peuvent
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 82/459
apparatre n'importe o dans le bloc, et tre ainsi dfinies au moment o on en a
besoin. Ceci permet un style de code plus naturel et rend le code plus facile
break et continue
comprendre.
Le droulement de toutes les instructions d'itration peut tre contrl de l'intrieur
Il est possible de dfinir plusieurs variables dans une instruction for, condition du corps de la boucle au moyen des instructions break et continue. L'instruction
qu'elles aient le mme type : break sort de la boucle sans excuter la suite des instructions. L'instruction
for(int i = 0, j = 1; continue arrte l'excution de l'itration courante, et l'excution reprend en dbut
i < 10 && j != 11; de boucle avec l'itration suivante.
i++, j++)
/* corps de la boucle for */; Ce programme montre des exemples d'utilisation des instructions break et
continue dans des boucles for et while :
La dfinition int de l'instruction for s'applique la fois i et j. La possibilit de //: c03:BreakAndContinue.java
dfinir des variables dans une expression de contrle est limite la boucle for. On // Dmonstration des mots clefs break et continue.
ne peut l'utiliser dans aucune autre instruction de slection ou d'itration. public class BreakAndContinue {
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
L'oprateur virgule if(i == 74) break; // Sortie dfinitive de la boucle for
if(i % 9 != 0) continue; // Continue avec l'itration
suivante
Au dbut de ce chapitre j'ai dclar que l'oprateur virgule ( distinguer du System.out.println(i);
sparateur virgule, utilis pour sparer les dfinitions et les arguments de }
fonctions) avait un seul usage en Java, savoir dans l'expression de contrle d'une int i = 0;
boucle for. Aussi bien la partie initialisation que la partie itration de l'expression // une "boucle infinie" :
while(true) {
de contrle peuvent tre formes de plusieurs instructions spares par des virgules, i++;
et ces instructions seront values squentiellement. L'exemple prcdent utilisait int j = i * 27;
cette possibilit. Voici un autre exemple : if(j == 1269) break; // Sortie de boucle
if(i % 10 != 0) continue; // Dbut de boucle
//: c03:CommaOperator.java System.out.println(i);
public class CommaOperator { }
public static void main(String[] args) { }
for(int i = 1, j = i + 10; i < 5; } ///:~
i++, j = i * 2) {
System.out.println("i= " + i + " j= " + j);
} Dans la boucle for la valeur de i n'atteint jamais 100 car l'instruction break
} termine la boucle lorsque i prend la valeur 74. En principe, il ne faudrait pas utiliser
} ///:~ break de cette manire, moins que l'on ne connaisse pas le moment o la
condition de fin arrivera. L'instruction continue provoque un branchement au
En voici le rsultat : dbut de la boucle d'itration (donc en incrmentant i) chaque fois que i n'est pas
i= 1 j= 11 divisible par 9. Lorsqu'il l'est, la valeur est imprime.
i= 2 j= 4
i= 3 j= 6 La seconde partie montre une boucle infinie qui, thoriquement, ne devrait
i= 4 j= 8 jamais s'arrter. Toutefois, elle contient une instruction break lui permettant de le
faire. De plus, l'instruction continue retourne au dbut de la boucle au lieu
d'excuter la fin, ainsi la seconde boucle n'imprime que lorsque la valeur de i est
remarquez que la partie initialisation ainsi que la partie itration sont values en
divisible par 10. La sortie est :
ordre squentiel. La partie initialisation peut comporter n'importe quel nombre de
dfinitions du mme type. 0
9
18
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 83/459
27 En Java, une tiquette ne peut se trouver qu'en un unique endroit : juste avant une
36 instruction d'itration. Et, j'insiste, juste avant - il n'est pas bon de mettre une autre
45
54 instruction entre l'tiquette et la boucle d'itration. De plus, il n'y a qu'une seule
63 bonne raison de mettre une tiquette avant une itration, c'est lorsqu'on a
72 l'intention d'y nicher une autre itration ou un switch. Ceci parce que les mots clefs
10 break et continue ont pour fonction naturelle d'interrompre la boucle en cours,
20 alors qu'utiliss avec une tiquette ils interrompent la boucle pour se brancher
30
40 l'tiquette :
label1:
outer-iteration {
La valeur 0 est imprime car 0 % 9 a pour rsultat 0. inner-iteration {
Il existe une seconde forme de boucle infinie, c'est for(;;). Le compilateur traite //...
break; // 1
while(true) et for(;;) de la mme manire, le choix entre l'une et l'autre est donc //...
affaire de got. continue;// 2
//...
L'infme goto continue label1; // 3
//...
break label1;// 4
Le mot clef goto est aussi ancien que les langages de programmation. En effet, goto }
a t le premier moyen de contrle des programmes dans les langages assembleur : }
si la condition A est satisfaite, alors sauter ici, sinon sauter l . Lorsqu'on lit le
code assembleur finalement gnr par n'importe quel compilateur, on voit qu'il Cas 1 : break interrompt l'itration intrieure, on se retrouve dans l'itration
comporte beaucoup de sauts. Toutefois, un goto au niveau du code source est un extrieure. Cas 2 : continue branche l'itration intrieure. Mais, cas 3 : continue
saut, et c'est ce qui lui a donn mauvaise rputation. Un programme n'arrtant pas label1 interrompt l'itration intrieure et l'itration extrieure, et branche dans tous
de sauter d'un point un autre ne peut-il tre rorganis afin que le flux du les cas label1. En fait, l'itration continue, mais en redmarrant partir de
programme soit plus squentiel ? goto tomba en disgrce aprs la publication du l'itration extrieure. Cas 4 : break label1 interrompt lui aussi dans tous les cas et
fameux article Le goto considr comme nuisible crit par Edsger Dijkstra, et branche label1, mais ne rentre pas nouveau dans l'itration. En fait il sort des
depuis lors les guerres de religion propos de son utilisation sont devenues deux itrations.
monnaie courante, les partisans du mot clef honni recherchant une nouvelle
Voici un exemple utilisant les boucles for :
audience.
//: c03:LabeledFor.java
Comme il est habituel en de semblables situations, la voie du milieu est la plus // la boucle for "tiquete" en Java.
indique. Le problme n'est pas d'utiliser le goto, mais de trop l'utiliser - dans public class LabeledFor {
quelques rares situations le goto est rellement la meilleure faon de structurer le public static void main(String[] args) {
flux de programme. int i = 0;
outer: // Il ne peut y avoir d'instruction ici
Bien que goto soit un mot rserv de Java, on ne le trouve pas dans le langage ; Java for(; true ;) { // boucle infinie
n'a pas de goto. Cependant, il existe quelque chose qui ressemble un saut, li aux inner: // Il ne peut y avoir d'instruction ici
for(; i < 10; i++) {
mots clefs break et continue. Ce n'est pas vraiment un saut, mais plutt une prt("i = " + i);
manire de sortir d'une instruction d'itration. On le prsente dans les discussions if(i == 2) {
sur le goto parce qu'il utilise le mme mcanisme : une tiquette. prt("continue");
continue;
Une tiquette est un identificateur suivi du caractre deux points, comme ceci : }
label1: if(i == 3) {
prt("break");
i++; // Sinon i ne sera
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 84/459
// jamais incrment. continue inner
break; i = 7
} continue outer
if(i == 7) { i = 8
prt("continue outer"); break outer
i++; // Sinon i ne sera
// jamais incrment.
continue outer; Si l'instruction break outer n'tait pas l, il n'y aurait aucun moyen de se brancher
} l'extrieur de la boucle extrieure depuis la boucle intrieure, puisque break
if(i == 8) { utilis seul ne permet de sortir que de la boucle la plus interne (il en est de mme
prt("break outer"); pour continue).
break outer;
} videmment, lorsque break a pour effet de sortir de la boucle et de la mthode, il
for(int k = 0; k < 5; k++) { est plus simple d'utiliser return.
if(k == 3) {
prt("continue inner"); Voici une dmonstration des instructions tiquetes break et continue avec des
continue inner; boucles while :
}
} //: c03:LabeledWhile.java
} // La boucle while "tiquete" en Java.
} public class LabeledWhile {
// On ne peut pas utiliser un break ou public static void main(String[] args) {
// un continue vers une tiquette ici int i = 0;
} outer:
static void prt(String s) { while(true) {
System.out.println(s); prt("Outer while loop");
} while(true) {
} ///:~ i++;
prt("i = " + i);
if(i == 1) {
Ce programme utilise la mthode prt( ) dj dfinie dans d'autres exemples. prt("continue");
continue;
Noter que break sort de la boucle for, et l'expression d'incrmentation ne sera }
jamais excute avant le passage en fin de boucle for. Puisque break saute if(i == 3) {
l'instruction d'incrmentation, l'incrmentation est ralise directement dans le cas prt("continue outer");
o i == 3. Dans le cas i == 7, l'instruction continue outer saute elle aussi en tte continue outer;
de la boucle, donc saute l'incrmentation, qui est, ici aussi, ralise directement. }
if(i == 5) {
Voici le rsultat : prt("break");
break;
i = 0 }
continue inner if(i == 7) {
i = 1 prt("break outer");
continue inner break outer;
i = 2 }
continue }
i = 3 }
break }
i = 4 static void prt(String s) {
continue inner System.out.println(s);
i = 5 }
continue inner } ///:~
i = 6
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 85/459
Les mmes rgles s'appliquent au while : switch(slecteur-entier) {
case valeur-entire1 : instruction; break;
1. Un continue gnre un saut en tte de la boucle courante et poursuit case valeur-entire2 : instruction; break;
l'excution ; case valeur-entire3 : instruction; break;
2. Un continue tiquet gnre un saut l'tiquette puis entre nouveau case valeur-entire4 : instruction; break;
case valeur-entire5 : instruction; break;
dans la boucle juste aprs cette tiquette ; // ...
3. Un break sort de la boucle par le bas ; default : instruction;
4. Un break tiquet sort de la boucle par le bas, la fin de la boucle repre }
par l'tiquette.
Le rsultat de cette mthode claircit cela : #/TIJ_PAGE05# #TIJ_PAGE06#
Outer while loop slecteur-entier est une expression qui produit une valeur entire. switch compare
i = 1 le rsultat de slecteur-entier avec chaque valeur-entire. S'il trouve une galit,
continue l'instruction correspondante (simple ou compose) est excute. Si aucune galit
i = 2 n'est trouve, l'instruction qui suit default est excute.
i = 3
continue outer Notons dans la dfinition prcdente que chaque instruction case se termine par
Outer while loop
i = 4
une instruction break, qui provoque un saut la fin du corps de l'instruction
i = 5 switch. Ceci est la manire habituelle de construire une instruction switch.
break Cependant break est optionnel. S'il n'est pas l, le code associ l'instruction case
Outer while loop suivante est excut, et ainsi de suite jusqu' la rencontre d'une instruction break.
i = 6 Bien qu'on n'ait gnralement pas besoin d'utiliser cette possibilit, elle peut se
i = 7 montrer trs utile pour un programmeur expriment. La dernire instruction, qui
break outer
suit default, n'a pas besoin de break car en fait l'excution continue juste
l'endroit o une instruction break l'aurait amene de toute faon. Il n'y a cependant
Il est important de se souvenir qu'il n'y a qu'une seule raison d'utiliser une tiquette aucun problme terminer l'instruction default par une instruction break si on
en Java, c'est lorsqu'il existe plusieurs boucles imbriques et que l'on veut utiliser pense que le style de programmation est une question importante.
break ou continue pour traverser plus d'un niveau d'itration.
L'instruction switch est une manire propre d'implmenter une slection multiple
Dijkstra, dans son article Le goto considr comme nuisible , critiquait les (c'est dire slectionner un certain nombre de possibilits d'excution), mais elle
tiquettes, mais pas le goto lui-mme. Il avait observ que le nombre de bugs requiert une expression de slection dont le rsultat soit entier, comme int ou char.
semblait augmenter avec le nombre d'tiquettes d'un programme. Les tiquettes et Par exemple on ne peut pas utiliser une chane de caractres ou un flottant comme
les goto rendent difficile l'analyse statique d'un programme, car ils introduisent des slecteur dans une instruction switch. Pour les types non entiers, il faut mettre en
cycles dans le graphe d'excution de celui-ci. Remarquons que les tiquettes Java ne oeuvre une srie d'instructions if.
sont pas concernes par ce problme, dans la mesure o leur emplacement est
contraint, et qu'elles ne peuvent pas tre utilises pour raliser un transfert de Voici un exemple qui cre des lettres alatoirement, et dtermine s'il s'agit d'une
contrle la demande. Il est intressant de noter que nous nous trouvons dans un voyelle ou d'une consonne :
cas o une fonctionnalit du langage est rendue plus utile en en diminuant la //: c03:VowelsAndConsonants.java
puissance. // Dmonstration de l'instruction switch.
public class VowelsAndConsonants {
public static void main(String[] args) {
switch for(int i = 0; i < 100; i++) {
char c = (char)(Math.random() * 26 + 'a');
System.out.print(c + ": ");
On parle parfois de switch comme d'une instruction de slection. L'instruction switch(c) {
switch slectionne un morceau de code parmi d'autres en se basant sur la valeur case 'a':
d'une expression entire. Voici sa forme : case 'e':
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 86/459
case 'i': // Qu'arrive-t-il lorsqu'on transtype un flottant
case 'o': // ou un double vers une valeur entire ?
case 'u': public class CastingNumbers {
System.out.println("vowel"); public static void main(String[] args) {
break; double
case 'y': above = 0.7,
case 'w': below = 0.4;
System.out.println( System.out.println("above: " + above);
"Sometimes a vowel"); System.out.println("below: " + below);
break; System.out.println(
default: "(int)above: " + (int)above);
System.out.println("consonant"); System.out.println(
} "(int)below: " + (int)below);
} System.out.println(
} "(char)('a' + above): " +
} ///:~ (char)('a' + above));
System.out.println(
"(char)('a' + below): " +
Math.random( ) gnrant une valeur entre 0 et 1, il faut la multiplier par la borne (char)('a' + below));
suprieure de l'intervalle des nombres qu'on veut produire (26 pour les lettres de }
l'alphabet) puis ajouter un dcalage correspondant la borne infrieure. } ///:~
Bien qu'il semble que la slection s'opre ici sur un type caractre, l'instruction
switch utilise en ralit la valeur entire du caractre. Les caractres entre Le rsultat :
guillemets simples des instructions case sont galement interprts comme des above: 0.7
entiers avant la comparaison. below: 0.4
(int)above: 0
Remarquez la manire d'empiler les instructions case pour affecter un mme code (int)below: 0
d'excution plusieurs cas d'galit. Il faut galement faire attention terminer (char)('a' + above): a
chaque instruction par une instruction break, faute de quoi le contrle serait (char)('a' + below): a
transfr l'instruction correspondant au case suivant.
La rponse est donc : le transtypage d'un type float ou double vers une valeur
Dtails de calcul : entire entrane une troncature dans tous les cas.
Une seconde question propos de Math.random( ) : cette mthode produit des
L'instruction : nombres entre zro et un, mais : les valeurs 0 et 1 sont-elles inclues ou exclues ? En
jargon mathmatique, obtient-on ]0,1[, [0,1], ]0,1] ou [0,1[ ? (les crochets tourns
char c = (char)(Math.random() * 26 + 'a');
vers le nombre signifient ce nombre est inclus , et ceux tourns vers l'extrieur
ce nombre est exclu ). nouveau, un programme de test devrait nous donner la
mrite une attention particulire. Math.random( ) a pour rsultat un double, par rponse :
suite la valeur 26 est convertie en double avant que la multiplication ne soit
effectue ; cette dernire a aussi pour rsultat un double. Ce qui signifie que 'a' doit //: c03:RandomBounds.java
// Math.random() produit-il les valeurs 0.0 et 1.0 ?
lui aussi tre converti en double avant d'excuter l'addition. Le rsultat double est public class RandomBounds {
finalement transtyp en char. static void usage() {
System.out.println("Usage: \n\t" +
Que fait exactement ce transtypage ? En d'autres termes, si on obtient une valeur de "RandomBounds lower\n\t" +
29.7 et qu'on la transtype en char, le rsultat est-il 30 ou 29 ? La rponse est dans "RandomBounds upper");
l'exemple suivant : System.exit(1);
}
//: c03:CastingNumbers.java public static void main(String[] args) {
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 87/459
if(args.length != 1) usage(); Thinking in Java Annotated Solution Guide, disponible pour un faible cot
if(args[0].equals("lower")) { www.BruceEckel.com.
while(Math.random() != 0.0)
; // Essayer encore 1. Dans la section priorit au dbut de ce chapitre, il y a deux expressions.
System.out.println("Produced 0.0!"); Utiliser ces expressions dans un programme qui montre qu'elles produisent
}
else if(args[0].equals("upper")) { des rsultats diffrents.
while(Math.random() != 1.0) 2. Utiliser les mthodes ternary( ) et alternative( ) dans un programme qui
; // Essayer encore fonctionne.
System.out.println("Produced 1.0!"); 3. partir des sections if-else et return , utiliser les mthodes test( ) et
} test2( ) dans un programme qui fonctionne.
else
usage(); 4. crire un programme qui imprime les valeurs de un 100.
} 5. Modifier l'exercice 4 de manire que le programme termine avec la valeur
} ///:~ 47, en utilisant le mot clef break. Mme exercice en utilisant return.
6. crire une fonction prenant pour arguments deux String, utiliser les
Pour lancer le programme, frapper en ligne de commande : comparaisons boolennes pour comparer les deux chanes et imprimer le
rsultat. En plus de == et !=, tester aussi equals( ). Dans la mthode main( ),
java RandomBounds lower
appeler la fonction avec diffrents objets de type String.
7. crire un programme qui gnre alatoirement 25 valeurs entires. Pour
ou bien : chaque valeur, utiliser une instruction if-then-else pour la classer (plus
java RandomBounds upper grande, plus petite, ou gale) par rapport une deuxime valeur gnre
alatoirement.
Dans les deux cas nous sommes obligs d'arrter le programme manuellement, et il 8. Modifier l'exercice 7 en englobant le code dans une boucle while infinie. Il
semble donc que Math.random( ) ne produise jamais les valeurs 0.0 ou 1.0. Une devrait alors fonctionner tant qu'on ne l'interrompt pas au moyen du clavier
telle exprience est dcevante. Si vous remarquez [26] qu'il existe environ 262 (classiquement avec Ctrl-C).
fractions diffrentes en double-prcision entre 0 et 1, alors la probabilit d'atteindre 9. crire un programme utilisant deux boucles for imbriques ainsi que
exprimentalement l'une ou l'autre des valeurs pourrait dpasser la vie d'un l'oprateur modulo (%) pour dtecter et imprimer les nombres premiers (les
ordinateur, voire celle de l'exprimentateur. Cela ne permet pas de montrer que 0.0 nombres entiers qui ne sont divisibles que par eux-mmes et l'unit).
est inclus dans les rsultats de Math.random( ). En ralit, en jargon 10. crire une instruction switch qui imprime un message pour chaque case,
mathmatique, le rsultat est [0,1[. la mettre dans une boucle for qui teste chaque case. Mettre un break
aprs chaque case, tester, puis enlever les break et voir ce qui se passe..
Rsum [25] John Kirkham crivait, J'ai fait mes dbuts en informatique en 1962 avec
FORTRAN II sur un IBM 1620. cette poque, pendant les annes 60 et jusqu'au
dbut des annes 70, FORTRAN tait un langage entirement crit en majuscules.
Ce chapitre termine l'tude des fonctionnalits fondamentales qu'on retrouve dans Sans doute parce que beaucoup de priphriques d'entre anciens taient de vieux
la plupart des langages de programmation : calcul, priorit des oprateurs, tlscripteurs utilisant le code Baudot cinq moments ( cinq bits), sans possibilit
transtypage, slection et itration. Vous tes dsormais prts aborder le monde de de minuscules. La lettre 'E' dans la notation scientifique tait en majuscule et ne
la programmation oriente objet. Le prochain chapitre traite de la question pouvait jamais tre confondue avec la base 'e' des logarithmes naturels, toujours
importante de l'initialisation et du nettoyage des objets, et le suivant du concept crite en minuscule. 'E' signifiait simplement puissance, et, naturellement,
essentiel consistant cacher l'implmentation. puissance de la base de numration habituellement utilise c'est dire puissance de
10. cette poque galement, l'octal tait largement utilis par les programmeurs.
Bien que je ne l'aie jamais vu utiliser, si j'avais vu un nombre octal en notation
Exercices scientifique j'aurais pens qu'il tait en base 8. Mon plus ancien souvenir d'une
notation scientifique utilisant un 'e' minuscule remonte la fin des annes 70 et je
Les solutions des exercices slectionns sont dans le document lectronique The trouvais immdiatement cela droutant. Le problme apparut lorsqu'on introduisit
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 88/459
les minuscules en FORTRAN, et non ses dbuts. En ralit il existait des fonctions oubli sont conserves. Ce phnomne peut entraner un manque de ressources
qui manipulaient la base des logarithmes naturels, et elles taient toutes en (dans la majorit des cas, un manque de mmoire).
majuscules.
C++ a introduit la notion de constructeur, une mthode appele automatiquement
[26] Chuck Allison crivait : Le nombre total de nombres dans un systme virgule la cration d'un objet. Java utilise aussi les constructeurs, associ un ramasse-
flottante est 2(M-m+1)b^(p-1) + 1 o b est la base (gnralement 2), p la miettes qui libre les ressources mmoire lorsqu'elles ne sont plus utilises. Ce
prcision (le nombre de chiffres dans la mantisse), M le plus grand exposant, et m le chapitre dcrit les concepts d'initialisation et de libration, ainsi que leur support
plus petit. Dans la norme IEEE 754, on a : M = 1023, m = -1022, p = 53, b = 2 dans Java.
d'o le nombre total de nombres est 2(1023+1022+1)2^52 = 2((2^10-1) +
(2^10-1))2^52 = (2^10-1)2^54 = 2^64 - 2^54 La moiti de ces nombres
(correspondant un exposant dans l'intervalle[-1022, 0]) sont infrieurs un en Garantie d'initialisation grce au
valeur absolue, et donc 1/4 de cette expression, soit 2^62 - 2^52 + 1
(approximativement 2^62) est dans l'intervalle [0,1[. Voir mon article constructeur
http://www.freshsources.com/1995006a.htm (suite de l'article).
Pour chaque classe il serait possible de crer une mthode initialise( ). Ce nom
#/TIJ_PAGE06#
inciterait excuter la mthode avant d'utiliser l'objet. Malheureusement ce serait
"HTTP://WWW.W3.ORG/TR/HTML4/LOOSE.DTD"> #TIJ_PAGE01# l'utilisateur de se souvenir d'appeler cette mthode pour chaque instance. En Java,
05.07.01 - version 1.5 [Armel] : le concepteur d'une classe peut garantir son initialisation grce une mthode
- Ajout des tags de sparation des pages pour le site. spciale que l'on dnomme constructeur. Quand une classe possde un
25.04.2001 - version 1.4 [Armel] : constructeur, Java l'appelle automatiquement toute cration d'objets, avant qu'ils
- Mise en forme du code html (titres-hx[verdana], paragraphes- ne puissent tre utiliss. L'initialisation est donc bien garantie.
p[Georgia], code-blockquote).
13.04.2001 - version 1.3 [Florence DEFAIX] Le premier problme consiste trouver un nom pour cette mthode ce qui entrane
- Aprs corrections proposes par Jrome QUELIN et J-P VIDAL. deux nouveaux problmes. Tout d'abord il pourrait y avoir un conflit avec le nom
Traducteur : d'un attribut. Ensuite c'est la compilation que l'appel du constructeur est vrifi. Il
- Florence DEFAIX & Y. CHICHA
Texte original : faut donc que le compilateur puisse dcider du nom du constructeur. La solution de
-Thinking in Java, 2nd edition, Revision 10 C++ parat la plus simple et la plus logique, elle est donc aussi utilise en Java. Il
2000 by Bruce Eckel faut donc donner au constructeur le nom de sa classe. Il semble naturel qu'une telle
mthode soit en charge de l'initialisation de la classe.
Voici une classe avec un constructeur :
4: Initialisation & Nettoyage //: c04:SimpleConstrutor.java
// Dmonstration d'un constructeur.
class Rock {
Depuis le dbut de la rvolution informatique, la Rock() { // Ceci est un constructeur
System.out.println("Creating Rock");
programmation sans garde-fou est la principale cause }
}
des cots de dveloppement excessifs. public class SimpleConstructor {
public static void main(String[] args) {
L'initialisation et la libration d'lments sont deux problmes majeurs. De for(int i = 0; i < 10; i++)
nombreux bogues en C surviennent lorsque le programmeur oublie d'initialiser une new Rock();
variable. L'utilisation de blibliothques augmente ce risque car les utilisateurs ne }
savent pas toujours comment initialiser certains composants, ni mme qu'ils le } ///:~
doivent. La phase de nettoyage ou libration pose problme dans la mesure o il est
trs facile d'oublier l'existence d'un lment dont on n'a plus besoin, car justement il Quand un objet est cr :
ne nous intresse plus. Dans ce cas, certaines ressources utilises par un lment
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 89/459
new Rock(); trouver une utilisation cette valeur.
de l'espace mmoire est allou et le constructeur est appel. L'objet sera
obligatoirement initialis avant qu'il ne puisse tre manipul. Surcharge de mthodes
Notez que la convention de nommage qui impose une minuscule pour la premire
lettre des noms de mthode ne s'applique pas aux constructeurs, leur nom devant L'un des points les plus importants de tout langage de programmation est le
exactement concider avec celui de la classe. nommage. Crer un objet revient donner un nom un emplacement mmoire. Une
mthode est un nom d'action. En utilisant des noms pour dcrire un systme, on
Comme les autres mthodes, un constructeur peut prendre des paramtres. Cela simplifie la lecture et la modification des programmes. Cela s'apparente l'criture
permet de prciser comment l'objet va tre cr. Notre premier exemple peut en prose dont le but est de communiquer avec le lecteur.
facilement tre modifi pour que le constructeur prenne un unique paramtre :
On se rfre tous les objets et mthodes en utilisant leurs noms. Des noms biens
//: c04:SimpleConstructor2.java choisis rendent la comprhension du code plus aise, tant pour le dveloppeur que
// Les constructeurs peuvent prendre des paramtres.
class Rock2 {
pour les relecteurs.
Rock2(int i) { Les difficults commencent lorsque l'on essaie d'exprimer les nuances subtiles du
System.out.println(
"Creating Rock number " + i);
langage humain dans un langage de programmation. Trs souvent, un mme mot a
} plusieurs sens, on parle de surcharge. Cette notion est trs pratique pour exprimer
} les diffrences triviales de sens. On dit laver la chemise , laver la voiture et
public class SimpleConstructor2 { laver le chien . Cela paratrait absurde d'tre oblig de dire laverChemise la
public static void main(String[] args) { chemise , laverVoiture la voiture et laverChien le chien pour que
for(int i = 0; i < 10; i++)
new Rock2(i);
l'auditoire puisse faire la distinction entre ces actions. La plupart des langages
} humains sont redondants tel point que mme sans entendre tous les mots, il est
} ///:~ toujours possible de comprendre le sens d'une phrase. Nous n'avons aucunement
besoin d'identifiants uniques, le sens peut tre dduit du contexte.
Les paramtres des constructeurs permettent de personnaliser la cration des La plupart des langages de programation (C en particulier) imposent un nom unique
objets. Par exemple, si la classe Tree (arbre) a un constructeur avec un paramtre pour chaque fonction. Ils ne permettent pas d'appeler une fonction affiche( ) pour
de type int qui dtermine la hauteur de l'arbre, un objet Tree se cre de la faon afficher des entiers et une autre appele affiche( ) pour afficher des flottants,
suivante : chaque fonction doit avoir un nom unique.
Tree t = new Tree(12);// arbre de 12 pieds En Java (et en C++), un autre facteur impose la surcharge de noms de mthodes :
les constructeurs. Comme le nom d'un constructeur est dtermin par le nom de la
De plus, si Tree(int) est le seul constructeur, le compilateur ne permettra pas de classe, il ne peut y avoir qu'un seul nom de constructeur. Mais que se passe-t-il
crer un objet Tree d'une autre faon. quand on veut crer un objet de diffrentes faons ? Par exemple, supposons que
La notion de constructeur limine toute une catgorie d'erreurs et rend plus aise la l'on construise une classe qui peut s'initialiser de faon standard ou en lisant des
lecture du code. Dans le fragment de code prcdent, par exemple, il n'y a pas informations depuis un fichier. Nous avons alors besoin de deux constructeurs, l'un
d'appel explicite une certaine mthode initialise( ) qui serait conceptuellement ne prenant pas de paramtre ( le constructeur par dfaut, aussi appel le
spare de la dfinition. En Java, definition et initialisation sont des concepts unifis constructeur sans paramtre / no-arg ), et un autre prenant une Chane / String
- il est impossible d'avoir l'un sans l'autre. comme paramtre, qui reprsente le nom du fichier depuis lequel on souhaite
initialiser l'objet. Tous les deux sont des constructeurs, ils doivent donc avoir le
Un constructeur est une mthode trs spciale de par le fait qu'elle n'a pas de valeur mme nom, le nom de la classe. Cela montre que la surcharge de mthode est
de retour. Cela n'a absolument rien voir avec le type de retour void, qui signifie essentielle pour utiliser le mme nom de mthode pour des utilisations sur
qu'une mthode ne renvoie rien mais qu'il aurait tout fait t possible de lui faire diffrents types de paramtres. Et si la surcharge de mthode est obligatoire pour les
renvoyer autre chose. Les constructeurs ne retournent rien et on n'a pas le choix. S'il constructeurs, elle est aussi trs pratique pour les mthodes ordinaires.
y avait une valeur de retour, et si l'on pouvait choisir son type, le compilateur devrait
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 90/459
L'exemple suivant montre la fois une surcharge de constructeur et une surcharge paramtre lorsqu'il n'y a rien d'autre dire. Cela paratrait trange de donner deux
de mthode ordinaire : noms distincts ce qui est manifestement le mme concept. Heureusement, la
//: c04:Overloading.java surchage de mthode permet l'utilisation du mme nom pour les deux.
// Exemple de surcharge de constructeur
// et de mthode ordinaire.
import java.util.*; Diffrencier les mthodes surcharges
class Tree {
int height; Quand deux mthodes ont le mme nom, comment Java peut-il dcider quelle
Tree() {
prt("Planting a seedling");// Planter une jeune pousse
mthode est demande ? Il y a une rgle toute simple : chaque mthode surcharge
height = 0; doit prendre une liste unique de types de paramtres.
}
Tree(int i) {
Lorsqu'on y pense, cela parat tout fait sens : comment le dveloppeur lui-mme
prt("Creating new Tree that is " // Cration d'un Arbre pourrait-il choisir entre deux mthodes du mme nom, autrement que par le type
+ i + " feet tall"); // de i pieds de haut des paramtres ?
height = i;
} Une diffrence dans l'ordre des paramtres est suffisante pour distinguer deux
void info() { mthodes ( cette approche n'est gnralement pas utilise car elle donne du code
prt("Tree is " + height // L'arbre mesure x pieds difficile maintenir.) :
+ " feet tall");
} //: c04:OverloadingOrder.java
void info(String s) { // Surcharge base sur l'ordre
prt(s + ": Tree is " // valeur de s :L'arbre mesure x // des paramtres.
pieds public class OverloadingOrder {
+ height + " feet tall"); static void print(String s, int i) {
} System.out.println(
static void prt(String s) { "String: " + s +
System.out.println(s); ", int: " + i);
} }
} static void print(int i, String s) {
public class Overloading { System.out.println(
public static void main(String[] args) { "int: " + i +
for(int i = 0; i < 5; i++) { ", String: " + s);
Tree t = new Tree(i); }
t.info(); public static void main(String[] args) {
t.info("overloaded method"); print("String first", 11);
} print(99, "Int first");
// constructeur surcharg : }
new Tree(); } ///:~
}
} ///:~ Les deux mthodes print( ) ont les mmes paramtres, mais dans un ordre
diffrent, et c'est ce qui les diffrencie.
Un objet Tree peut tre cr soit en tant que jeune pousse, sans fournir de
paramtre, soit en tant que plante pousse en ppinire, en donnant une hauteur
initiale. Pour permettre ceci, il y a deux constructeurs, l'un ne prend pas de Surcharge avec types de base
paramtre (on appelle les constructeurs sans paramtre des constructeurs par
dfaut name="fnB27">[27]) et un deuxime qui prend la hauteur initiale de l'arbre. Un type de base peut tre promu automatiquement depuis un type plus petit vers un
plus grand ; ceci peut devenir dconcertant dans certains cas de surcharge.
Il est aussi possible d'appeler la mthode info( ) de plusieurs faons. Par exemple, L'exemple suivant montre ce qui se passe lorsqu'un type de base est pass une
avec un paramtre String si un message supplmentaire est dsir, ou sans mthode surcharge :
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 91/459
//: c04:PrimitiveOverloading.java }
// Promotion des types de base et surcharge. void testInt() {
public class PrimitiveOverloading { int x = 0;
// boolean ne peut pas tre converti automatiquement prt("int argument:");
static void prt(String s) { f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
System.out.println(s); }
} void testLong() {
void f1(char x) { prt("f1(char)"); } long x = 0;
void f1(byte x) { prt("f1(byte)"); } prt("long argument:");
void f1(short x) { prt("f1(short)"); } f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
void f1(int x) { prt("f1(int)"); } }
void f1(long x) { prt("f1(long)"); } void testFloat() {
void f1(float x) { prt("f1(float)"); } float x = 0;
void f1(double x) { prt("f1(double)"); } prt("float argument:");
void f2(byte x) { prt("f2(byte)"); } f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
void f2(short x) { prt("f2(short)"); } }
void f2(int x) { prt("f2(int)"); } void testDouble() {
void f2(long x) { prt("f2(long)"); } double x = 0;
void f2(float x) { prt("f2(float)"); } prt("double argument:");
void f2(double x) { prt("f2(double)"); } f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
void f3(short x) { prt("f3(short)"); } }
void f3(int x) { prt("f3(int)"); } public static void main(String[] args) {
void f3(long x) { prt("f3(long)"); } PrimitiveOverloading p =
void f3(float x) { prt("f3(float)"); } new PrimitiveOverloading();
void f3(double x) { prt("f3(double)"); } p.testConstVal();
void f4(int x) { prt("f4(int)"); } p.testChar();
void f4(long x) { prt("f4(long)"); } p.testByte();
void f4(float x) { prt("f4(float)"); } p.testShort();
void f4(double x) { prt("f4(double)"); } p.testInt();
void f5(long x) { prt("f5(long)"); } p.testLong();
void f5(float x) { prt("f5(float)"); } p.testFloat();
void f5(double x) { prt("f5(double)"); } p.testDouble();
void f6(float x) { prt("f6(float)"); } }
void f6(double x) { prt("f6(double)"); } } ///:~
void f7(double x) { prt("f7(double)"); }
void testConstVal() {
prt("Testing with 5"); En regardant la sortie du programme, on voit que la constante 5 est considre
f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5); comme un int. Lorsqu'une mthode surcharge utilisant un int est disponible, elle
} est utilise. Dans tous les autres cas, si un type de donnes est plus petit que
void testChar() { l'argument de la mthode, le type est promu. char est lgrerent diffrent, comme il
char x = 'x';
prt("char argument:");
ne trouve pas une correspondance exacte, il est promu vers un int.
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); #/TIJ_PAGE01# #TIJ_PAGE02#
}
void testByte() { Qu'arrive-t'il lorsque le paramtre est plus grand que celui attendu par la mthode
byte x = 0; surcharge ? Une modification du programme prcdent donne la rponse :
prt("byte argument:");
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); //: c04:Demotion.java
} // Types de base dchus et surcharge.
void testShort() { public class Demotion {
short x = 0; static void prt(String s) {
prt("short argument:"); System.out.println(s);
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); }
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 92/459
void f1(char x) { prt("f1(char)"); }
void f1(byte x) { prt("f1(byte)"); } Surcharge sur la valeur de retour
void f1(short x) { prt("f1(short)"); }
void f1(int x) { prt("f1(int)"); }
Il est frquent de se demander Pourquoi seulement les noms de classes et la liste
void f1(long x) { prt("f1(long)"); }
void f1(float x) { prt("f1(float)"); } des paramtres des mthodes ? Pourquoi ne pas aussi distinguer entre deux
void f1(double x) { prt("f1(double)"); } mthodes en se basant sur leur type de retour ? Par exemple, ces deux mthodes,
void f2(char x) { prt("f2(char)"); } qui ont le mme nom et les mmes arguments, peuvent facilement tre distingues
void f2(byte x) { prt("f2(byte)"); } l'une de l'autre :
void f2(short x) { prt("f2(short)"); }
void f2(int x) { prt("f2(int)"); } void f() {}
void f2(long x) { prt("f2(long)"); } int f() {}
void f2(float x) { prt("f2(float)"); }
void f3(char x) { prt("f3(char)"); }
void f3(byte x) { prt("f3(byte)"); } Cela fonctionne bien lorsque le compilateur peut dterminer le sens sans quivoque
void f3(short x) { prt("f3(short)"); } depuis le contexte, comme dans int x = f( ). Par contre, on peut utiliser une
void f3(int x) { prt("f3(int)"); } mthode et ignorer sa valeur de retour. On se rfre souvent cette action comme
void f3(long x) { prt("f3(long)"); } appeler une mthode pour ses effets de bord puisqu'on ne s'intresse pas la valeur
void f4(char x) { prt("f4(char)"); } de retour mais aux autres effets que cet appel de mthode gnre. Donc, si on
void f4(byte x) { prt("f4(byte)"); }
void f4(short x) { prt("f4(short)"); } appelle la mthode comme suit :
void f4(int x) { prt("f4(int)"); } f();
void f5(char x) { prt("f5(char)"); }
void f5(byte x) { prt("f5(byte)"); }
void f5(short x) { prt("f5(short)"); } Comment Java peut-il dterminer quelle mthode f( ) doit tre excute ? Et
void f6(char x) { prt("f6(char)"); } comment quelqu'un lisant ce code pourrait-il le savoir ? A cause de ce genre de
void f6(byte x) { prt("f6(byte)"); } difficults, il est impossible d'utiliser la valeur de retour pour diffrencier deux
void f7(char x) { prt("f7(char)"); } mthodes Java surcharges.
void testDouble() {
double x = 0;
prt("double argument:");
f1(x);f2((float)x);f3((long)x);f4((int)x);
Constructeurs par dfaut
f5((short)x);f6((byte)x);f7((char)x);
} Comme mentionn prcdemment, un constructeur par dfaut (c.a.d un
public static void main(String[] args) { constructeur no-arg ) est un constructeur sans argument, utilis pour crer des
Demotion p = new Demotion();
p.testDouble(); objets de base . Si une classe est cre sans constructeur, le compilateur cr
} automatiquement un constructeur par dfaut. Par exemple :
} ///:~ //: c04:DefaultConstructor.java
class Bird {
Ici, les mthodes prennent des types de base plus restreints. Si les paramtres sont int i;
}
d'un type plus grand, if faut les caster (convertir) vers le type requis en utilisant le public class DefaultConstructor {
nom du type entre parenthses. Sinon, le compilateur donnera un message d'erreur. public static void main(String[] args) {
Bird nc = new Bird(); // dfaut !
Il est important de noter qu'il s'agit d'une conversion vers un type plus petit, ce qui }
signifie que des informations peuvent tre perdues pendant la conversion. C'est } ///:~
d'ailleurs pour cette raison que le compilateur force une conversion explicite.
La ligne
new Bird();
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 93/459
cre un nouvel objet et appelle le constructeur par dfaut, mme s'il n'tait pas obtenir une rfrence sur l'objet courant. Comme cette rfrence est passe en tant
dfini explicitement. Sans lui, il n'y aurait pas de mthode appeler pour crer cet que paramtre cach par le compilateur, il n'y a pas d'identificateur pour elle. Cette
objet. Par contre, si au moins un constructeur est dfini (avec ou sans argument), le pour cette raison que le mot cl this existe. this - qui ne peut tre utilis qu'
compilateur n'en synthtisera pas un : l'intrieur d'une mthode - est une rfrence sur l'objet pour lequel cette mthode
class Bush { t appele. On peut utiliser cette rfrence comme tout autre rfrence vers un
Bush(int i) {} objet. Il n'est toutefois pas ncessaire d'utiliser this pour appeler une mthode de la
Bush(double d) {} classe courante depuis une autre mthode de la classe courante ; il suffit d'appeler
} cette mthode. La rfrence this est automatiquement utilise pour l'autre
mthode. On peut crire :
Maintenant si on crit : class Apricot {
new Bush(); void pick() { /* ... */ }
void pit() { pick(); /* ... */ }
}
le compilateur donnera une erreur indiquant qu'aucun constructeur ne correspond.
C'est comme si lorsqu'aucun constructeur n'est fourni, le compilateur dit Il faut un A l'intrieur de pit( ), on pourrait crire this.pick( ) mais ce n'est pas ncessaire.
constructeur, je vais en crer un. Alors que s'il existe un constructeur, le Le compilateur le fait automatiquement pour le dveloppeur. Le mot-cl this est
compilateur dit Il y a un constructeur donc le dveloppeur sait se qu'il fait; s'il n'a uniquement utilis pour les cas spciaux dans lesquels on doit utiliser explicitement
pas dfini de constructeur par dfaut c'est qu'il ne dsirait pas qu'il y en ait un. une rfrence sur l'objet courant. Par exemple, il est courament utilis en
association avec return quand on dsire renvoyer une rfrence sur l'objet
Le mot-cl this courant :
//: c04:Leaf.java
Lorsqu'il existe deux objets a et b du mme type , il est intressant de se demander // Utilisation simple du mot-cl "this".
comment on peut appeler une mthode f( ) sur ces deux objets : public class Leaf {
int i = 0;
class Banana { void f(int i) { /* ... */ } } Leaf increment() {
Banana a = new Banana(), b = new Banana(); i++;
a.f(1); return this;
b.f(2); }
void print() {
System.out.println("i = " + i);
S'il y a une unique mthode f( ), comment cette mthode peut-elle savoir si elle a t }
appele sur l'objet a ou b ? public static void main(String[] args) {
Leaf x = new Leaf();
Pour permettre au dveloppeur d'crire le code dans une syntaxe pratique et orient x.increment().increment().increment().print();
objet dans laquelle on envoie un message vers un objet, le compilateur effectue un }
travail secret pour le dveloppeur. Il y a un premier paramtre cach pass la } ///:~
mthode f( ), et ce paramtre est une rfrence vers l'objet en train d'tre manipul.
Les deux appels de mthode prcdents correspondent donc ceci : Puisque increment( ) renvoie une rfrence vers l'objet courant par le biais du
Banana.f(a,1); mot-cl this, on peut facilement appeler plusieurs oprations successivement sur le
Banana.f(b,2); mme objet.
Ce travail est interne et il est impossible d'crire des expressions de ce type
directement en esprant que le compilateur les acceptera, mais cela donne une ide
de ce qui se passe.
Supposons maintenant que l'on est l'intrieur d'une mthode et que l'on dsire
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 94/459
Appeler un constructeur depuis un autre constructeur } ///:~
Quand une classe possde plusieurs constructeurs, il peut tre utile d'appeler un Le constructeur Flower(String s, int petals) montre qu'on peut appeler un
constructeur depuis un autre pour viter de la duplication de code. C'est possible constructeur en utilisant this, mais pas deux. De plus, l'appel au constructeur doit
grce au mot-cl this. absolument tre la premire instruction sinon le compilateur donnera un message
d'erreur.
En temps normal, this signifie cet objet ou l'objet courant, et renvoie une
rfrence sur l'objet courant. Dans un constructeur, le mot-cl this prend un sens Cet exemple montre aussi un usage diffrent du mot-cl this. Les noms du
diffrent quand on lui passe une liste de paramtres : il signifie un appel explicite au paramtre s et du membre de donnes s tant les mmes, il y a ambigute. On la
constructeur qui correspond cette liste de paramtres. Cela donne un moyen trs rsoud en utilisant this.s pour se rfrer au membre de donns. Cette forme est trs
simple d'appeler d'autres constructeurs : courante en Java et utilise frquemment dans ce livre.
//: c04:Flower.java Dans la mthode print( ) on peut voir que le compilateur ne permet pas l'appel
// Appel de constructeurs avec "this." d'un constructeur depuis toute autre mthode qu'un constructeur.
public class Flower {
La signification de static
int petalCount = 0;
String s = new String("null");
Flower(int petals) {
petalCount = petals; En pensant au mot-cl this, on comprend mieux le sens de rendre une mthode
// Constructeur avec un unique paramtre int
System.out.println( statics. Cela signifie qu'il n'y a pas de this pour cette mthode. Il est impossible
"Constructor w/ int arg only, petalCount= " d'appeler une mthode non-static depuis une mthode static [28] (par contre,
+ petalCount); l'inverse est possible), et il est possible d'appeler une mthode static sur la classe
} elle-mme, sans aucun objet. En fait, c'est principalement la raison de l'existence
Flower(String ss) { des mthodes static. C'est l'quivalent d'une fonction globale en C. Sauf que les
// Constructeur avec un unique paramtre String
System.out.println(
fonctions globales sont interdites en Java, et ajouter une mthode static dans une
"Constructor w/ String arg only, s=" + ss); classe lui permet d'accder d'autres mthodes static ainsi qu'aux membres static.
s = ss;
} Certaines personnes argumentent que les mthodes static ne sont pas orientes
Flower(String s, int petals) { objet puisqu'elles ont la smantique des fonctions globales ; avec une mthode
this(petals); static on n'envoie pas un message vers un objet, puisqu'il n'y a pas de this. C'est
//!this(s); // Impossible d'en appeler deux ! probablement un argument valable, et si vous utilisez beaucoup de mthodes
this.s = s; // Autre usage de "this" statiques vous devriez repenser votre stratgie. Pourtant, les mthodes statics sont
System.out.println("String & int args");
} utiles et il y a des cas o on en a vraiment besoin. On peut donc laisser les
// Constructeur par dfaut thoriciens dcider si oui ou non il s'agit de vraie programmation oriente objet.
Flower() { D'ailleurs, mme Smalltalk a un quivalent avec ses mthodes de classe.
this("hi", 47);
Nettoyage : finalisation et ramasse-
System.out.println(
"default constructor (no args)");
}
void print() {
//!this(11); // Pas l'intrieur d'une mthode normale ! miettes
System.out.println(
"petalCount = " + petalCount + " s = "+ s); Les programmeurs connaissent l'importance de l'initialisation mais oublient
}
public static void main(String[] args) { souvent celle du nettoyage. Aprs tout, qui a besoin de nettoyer un int ? Cependant,
Flower x = new Flower(); avec des bibliothques, simplement oublier un objet aprs son utilisation n'est pas
x.print(); toujours sr. Bien entendu, Java a un ramasse-miettes pour rcuprer la mmoire
} prise par des objets qui ne sont plus utiliss. Considrons maintenant un cas trs
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 95/459
particulier. Supposons que votre objet alloue une zone de mmoire spciale sans
utiliser new. Le ramasse-miettes ne sait rcuprer que la mmoire alloue avec
A quoi sert finalize( ) ?
new, donc il ne saura pas comment rcuprer la zone speciale de mmoire
utilise par l'objet. Pour grer ce cas, Java fournit une mthode appele finalize( ) A ce point, on peut croire qu'il ne faudrait pas utiliser finalize( ) comme mthode
qui peut tre dfinie dans votre classe. Voici comment c'est suppos marcher. Quand gnrale de nettoyage. A quoi sert-elle alors ?
le ramasse-miettes est prt librer la mmoire utilise par votre objet, il va d'abord Une troisime rgle stipule :
appeler finalize( ) et ce n'est qu' la prochaine passe du ramasse-miettes que la
mmoire de l'objet est libre. En choisissant d'utiliser finalize( ), on a la Le ramasse-miettes ne s'occupe que de la mmoire.
possibilit d'effectuer d'importantes tches de nettoyage l'excution du ramasse-
miettes. C'est dire que la seule raison d'exister du ramasse-miettes est de rcuprer la
mmoire que le programme n'utilise plus. Par consquent, toute activit associe au
C'est un pige de programmation parce que certains programmeurs, ramasse-miettes, la mthode finalize( ) en particulier, doit se concentrer sur la
particulirement les programmeurs C++, risquent au dbut de confondre finalize mmoire et sa libration.
( ) avec le destructeur de C++ qui est une fonction toujours appele quand un objet
est dtruit. Cependant il est important ici de faire la diffrence entre C++ et Java, Est-ce que cela veut dire que si un objet contient d'autres objets, finalize( ) doit
car en C++ les objets sont toujours dtruits (dans un programme sans bug), alors librer ces objets explicitement ? La rponse est... non. Le ramasse-miettes prend
qu'en Java les objets ne sont pas toujours rcuprs par le ramasse-miettes. Dit soin de librer tous les objets quelle que soit la faon dont ils ont t crs. Il se
autrement : trouve que l'on a uniquement besoin de finalize( ) dans des cas bien prcis o un
objet peut allouer de la mmoire sans crer un autre objet. Cependant vous devez
Le mcanisme de ramasse-miettes n'est pas un mcanisme vous dire que tout est objet en Java, donc comment est-ce possible ?
de destruction. Il semblerait que finalize( ) ait t introduit parce qu'il est possible d'allouer de la
mmoire -la-C en utilisant un mcanisme autre que celui propos normalement par
Si vous vous souvenez de cette rgle de base, il n'y aura pas de problme. Cela veut Java. Cela arrive gnralement avec des mthodes natives, qui sont une faon
dire que si une opration doit tre effectue avant la disparition d'un objet, celle-ci d'appeler du code non-Java en Java (les mthodes natives sont expliques en
est la charge du dveloppeur. Java n'a pas de mcanisme quivalent au Appendice B). C et C++ sont les seuls langages actuellement supports par les
destructeur, il est donc ncessaire de crer une mthode ordinaire pour raliser ce mthodes natives, mais comme elles peuvent appeler des routines crites avec
nettoyage. Par exemple, supposons qu'un objet se dessine l'cran pendant sa d'autres langages, il est en fait possible d'appeler n'importe quoi. Dans ce code non-
cration. Si son image n'est pas efface explicitement de l'cran, il se peut qu'elle ne Java, on peut appeler des fonctions de la famille de malloc( ) en C pour allouer de
le soit jamais. Si l'on ajoute une fonctionnalit d'effacement dans finalize( ), alors la mmoire, et moins qu'un appel free( ) ne soit effectu cette mmoire ne sera
l'image sera efface de l'cran si l'objet est rcupr par le ramasse-miette, sinon pas libre, provoquant une fuite. Bien entendu, free( ) est une fonction C et
l'image restera. Il y a donc une deuxime rgle se rappeler : C++, ce qui veut dire qu'elle doit tre appele dans une mthode native dans le
finalize( ) correspondant.
Les objets peuvent ne pas tre rcuprs par le ramasse-
miettes. #/TIJ_PAGE02# #TIJ_PAGE03#
Il se peut que la mmoire prise par un objet ne soit jamais libre parce que le Maintenant, vous vous dites probablement que vous n'allez pas beaucoup utiliser
programme n'approche jamais la limite de mmoire qui lui a t attribue. Si le finalize( ). Vous avez raison : ce n'est pas l'endroit appropri pour effectuer des
programme se termine sans que le ramasse-miettes n'ait jamais libr la mmoire oprations normales de nettoyage. Dans ce cas, o celles-ci doivent-elles se passer ?
prise par les objets, celle-ci sera rendue en masse (NDT : en franais dans le texte)
au systme d'exploitation au moment o le programme s'arrte. C'est une bonne Le nettoyage est impratif
chose, car le ramasse-miettes implique un cot supplmentaire et s'il n'est jamais
appel, c'est autant d'conomis. Pour nettoyer un objet, son utilisateur doit appeler une mthode de nettoyage au
moment o celui-ci est ncessaire. Cela semble assez simple, mais se heurte au
concept de destructeur de C++. En C++, tous les objets sont, ou plutt devraient
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 96/459
tre, dtruits. Si l'objet C++ est cr localement (c'est dire sur la pile, ce qui n'est "Finalizing Chair #47, " +
pas possible en Java), alors la destruction se produit la fermeture de la porte dans "Setting flag to stop Chair creation");
f = true;
laquelle l'objet a t cr. Si l'objet a t cr par new (comme en Java) le }
destructeur est appel quand le programmeur appelle l'oprateur C++ delete (cet finalized++;
oprateur n'existe pas en Java). Si le programmeur C++ oublie d'appeler delete, le if(finalized >= created)
destructeur n'est jamais appel et l'on obtient une fuite mmoire. De plus les System.out.println(
membres de l'objet ne sont jamais nettoy non plus. Ce genre de bogue peut tre trs "All " + finalized + " finalized");
}
difficile reprer. }
Contrairement C++, Java ne permet pas de crer des objets locaux, new doit public class Garbage {
public static void main(String[] args) {
toujours tre utilis. Cependant Java n'a pas de delete pour librer l'objet car le // Tant que le flag n'a pas t lev,
ramasse-miettes se charge automatiquement de rcuprer la mmoire. Donc d'un // construire des objets Chair et String:
point de vue simplistique, on pourrait dire qu' cause du ramasse-miettes, Java n'a while(!Chair.f) {
pas de destructeur. Cependant mesure que la lecture de ce livre progresse, on new Chair();
s'aperoit que la prsence d'un ramasse-miettes ne change ni le besoin ni l'utilit des new String("To take up space");
}
destructeurs (de plus, finalize( ) ne devrait jamais tre appel directement, ce n'est System.out.println(
donc pas une bonne solution pour ce problme). Si l'on a besoin d'effectuer des "After all Chairs have been created:\n" +
oprations de nettoyage autre que librer la mmoire, il est toujours ncessaire "total created = " + Chair.created +
d'appeler explicitement la mthode correspondante en Java, ce qui correspondra ", total finalized = " + Chair.finalized);
un destructeur C++ sans tre aussi pratique. // Arguments optionnels pour forcer
// la finalisation et l'excution du ramasse-miettes :
Une des utilisations possibles de finalize( ) est l'observation du ramasse-miettes. if(args.length > 0) {
L'exemple suivant montre ce qui se passe et rsume les descriptions prcdentes du if(args[0].equals("gc") ||
args[0].equals("all")) {
ramasse-miettes : System.out.println("gc():");
//: c04:Garbage.java System.gc();
// Dmonstration du ramasse-miettes }
// et de la finalisation if(args[0].equals("finalize") ||
class Chair { args[0].equals("all")) {
static boolean gcrun = false; System.out.println("runFinalization():");
static boolean f = false; System.runFinalization();
static int created = 0; }
static int finalized = 0; }
int i; System.out.println("bye!");
Chair() { }
i = ++created; } ///:~
if(created == 47)
System.out.println("Created 47"); Le programme ci-dessus cre un grand nombre d'objets Chair et, un certain point
}
public void finalize() { aprs que le ramasse-miettes ait commenc s'excuter, le programme arrte de
if(!gcrun) { crer des Chairs. Comme le ramasse-miettes peut s'excuter n'importe quand, on
// Premier appel de finalize() : ne sait pas exactement quel moment il se lance, il existe donc un flag appel
gcrun = true; gcrun qui indique si le ramasse-miettes a commenc son excution. Un deuxime
System.out.println( flag f est le moyen pour Chair de prvenir la boucle main( ) qu'elle devrait arrter
"Beginning to finalize after " +
created + " Chairs have been created"); de fabriquer des objets. On lve ces deux flags dans finalize( ), qui est appel
} pendant l'excution du ramasse-miettes.
if(i == 47) {
System.out.println( Deux autres variables statiques, created and finalized, enregistre le nombre
d'objets Chair crs par rapport au nombre rclam par le ramasse-miettes. Enfin,
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 97/459
chaque objet Chair contient sa propre version (non statique) de l'int i pour savoir Le programme ci-dessus montre que les mthodes de finalisation sont toujours
quel est son numro. Quand l'objet Chair numro 47 est rclam, le flag est mis excutes mais seulement si le programmeur force lui-mme l'appel. Si on ne force
true pour arrter la cration des objets Chair. pas l'appel de System.gc( ), le rsultat ressemblera ceci :
Tout ceci se passe dans le main( ), dans la boucle Created 47
Beginning to finalize after 3486 Chairs have been created
while(!Chair.f) { Finalizing Chair #47, Setting flag to stop Chair creation
new Chair(); After all Chairs have been created:
new String("To take up space"); total created = 3881, total finalized = 2684
} bye!
On peut se demander comment cette boucle va se terminer puisque rien dans la Toutes les mthodes de finalisation ne sont donc pas appeles la fin du
boucle ne change la valeur de Chair.f. Cependant, finalize( ) le fera au moment de programme. Ce n'est que quand System.gc( ) est appel que tous les objets qui ne
la rclamation du numro 47. sont plus utiliss seront finaliss et dtruits.
La cration d'un objet String chaque itration reprsente simplement de l'espace Il est important de se souvenir que ni le ramasse-miettes, ni la finalisation ne sont
mmoire supplmentaire pour inciter le ramasse-miettes s'excuter, ce qu'il fera garantis. Si la machine virtuelle Java (JVM) ne risque pas de manquer de mmoire,
ds qu'il se sentira inquiet pour le montant de mmoire disponible. elle ne perdra (lgitimement) pas de temps en rcuprer grce au ramasse-miettes.
A l'excution du programme, l'utilisateur fournit une option sur la ligne de
commande : gc, finalize, ou all. Le paramtre gc permet l'appel de la La death condition
mthode System.gc( ) (pour forcer l'excution du ramasse-miettes). finalize
permet d'appeler System.runFinalization( ) ce qui, en thorie, fait que tout objet En gnral, on ne peut pas compter sur un appel finalize( ), et il est ncessaire de
non finalis soit finalis. Enfin, all excute les deux mthodes. crer des fonctions spciales de nettoyage et de les appeler explicitement. Il
Le comportement de ce programme et celui de la version de la premire dition de semblerait donc que finalize( ) ne soit utile que pour effectuer des tches de
cet ouvrage montrent que la question du ramasse-miettes et de la finalisation a nettoyage mmoire trs spcifiques dont la plupart des programmeurs n'aura jamais
volu et qu'une grosse part de cette volution s'est passe en coulisse. En fait, il est besoin. Cependant, il existe une trs intressante utilisation de finalize( ) qui ne
possible que le comportement du programme soit tout fait diffrent lorsque vous ncessite pas que son appel soit garanti. Il s'agit de la vrification de la death
lirez ces lignes. condition [29] d'un objet (tat d'un objet sa destruction).
Si System.gc( ) est appel, alors la finalisation concerne tous les objets. Ce n'tait Au moment o un objet n'est plus intressant, c'est dire lorsqu'il est prt tre
pas forcment le cas avec les implmentations prcdentes du JDK bien que la rclam par le ramasse-miettes, cet objet doit tre dans un tat o sa mmoire peut
documentation dise le contraire. De plus, il semble qu'appeler tre libre sans problme. Par exemple, si l'objet reprsente un fichier ouvert, celui-
System.runFinalization( ) n'ait aucun effet. ci doit tre ferm par le programmeur avant que la mmoire prise par l'objet ne soit
rclame. Si certaines parties de cet objet n'ont pas t nettoyes comme il se doit, il
Cependant, on voit que toutes les mthodes de finalisation sont excutes seulement s'agit d'un bogue du programme qui peut tre trs difficile localiser. L'intrt de
dans le cas o System.gc( ) est appel aprs que tous les objets aient t crs et finalize( ) est qu'il est possible de l'utiliser pour dcouvrir cet tat de l'objet, mme
mis l'cart. Si System.gc( ) n'est pas appel, seulement certains objets seront si cette mthode n'est pas toujours appele. Si une des finalisations trouve le bogue,
finaliss. En Java 1.1, la mthode System.runFinalizersOnExit( ) fut introduite alors le problme est dcouvert et c'est ce qui compte vraiment aprs tout.
pour que les programmes puissent excuter toutes les mthodes de finalisation
lorsqu'ils se terminent, mais la conception tait bogue et la mthode a t classe Voici un petit exemple pour montrer comment on peut l'utiliser :
deprecated. C'est un indice supplmentaire qui montre que les concepteurs de Java //: c04:DeathCondition.java
ont eu de nombreux dmls avec le problme du ramasse-miettes et de la // Comment utiliser finalize() pour dtecter les objets
finalisation. Il est esprer que ces questions ont t rgles dans Java 2. qui
// n'ont pas t nettoys correctement.
class Book {
boolean checkedOut = false;
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 98/459
Book(boolean checkOut) { Un exemple serait de considrer le tas en C++ comme une pelouse o chaque objet
checkedOut = checkOut; prend et dlimite son morceau de gazon. Cet espace peut tre abandonn un peu
}
void checkIn() { plus tard et doit tre rutilis. Avec certaines JVMs, le tas de Java est assez
checkedOut = false; diffrent ; il ressemble plus une chane de montage qui avancerait chaque fois
} qu'un objet est allou. Ce qui fait que l'allocation est remarquablement rapide. Le
public void finalize() { pointeur du tas progresse simplement dans l'espace vide, ce qui correspond donc
if(checkedOut) l'allocation sur la pile en C++ (il y a bien sr une petite pnalit supplmentaire
System.out.println("Error: checked out");
} pour le fonctionnement interne mais ce n'est pas comparable la recherche de
} mmoire libre).
public class DeathCondition {
public static void main(String[] args) { On peut remarquer que le tas n'est en fait pas vraiment une chane de montage, et
Book novel = new Book(true); s'il est trait de cette manire, la mmoire finira par avoir un taux de paging
// Nettoyage correct : (utiliser toute la mmoire virtuelle incluant la partie sur disque dur) important (ce
novel.checkIn(); qui reprsente un gros problme de performance) et finira par manquer de
// Perd la rfrence et oublie le nettoyage : mmoire. Le ramasse-miettes apporte la solution en s'interposant et, alors qu'il
new Book(true);
// Force l'excution du ramasse-miettes et de la collecte les miettes (les objets inutilisables), il compacte tous les objets du tas. Ceci
finalisation : reprsente l'action de dplacer le pointeur du tas un peu plus vers le dbut et
System.gc(); donc plus loin du page fault (interruption pour demander au systme
} d'exploitation des pages de mmoire supplmentaire situes dans la partie de la
} ///:~ mmoire virtuelle qui se trouve sur disque dur). Le ramasse-miettes rarrange tout
pour permettre l'utilisation de ce modle d'allocation trs rapide et utilisant une
Ici, la death condition est le fait que tous les objets de type Book doivent tre sorte de tas infini.
rendus (checked in) avant d'tre rcupr par le ramasse-miettes, mais dans la
fonction main( ) une erreur de programmation fait qu'un de ces livres n'est pas Pour comprendre comment tout cela fonctionne, il serait bon de donner maintenant
rendu. Sans finalize( ) pour vrifier la death condition, cela pourrait s'avrer un une meilleure description de la faon dont un ramasse-miettes fonctionne. Nous
bogue difficile trouver. utiliserons l'acronyme GC (en anglais, un ramasse-miette est appel Garbage
Collector) dans les paragraphes suivants. Une technique de GC relativement simple
Il est important de noter l'utilisation de System.gc( ) pour forcer l'excution de la mais lente est le compteur de rfrence. L'ide est que chaque objet contient un
finalisation (en fait, il est utile de le faire pendant le dveloppement du programme compteur de rfrence et chaque fois qu'une nouvelle rfrence sur un objet est
pour acclrer le dbogage). Cependant mme si System.gc() n'est pas appel, il cre le compteur est incrment. A chaque fois qu'une rfrence est hors de porte
est trs probable que le livre (Book) perdu soit dcouvert par plusieurs excutions ou que la valeur null lui est assigne, le compteur de rfrences est dcrment. Par
successives du programme (en supposant que suffisamment de mmoire soit allou consquent, la gestion des compteurs de rfrences reprsente un cot faible mais
pour que le ramasse-miettes se dclenche). constant tout au long du programme. Le ramasse-miettes se dplace travers toute
la liste d'objets et quand il en trouve un avec un compteur zro, il libre la
Comment fonctionne un ramasse-miettes ? mmoire. L'inconvnient principal est que si des objets se rfrencent de faon
circulaire, ils ne peuvent jamais avoir un compteur zro tout en tant inaccessible.
Pour localiser ces objets qui se rfrencent mutuellement, le ramasse-miettes doit
Les utilisateurs de langages o l'allocation d'objets sur le tas cote cher peuvent faire un important travail supplmentaire. Les compteurs de rfrences sont
supposer que la faon qu'a Java de tout allouer sur le tas ( l'exception des types de gnralement utiliss pour expliquer les ramasses-miettes mais ils ne semblent pas
base) cote galement cher. Cependant, il se trouve que l'utilisation d'un ramasse- tre utiliss dans les implmentations de la JVM.
miettes peut acclrer de manire importante la cration d'objets. Ceci peut sembler
un peu bizarre premire vue : la rclamation d'objets aurait un effet sur la cration D'autres techniques, plus performantes, n'utilisent pas de compteur de rfrences.
d'objets. Mais c'est comme a que certaines JVMs fonctionnent et cela veut dire, Elles sont plutt bases sur l'ide que l'on est capable de remonter la chane de
qu'en Java, l'allocation d'objets sur le tas peut tre presque aussi rapide que rfrences de tout objet non-mort (i.e encore en utilisation) jusqu' une rfrence
l'allocation sur la pile dans d'autres langages. vivant sur la pile ou dans la zone statique. Cette chane peut trs bien passer par
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 99/459
plusieurs niveaux d'objets. Par consquent, si l'on part de la pile et de la zone marqu avec un flag, mais rien n'est encore collect. C'est seulement lorsque la
statique et que l'on trace toutes les rfrences, on trouvera tous les objets encore en phase de mark est termine que le sweep commence. Pendant ce balayage, les
utilisation. Pour chaque rfrence que l'on trouve, il faut aller jusqu' l'objet objets morts sont librs. Aucune copie n'est effectue, donc si le ramasse-miettes
rfrenc et ensuite suivre toutes les rfrences contenues dans cet objet, aller dcide de compacter la mmoire, il le fait en rarrangeant les objets.
jusqu'aux objets rfrencs, etc. jusqu' ce que l'on ait visit tous les objets que l'on
Le stop-and-copy correspond l'ide que ce type de ramasse-miettes ne s'excute
peut atteindre depuis la rfrence sur la pile ou dans la zone statique. Chaque objet
pas en tche de fond, le programme est en fait arrt pendant l'excution du
visit doit tre encore vivant. Notez qu'il n'y a aucun problme avec les groupes qui
ramasse-miettes. La littrature de Sun mentionne assez souvent le ramasse-miettes
s'auto-rfrencent : ils ne sont tout simplement pas trouvs et sont donc
comme une tche de fond de basse priorit, mais il se trouve que le ramasse-miettes
automatiquement morts.
n'a pas t implment de cette manire, tout au moins dans les premires versions
Avec cette approche, la JVM utilise un ramasse-miettes adaptatif. Le sort des objets de la JVM de Sun. Le ramasse-miettes tait plutt excut quand il restait peu de
vivants trouvs dpend de la variante du ramasse-miettes utilise ce moment-l. mmoire libre. De plus, le mark-and-sweep ncessite l'arrt du programme.
Une de ces variantes est le stop-and-copy. L'ide est d'arrter le programme dans un
Comme il a t dit prcdemment, la JVM dcrite ici alloue la mmoire par blocs. Si
premier temps (ce n'est pas un ramasse-miettes qui s'excute en arrire-plan). Puis,
un gros objet est allou, un bloc complet lui est rserv. Le stop-and-copy
chaque objet vivant que l'on trouve est copi d'un tas un autre, dlaissant les objets
strictement appliqu ncessite la copie de chaque objet vivant du tas d'origine vers
morts. De plus, au moment o les objets sont copis, ils sont rassembls les uns
un nouveau tas avant de pouvoir librer le vieux tas, ce qui se traduit par la
ct des autres, compactant de ce fait le nouveau tas (et permettant d'allouer de la
manipulation de beaucoup de mmoire. Avec des blocs, le ramasse-miettes peut
mmoire en la rcuprant l'extrmit du tas comme cela a t expliqu
simplement utiliser les blocs vides (et/ou contenant uniquement des objets morts)
auparavant).
pour y copier les objets. Chaque bloc possde un compteur de gnration pour
Bien entendu, quand un objet est dplac d'un endroit un autre, toutes les savoir s'il est mort (vide) ou non. Dans le cas normal, seuls les blocs crs depuis
rfrences qui pointent (i.e. qui rfrencent) l'objet doivent tre mis jour. La le ramasse-miettes sont compacts ; les compteurs de gnrations de tous les autres
rfrence qui part du tas ou de la zone statique vers l'objet peut tre modifie sur le blocs sont mis jour s'ils ont t rfrencs. Cela prend en compte le cas courant des
champ, mais il y a d'autres rfrences pointant sur cet objet qui seront trouves sur nombreux objets ayant une dure de vie trs courte. Rgulirement, un balayage
le chemin. Elles seront corriges ds qu'elles seront trouves (on peut s'imaginer complet est effectu, les gros objets ne sont toujours pas copis (leurs compteurs de
une table associant les anciennes adresses aux nouvelles). gnration sont simplement mis jour) et les blocs contenant des petits objets sont
copis et compacts. La JVM value constamment l'efficacit du ramasse-miettes et
Il existe deux problmes qui rendent ces ramasse-miettes par copie inefficaces. Le
si cette technique devient une pnalit plutt qu'un avantage, elle la change pour un
premier est l'utilisation de deux tas et le dplacement des objets d'un tas l'autre,
mark-and-sweep . De mme, la JVM value l'efficacit du mark-and-sweep et si
utilisant ainsi deux fois plus de mmoire que ncessaire. Certaines JVMs s'en
le tas se fragmente, le stop-and-copy est rutilis. C'est l o l' adaptation vient
sortent en allouant la mmoire par morceau et en copiant simplement les objets
en place et finalement on peut utiliser ce terme anglophone rallonge : adaptive
d'un morceau un autre.
generational stop-and-copy mark-and-sweep qui correspondrait adaptatif
Le deuxime problme est la copie. Une fois que le programme atteint un tat stable, entre marque-et-balaye et stoppe-et-copie de faon gnrationnelle .
il se peut qu'il ne gnre pratiquement plus de miettes (i.e. d'objets morts). Malgr
#/TIJ_PAGE03# #TIJ_PAGE04#
a, le ramasse-miettes par copie va quand mme copier toute la mmoire d'une zone
une autre, ce qui est du gaspillage put et simple. Pour viter cela, certaines JVMs Il existe un certain nombre d'autres optimisations possibles dans une JVM. Une
dtectent que peu d'objets meurent et choisissent alors une autre technique (c'est la d'entre elles, trs importante, implique le module de chargement des classes et le
partie d'adaptation). Cette autre technique est appele mark and sweep (NDT : compilateur Just-In-Time (JIT). Quand une classe doit tre charge (gnralement
litralement marque et balaye), et c'est ce que les versions prcdentes de la JVM la premire fois que l'on veut crer un objet de cette classe), le fichier .class est
de Sun utilisaient en permanence. En gnral, le mark and sweep est assez lent, trouv et le byte-code pour cette classe est charg en mmoire. A ce moment-l, une
mais quand on sait que l'on gnre peu ou pas de miettes, la technique est rapide. possibilit est d'utiliser le JIT sur tout le code, mais cela a deux inconvnients. Tout
d'abord c'est un peu plus coteux en temps et, quand on considre toutes les classes
La technique de mark and sweep suit la mme logique de partir de la pile et de la
charges sur la dure de vie du programme, cela peut devenir consquent. De plus,
zone de mmoire statique et de suivre toutes les rfrences pour trouver les objets
la taille de l'excutable est augmente (les byte codes sont bien plus compacts que le
encore en utilisation. Cependant, chaque fois qu'un objet vivant est trouv, il est
code rsultant du JIT) et peut donc causer l'utilisation de pages dans la mmoire
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 100/459
virtuelle, ce qui ralentit clairement le programme. Une autre approche est "int" + i + "\n" +
l'valuation paresseuse qui n'utilise le JIT que lorsque cela est ncessaire. Par "long " + l + "\n" +
"float" + f + "\n" +
consquent, si une partie du code n'est jamais excute, il est possible qu'elle ne soit "double " + d);
jamais compile par le JIT. }
}
Initialisation de membre
public class InitialValues {
public static void main(String[] args) {
Measurement d = new Measurement();
d.print();
Java prend en charge l'initialisation des variables avant leur utilisation. Dans le cas /* Dans ce cas, il est galement possible d'crire :
des variables locales une mthode, cett garantie prend la forme d'une erreur la new Measurement().print();
compilation. Donc le code suivant : */
}
void f() { } ///:~
int i;
i++;
} Voici la sortie de ce programme :
Data typeInitial value
gnrera un message d'erreur disant que la variable i peut ne pas avoir t booleanfalse
char [ ] 0
initialise. Bien entendu, le compilateur aurait pu donner i une valeur par dfaut, byte 0
mais il est plus probable qu'il s'agit d'une erreur de programmation et une valeur short0
par dfaut aurait masqu ce problme. En forant le programmeur donner une int0
valeur par dfaut, il y a plus de chances de reprer un bogue. long 0
float0.0
Cependant, si une valeur primitive est un membre de donnes d'une classe, les double 0.0
choses sont un peu diffrentes. Comme n'importe quelle mthode peut initialiser ou
utiliser cette donne, il ne serait pas trs pratique ou faisable de forcer l'utilisateur La valeur pour char est zro, ce qui se traduit par un espace dans la sortie-cran.
l'initialiser correctement avant son utilisation. Cependant, il n'est pas correct de la
laisser avec n'importe quoi comme valeur, Java garantit donc de donner une valeur Nous verrons plus tard que quand on dfinit une rfrence sur un objet dans une
initiale chaque membre de donnes avec un type primitif. On peut voir ces valeurs classe sans l'initialiser avec un nouvel objet, la valeur spciale null (mot-cl Java)
ici : est donne cette rfrence.
//: c04:InitialValues.java On peut voir que mme si des valeurs ne sont pas spcifies, les donnes sont
// Imprime les valeurs initiales par dfaut. initialises automatiquement. Il n'y a donc pas de risque de travailler par inattention
class Measurement { avec des variables non-initialises.
boolean t;
char c;
byte b;
short s;
Spcifier une initialisation
int i;
long l; Comment peut-on donner une valeur initiale une variable ? Une manire directe
float f; de le faire est la simple affectation au moment de la dfinition de la variable dans la
double d; classe (note : il n'est pas possible de le faire en C++ bien que tous les dbutants s'y
void print() {
System.out.println( essayent). Les dfinitions des champs de la classe Measurement sont modifies ici
"Data typeInitial value\n" + pour fournir des valeurs initiales :
"boolean" + t + "\n" + class Measurement {
"char [" + c + "] "+ (int)c +"\n"+ boolean b = true;
"byte " + b + "\n" + char c = 'x';
"short" + s + "\n" +
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 101/459
byte B = 47; limite dans le sens o chaque objet de type Measurement aura les mmes valeurs
short s = 0xff; d'initialisation. Quelquefois c'est exactement ce dont on a besoin, mais d'autres fois
int i = 999;
long l = 1; un peu plus de flexibilit serait ncessaire.
float f = 3.14f;
double d = 3.14159;
//. . . Initialisation par constructeur
On peut initialiser des objets de type non-primitif de la mme manire. Si Depth On peut utiliser le constructeur pour effectuer les initialisations. Cela apporte plus
(NDT : profondeur ) est une classe, on peut ajouter une variable et l'initialiser de de flexibilit pour le programmeur car il est possible d'appeler des mthodes et
cette faon : effectuer des actions l'excution pour dterminer les valeurs initiales. Cependant il
y a une chose se rappeler : cela ne remplace pas l'initialisation automatique qui est
class Measurement { faite avant l'excution du constructeur. Donc par exemple :
Depth o = new Depth();
boolean b = true; class Counter {
// . . . int i;
Counter() { i = 7; }
// . . .
Si o ne reoit pas de valeur initiale et que l'on essaye de l'utiliser malgr tout, on
obtient une erreur l'excution appele exception (explications au chapitre 10).
Dans ce cas, i sera d'abord initialis 0 puis 7. C'est ce qui ce passe pour tous les
Il est mme possible d'appeler une mthode pour fournir une valeur d'initialisation : types primitifs et les rfrences sur objet, mme pour ceux qui ont t initialiss
class CInit { explicitement au moment de leur dfinition. Pour cette raison, le compilateur ne
int i = f(); force pas l'utilisateur initialiser les lments dans le constructeur un endroit
//... donn, ni avant leur utilisation : l'initialisation est toujours garantie [30].
}
Ordre d'initialisation
Bien sr cette mthode peut avoir des arguments, mais ceux-ci ne peuvent pas tre
d'autres membres non encore initialiss, de la classe. Par consquent ce code est
valide : Dans une classe, l'ordre d'initialisation est dtermin par l'ordre dans lequel les
variables sont definies. Les dfinitions de variables peuvent tre dissmines
class CInit { n'importe o et mme entre les dfinitions des mthodes, mais elles sont initialises
int i = f();
int j = g(i);
avant tout appel une mthode, mme le constructeur. Par exemple :
//... //: c04:OrderOfInitialization.java
} // Montre l'ordre d'initialisation.
// Quand le constructeur est appel pour crer
// un objet Tag, un message s'affichera :
Mais pas celui-ci : class Tag {
class CInit { Tag(int marker) {
int j = g(i); System.out.println("Tag(" + marker + ")");
int i = f(); }
//... }
} class Card {
Tag t1 = new Tag(1); // Avant le constructeur
Card() {
C'est un des endroits o le compilateur se plaint avec raison du forward referencing // Montre que l'on est dans le constructeur :
(rfrence un objet dclar plus loin dans le code), car il s'agit d'une question System.out.println("Card()");
d'ordre d'initialisation et non pas de la faon dont le programme est compil. t3 = new Tag(33); // Rinitialisation de t3
}
Cette approche par rapport l'initialisation est trs simple. Elle est galement Tag t2 = new Tag(2); // Aprs le constructeur
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 102/459
void f() { class Bowl {
System.out.println("f()"); Bowl(int marker) {
} System.out.println("Bowl(" + marker + ")");
Tag t3 = new Tag(3); // la fin }
} void f(int marker) {
public class OrderOfInitialization { System.out.println("f(" + marker + ")");
public static void main(String[] args) { }
Card t = new Card(); }
t.f(); // Montre que la construction a t effectue class Table {
} static Bowl b1 = new Bowl(1);
} ///:~ Table() {
System.out.println("Table()");
b2.f(1);
Dans la classe Card, les dfinitions des objets Tag sont intentionnellement }
disperses pour prouver que ces objets seront tous initialiss avant toute action (y void f2(int marker) {
compris l'appel du constructeur). De plus, t3 est rinitialis dans le constructeur. La System.out.println("f2(" + marker + ")");
sortie-cran est la suivante : }
static Bowl b2 = new Bowl(2);
Tag(1) }
Tag(2) class Cupboard {
Tag(3) Bowl b3 = new Bowl(3);
Card() static Bowl b4 = new Bowl(4);
Tag(33) Cupboard() {
f() System.out.println("Cupboard()");
b4.f(2);
}
La rfrence sur t3 est donc initialise deux fois, une fois avant et une fois pendant void f3(int marker) {
l'appel au constructeur (on jette le premier objet pour qu'il soit rcupr par le System.out.println("f3(" + marker + ")");
ramasse-miettes plus tard). A premire vue, cela ne semble pas trs efficace, mais }
cela garantit une initialisation correcte ; que se passerait-il si l'on surchargeait le static Bowl b5 = new Bowl(5);
constructeur avec un autre constructeur qui n'initialiserait pas t3 et qu'il n'y avait }
public class StaticInitialization {
pas d'initialisation par dfaut dans la dfinition de t3 ? public static void main(String[] args) {
System.out.println(
Initialisation de donnes statiques "Creating new Cupboard() in main");
new Cupboard();
System.out.println(
Quand les donnes sont statiques (static) la mme chose se passe ; s'il s'agit d'une "Creating new Cupboard() in main");
donne de type primitif et qu'elle n'est pas initialise, la variable reoit une valeur new Cupboard();
initiale standard. Si c'est une rfrence sur un objet, c'est la valeur null qui est t2.f2(1);
t3.f3(1);
utilise moins qu'un nouvel objet ne soit cr et sa rfrence donne comme valeur }
la variable. static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
Pour une initialisation l'endroit de la dfinition, les mmes rgles que pour les } ///:~
variables non-statiques sont appliques. Il n'y a qu'une seule version (une seule zone
mmoire) pour une variable statique quel que soit le nombre d'objets crs. Mais
une question se pose lorsque cette zone statique est initialise. Un exemple va Bowl permet de visionner la cration d'une classe. Table, ainsi que Cupboard,
crent des membres static de Bowl partout au travers de leur dfinition de classe.
rendre cette question claire :
Il est noter que Cupboard cre un Bowl b3 non-statique avant les dfinitions
//: c04:StaticInitialization.java statiques. La sortie montre ce qui se passe :
// Prciser des valeurs initiales dans une
// dfinition de classe. Bowl(1)
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 103/459
Bowl(2) excute ;
Table() 6. Les constructeurs sont excuts. Comme nous le verrons au chapitre 6, ceci
f(1)
Bowl(4) peut en fait dclencher beaucoup d'activit, surtout lorsqu'il y a de
Bowl(5) l'hritage.
Bowl(3)
Cupboard()
f(2) Initialisation statique explicite
Creating new Cupboard() in main
Bowl(3) Java permet au programmeur de grouper toute autre initialisation statique dans une
Cupboard() clause de construction static (quelquefois appel bloc statique) dans une classe.
f(2)
Creating new Cupboard() in main Cela ressemble ceci :
Bowl(3) class Spoon {
Cupboard() static int i;
f(2) static {
f2(1) i = 47;
f3(1) }
// . . .
L'initialisation statique intervient seulement si c'est ncessaire. Si on ne cre
jamais d'objets Table et que Table.b1 ou Table.b2 ne sont jamais rfrencs, les On dirait une mthode, mais il s'agit simplement du mot-cl static suivi d'un corps
membres statiques Bowl b1 et b2 ne seront jamais crs. Cependant, ils ne sont de mthode. Ce code, comme les autres initialisations statiques, est excut une
initialiss que lorsque le premier objet Table est cr (ou le premier accs statique seule fois, la cration du premier objet de cette classe ou au premier accs un
est effectu). Aprs cela, les objets statiques ne sont pas rinitialiss. membre dclar static de cette classe (mme si on ne cre jamais d'objet de cette
classe). Par exemple :
Dans l'ordre d'initialisation, les membres static viennent en premier, s'ils n'avaient
pas dj t initialiss par une prcdente cration d'objet, les objets non static sont //: c04:ExplicitStatic.java
traits. On peut le voir clairement dans la sortie du programme. // Initialisation statique explicite
// avec l'instruction "static".
Il peut tre utile de rsumer le processus de cration d'un objet. Considrons une class Cup {
classe appele Dog : Cup(int marker) {
System.out.println("Cup(" + marker + ")");
1. La premire fois qu'un objet de type Dog est cr, ou la premire fois qu'on }
utilise une mthode dclare static ou un champ static de la classe Dog, void f(int marker) {
System.out.println("f(" + marker + ")");
l'interprteur Java doit localiser Dog.class, ce qu'il fait en cherchant dans }
le classpath ; }
2. Au moment o Dog.class est charge (crant un objet Class, que nous class Cups {
verrons plus tard), toutes les fonctions d'initialisation statiques sont static Cup c1;
excutes. Par consquent, l'initialisation statique n'arrive qu'une fois, au static Cup c2;
static {
premier chargement de l'objet Class ; c1 = new Cup(1);
3. Lorsque l'on excute new Dog( ) pour crer un nouvel objet de type Dog, c2 = new Cup(2);
le processus de construction commence par allouer suffisamment d'espace }
mmoire sur le tas pour contenir un objet Dog ; Cups() {
4. Cet espace est mis zro, donnant automatiquement tous les membres de System.out.println("Cups()");
}
type primitif dans cet objet Dog leurs valeurs par dfaut (zro pour les }
nombres et l'quivalent pour les boolean et les char) et aux rfrences la public class ExplicitStatic {
valeur null ; public static void main(String[] args) {
5. Toute initialisation effectue au moment de la dfinition des champs est System.out.println("Inside main()");
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 104/459
Cups.c1.f(99);// (1) {
} c1 = new Mug(1);
// static Cups x = new Cups();// (2) c2 = new Mug(2);
// static Cups y = new Cups();// (2) System.out.println("c1 & c2 initialized");
} ///:~ }
Les instructions statiques d'initialisation pour Cups sont excutes soit quand ressemble exactement la clause d'initialisation statique moins le mot-cl static.
l'accs l'objet static c1 intervient la ligne (1), soit si la ligne (1) est mise en Cette syntaxe est ncessaire pour permettre l'initialisation de classes internes
commentaire et les lignes (2) ne le sont pas. Si (1) et (2) sont en commentaire, anonymes (voir Chapitre 8).
l'initialisation static pour Cups n'intervient jamais. De plus, que l'on enlve les
commentaires pour les deux lignes (2) ou pour une seule n'a aucune importance :
l'initialisation statique n'est effectue qu'une seule fois. Initialisation des tableaux
Initialisation d'instance non statique L'initialisation des tableaux en C est laborieuse et source d'erreurs. C++ utilise
l'initialisation d'aggregats pour rendre cette opration plus sre [31]. Java n'a pas
Java offre une syntaxe similaire pour initialiser les variables non static pour chaque d' aggregats comme C++, puisque tout est objet en Java. Java possde pourtant
objet. Voici un exemple : des tableaux avec initialisation.
//: c04:Mugs.java Un tableau est simplement une suite d'objets ou de types de base, tous du mme
// Java "Instance Initialization." (Initialisation type et runis ensemble sous un mme nom. Les tableaux sont dfinis et utiliss
d'instance de Java) avec l'oprateur d'indexation [ ] (crochets ouvrant et fermant). Pour dfinir un
class Mug { tableau il suffit d'ajouter des crochets vides aprs le nom du type :
Mug(int marker) {
System.out.println("Mug(" + marker + ")"); int[] a1;
}
void f(int marker) {
System.out.println("f(" + marker + ")"); Les crochets peuvent galement tre plac aprs le nom de la variable :
} int a1[];
}
public class Mugs {
Mug c1; Cela correspond aux attentes des programmeurs C et C++. Toutefois, la premire
Mug c2; syntaxe est probablement plus sense car elle annonce le type comme un tableau
{ de int. Ce livre utilise cette syntaxe.
c1 = new Mug(1);
c2 = new Mug(2); Le compilateur ne permet pas de spcifier la taille du tableau sa dfinition. Cela
System.out.println("c1 & c2 initialized"); nous ramne ce problme de rfrence. A ce point on ne dispose que d'une
}
Mugs() { rfrence sur un tableau, et aucune place n'a t alloue pour ce tableau. Pour crer
System.out.println("Mugs()"); cet espace de stockage pour le tableau, il faut crire une expression d'initialisation.
} Pour les tableaux, l'initialisation peut apparatre tout moment dans le code, mais
public static void main(String[] args) { on peut galement utiliser un type spcial d'initialisation qui doit alors apparatre
System.out.println("Inside main()"); la dclaration du tableau. Cette initalisation spciale est un ensemble de valeurs
Mugs x = new Mugs();
} entre accolades. L'allocation de l'espace de stockage pour le tableau (l'quivalent de
} ///:~ new) est prise en charge par le compilateur dans ce cas. Par exemple :
int[] a1 = { 1, 2, 3, 4, 5 };
#/TIJ_PAGE04# #TIJ_PAGE05#
On peut voir que la clause d'initialisation d'instance : Mais pourquoi voudrait-on dfinir une rfrence sur tableau sans tableau ?
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 105/459
int[] a2; //: c04:ArrayNew.java
// Crer des tableaux avec new.
import java.util.*;
Il est possible d'affecter un tableau un autre en Java, on peut donc crire : public class ArrayNew {
a2 = a1; static Random rand = new Random();
static int pRand(int mod) {
return Math.abs(rand.nextInt()) % mod + 1;
Cette expression effectue en fait une copie de rfrence, comme le montre la suite : }
public static void main(String[] args) {
//: c04:Arrays.java int[] a;
// Tableau de types primitifs. a = new int[pRand(20)];
public class Arrays { System.out.println(
public static void main(String[] args) { "length of a = " + a.length);
int[] a1 = { 1, 2, 3, 4, 5 }; for(int i = 0; i < a.length; i++)
int[] a2; System.out.println(
a2 = a1; "a[" + i + "] = " + a[i]);
for(int i = 0; i < a2.length; i++) }
a2[i]++; } ///:~
for(int i = 0; i < a1.length; i++)
System.out.println(
"a1[" + i + "] = " + a1[i]); Comme la taille du tableau est choisie alatoirement (en utilisant la mthode
} pRand( )), il est clair que la cration du tableau se passe effectivement
} ///:~
l'excution. De plus, on peut voir en excutant le programme que les tableaux de
types primitifs sont automatiquement initialiss avec des valeurs vides (pour les
On peut voir que a1 a une valeur initiale tandis qu' a2 n'en a pas ; a2 prend une nombres et les char, cette valeur est zro, pour les boolean, cette valeur est false).
valeur plus tard dans ce cas, vers un autre tableau.
Bien sr le tableau pourrait aussi avoir t dfini et initialis sur la mme ligne :
Maintenant voyons quelque chose de nouveau : tous les tableaux ont un membre
int[] a = new int[pRand(20)];
intrinsque (qu'ils soient tableaux d'objets ou de types de base) que l'on peut
interroger mais pas changer ; il donne le nombre d'lments dans le tableau. Ce
membre s'appelle length (longueur). Comme les tableaux en Java , comme C et Lorsque l'on travaille avec un tableau d'objets non primitifs, il faut toujours utiliser
C++, commencent la case zero, le plus grand nombre d'lments que l'on peut new. Encore une fois, le problme des rfrences revient car ce que l'on cre est un
indexer est length - 1. Lorsqu'on dpasse ces bornes, C et C++ acceptent cela tableau de rfrences. Considrons le type englobant Integer, qui est une classe et
tranquillement et la mmoire peut tre corrompue ; ceci est la cause de bogues non un type de base :
infmes. Par contre, Java empche ce genre de problmes en gnrant une erreur //: c04:ArrayClassObj.java
d'excution (une exception, le sujet du Chapitre 10) lorsque le programme essaye // Cration d'un tableau d'objets (types de base exclus).
d'accder une valeur en dehors des limites. Bien sr, vrifier ainsi chaque accs import java.util.*;
public class ArrayClassObj {
cote du temps et du code ; comme il n'y a aucun moyen de dsactiver ces static Random rand = new Random();
vrifications, les accs tableaux peuvent tre une source de lenteur dans un static int pRand(int mod) {
programme s'ils sont placs certains points critiques de l'excution. Les return Math.abs(rand.nextInt()) % mod + 1;
concepteurs de Java ont pens que cette vitesse lgrement rduite tait largement }
contrebalance par les aspects de scurit sur Internet et la meilleure productivit public static void main(String[] args) {
Integer[] a = new Integer[pRand(20)];
des programmeurs. System.out.println(
Que faire quand on ne sait pas au moment o le programme est crit, combien "length of a = " + a.length);
for(int i = 0; i < a.length; i++) {
d'lments vont tre requis l'excution ? Il suffit d'utiliser new pour crer les a[i] = new Integer(pRand(500));
lments du tableau. Dans ce cas, new fonctionne mme pour la cration d'un System.out.println(
tableau de types de base (new ne peut pas crer un type de base) : "a[" + i + "] = " + a[i]);
}
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 106/459
} au long du livre), on peut crer une mthode qui prend un tableau d'Object et
} ///:~ l'appeler ainsi :
//: c04:VarArgs.java
Ici, mme aps que new ait t appel pour crer le tableau : // Utilisation de la syntaxe des tableaux pour crer
Integer[] a = new Integer[pRand(20)]; // des listes nombre d'argument variable.
class A { int i; }
public class VarArgs {
c'est uniquement un tableau de rfrences, et l'initialisation n'est pas complte tant static void f(Object[] x) {
que cette rfrence n'a pas elle-mme t initialise en creant un nouvel objet for(int i = 0; i < x.length; i++)
Integer : System.out.println(x[i]);
}
a[i] = new Integer(pRand(500)); public static void main(String[] args) {
f(new Object[] {
new Integer(47), new VarArgs(),
Oublier de crer l'objet produira une exception d'excution ds que l'on accdera new Float(3.14), new Double(11.11) });
l'emplacement. f(new Object[] {"one", "two", "three" });
f(new Object[] {new A(), new A(), new A()});
Regardons la formation de l'objet String l'intrieur de print. On peut voir que la }
rfrence vers l'objet Integer est automatiquement convertie pour produire une } ///:~
String reprsentant la valeur l'intrieur de l'objet.
Il est galement possible d'initialiser des tableaux d'objets en utilisant la liste A ce niveau, il n'y a pas grand chose que l'on peut faire avec ces objets inconnus, et
dlimite par des accolades. Il y a deux formes : ce programme utilise la conversion automatique vers String afin de faire quelque
chose d'utile avec chacun de ces Objects. Au chapitre 12, qui explique
//: c04:ArrayInit.java
// Initialisation de tableaux. l'identification dynamique de types (RTTI), nous verrons comment dcouvrir le
public class ArrayInit { type exact de tels objets afin de les utiliser des fins plus intressantes.
public static void main(String[] args) {
Tableaux multidimensionels
Integer[] a = {
new Integer(1),
new Integer(2),
new Integer(3),
};
Java permet de crer facilement des tableaux multidimensionnels :
Integer[] b = new Integer[] { //: c04:MultiDimArray.java
new Integer(1), // Cration de tableaux multidimensionnels.
new Integer(2), import java.util.*;
new Integer(3), public class MultiDimArray {
}; static Random rand = new Random();
} static int pRand(int mod) {
} ///:~ return Math.abs(rand.nextInt()) % mod + 1;
}
static void prt(String s) {
C'est parfois utile, mais d'un usage plus limit car la taille du tableau est dtermine System.out.println(s);
la compilation. La virgule finale dans la liste est optionnelle. (Cette fonctionnalit }
permet une gestion plus facile des listes longues.) public static void main(String[] args) {
int[][] a1 = {
La deuxime forme d'initialisation de tableaux offre une syntaxe pratique pour crer { 1, 2, 3, },
et appeler des mthodes qui permet de donner le mme effet que les listes nombre { 4, 5, 6, },
d'arguments variable de C ( varargs en C). Ces dernires permettent le passage };
d'un nombre quelconque de paramtres, chacun de type inconnu. Comme toutes les for(int i = 0; i < a1.length; i++)
for(int j = 0; j < a1[i].length; j++)
classes hritent d'une classe racine Object (un sujet qui sera couvert en dtail tout prt("a1[" + i + "][" + j +
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 107/459
"] = " + a1[i][j]); vecteur du tableau est dlimit par des accolades :
// tableau 3-D avec taille fixe :
int[][][] a2 = new int[2][2][4]; int[][] a1 = {
for(int i = 0; i < a2.length; i++) { 1, 2, 3, },
for(int j = 0; j < a2[i].length; j++) { 4, 5, 6, },
for(int k = 0; k < a2[i][j].length; };
k++)
prt("a2[" + i + "][" +
j + "][" + k +
Chaque paire de crochets donne accs la dimension suivante du tableau.
"] = " + a2[i][j][k]); Le deuxime exemple montre un tableau trois dimensions allou par new. Ici le
// tableau 3-D avec vecteurs de taille variable :
int[][][] a3 = new int[pRand(7)][][]; tableau entier est allou en une seule fois :
for(int i = 0; i < a3.length; i++) { int[][][] a2 = new int[2][2][4];
a3[i] = new int[pRand(5)][];
for(int j = 0; j < a3[i].length; j++)
a3[i][j] = new int[pRand(5)]; Par contre, le troisime exemple montre que les vecteurs dans les tableaux qui
} forment la matrice peuvent tre de longueurs diffrentes :
for(int i = 0; i < a3.length; i++)
for(int j = 0; j < a3[i].length; j++) int[][][] a3 = new int[pRand(7)][][];
for(int k = 0; k < a3[i][j].length; for(int i = 0; i < a3.length; i++) {
k++) a3[i] = new int[pRand(5)][];
prt("a3[" + i + "][" + for(int j = 0; j < a3[i].length; j++)
j + "][" + k + a3[i][j] = new int[pRand(5)];
"] = " + a3[i][j][k]); }
// Tableau d'objets non primitifs :
Integer[][] a4 = { Le premier new cre un tableau avec un longueur alatoire pour le premier lment
{ new Integer(1), new Integer(2)},
{ new Integer(3), new Integer(4)},
et le reste de longeur indtermine. Le deuxime new l'intrieur de la boucle for
{ new Integer(5), new Integer(6)}, remplit les lments mais laisse le troisime index indtermin jusqu'au troisime
}; new.
for(int i = 0; i < a4.length; i++)
for(int j = 0; j < a4[i].length; j++) On peut voir l'excution que les valeurs des tableaux sont automatiquement
prt("a4[" + i + "][" + j + initialises zro si on ne leur donne pas explicitement de valeur initiale.
"] = " + a4[i][j]);
Integer[][] a5; Les tableaux d'objets non primitifs fonctionnent exactement de la mme manire,
a5 = new Integer[3][]; comme le montre le quatrime exemple, qui prsente la possibilit d'utiliser new
for(int i = 0; i < a5.length; i++) { dans les accolades d'initialisation :
a5[i] = new Integer[3];
for(int j = 0; j < a5[i].length; j++) Integer[][] a4 = {
a5[i][j] = new Integer(i*j); { new Integer(1), new Integer(2)},
} { new Integer(3), new Integer(4)},
for(int i = 0; i < a5.length; i++) { new Integer(5), new Integer(6)},
for(int j = 0; j < a5[i].length; j++) };
prt("a5[" + i + "][" + j +
"] = " + a5[i][j]); Le cinquime exemple montre comment un tableau d'objets non primitifs peut tre
}
} ///:~ construit pice par pice :
Integer[][] a5;
Le code d'affichage utilise length ; de cette faon il ne force pas une taille de tableau a5 = new Integer[3][];
for(int i = 0; i < a5.length; i++) {
fixe. a5[i] = new Integer[3];
Le premier exemple montre un tableau multidimensionnel de type primitifs. Chaque for(int j = 0; j < a5[i].length; j++)
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 108/459
a5[i][j] = new Integer(i*j); lectronique The Thinking in Java Annotated Solution Guide, disponible pour une
} modeste somme l'adresse www.BruceEckel.com.
L'expression i*j est l uniquement pour donner une valeur intressante l' Integer. 1. Crez une classe avec un constructeur par dfaut (c'est dire sans
argument) qui imprime un message. Crez un objet de cette classe.
2. Ajoutez la classe de l'exercice 1 un constructeur surcharg qui prend une
Rsum String en argument et qui l'imprime avec votre message.
3. Crez un tableau de rfrences sur des objets de la classe que vous avez
cre l'exercice 2. Mais ne crez pas les objets eux-mme. Quand le
Le mcanisme apparemment sophistiqu d'initialisation que l'on appelle
programme s'excute, voyez si les messages d'initialisation du constructeur
constructeur souligne l'importance donne l'initialisation dans ce langage. Quand
sont imprims.
Stroustrup tait en train de crer C++, une des premires observations qu'il fit
4. Terminez l'exercice 3 en creant les objets pour remplir le tableau de
propos de la productivit en C tait qu'une initialisation inapproprie des variables
rfrences.
cause de nombreux problmes de programmation. Ce genre de bogues est difficile
5. Crez un tableau d'objets String et affectez une chane de caractres
trouver. Des problmes similaires se retrouvent avec un mauvais nettoyage. Parce
chaque lment. Imprimez le tableau en utilisant une boucle for.
que les constructeurs permettent de garantir une initialisation et un nettoyage
6. Crez une classe Dog avec une mthode bark( ) (NDT: to bark = aboyer)
correct (le compilateur n'autorisera pas la cration d'un objet sans un appel valide
surcharge. Cette mthode sera surcharge en utilisant divers types primitifs
du constructeur), le programmeur a un contrle complet en toute scurit.
de donnes et devra imprimer diffrent types d'aboiement, hurlement, ...
En C++, la destruction est importante parce que les objets crs avec new doivent suivant la version surcharge qui est appele. Ecrivez galement une
tre dtruits explicitement .En Java, le ramasse-miettes libre automatiquement la mthode main( ) qui appellera toutes les versions.
mmoire pour tous les objets, donc la mthode de nettoyage quivalente en Java 7. Modifiez l'exercice 6 pour que deux des mthodes surcharges aient deux
n'est pratiquement jamais ncessaire. Dans les cas o un comportement du style paramtres (de deux types diffrents), mais dans l'ordre inverse l'une par
destructeur n'est pas ncessaire, le ramasse-miettes de Java simplifie grandement la rapport l'autre. Vrifiez que cela fonctionne.
programmation et ajoute une scurit bien ncessaire la gestion mmoire. Certains 8. Crez une classe sans constructeur et crez ensuite un objet de cette classe
ramasse-miettes peuvent mme s'occuper du nettoyage d'autres ressources telles dans main( ) pour vrifier que le constructeur par dfaut est construit
que les graphiques et les fichiers. Cependant, le prix du ramasse-miettes est pay par automatiquement.
une augmentation du temps d'excution, qu'il est toutefois difficile d'valuer cause 9. Crez une classe avec deux mthodes. Dans la premire mthode, appelez la
de la lenteur globale des interprteurs Java au moment de l'criture de cet ouvrage. seconde mthode deux fois : la premire fois sans utiliser this et la seconde
Lorsque cela changera, il sera possible de savoir si le cot du ramasse-miettes fois en l'utilisant.
posera des barrires l'utilisation de Java pour certains types de programmes (un 10. Crez une classe avec deux constructeurs (surchargs). En utilisant this,
des problmes est que le ramasse-miettes est imprvisible). appelez le second constructeur dans le premier.
11. Crez une classe avec une mthode finalize( ) qui imprime un message.
Parce que Java garantit la construction de tous les objets, le constructeur est, en fait, Dans main( ), crez un objet de cette classe. Expliquez le comportement de
plus consquent que ce qui est expliqu ici. En particulier, quand on cre de ce programme.
nouvelles classes en utilisant soit la composition, soit l'hritage la garantie de 12. Modifiez l'exercice 11 pour que votre finalize( ) soit toujours appel.
construction est maintenue et une syntaxe supplmentaire est ncessaire. La 13. Crez une classe Tank (NDT: citerne) qui peut tre remplie et vide et qui a
composition, l'hritage et leurs effets sur les constructeurs sont expliqus un peu une death condition qui est que la citerne doit tre vide quand l'objet est
plus loin dans cet ouvrage. nettoy. Ecrivez une mthode finalize( ) qui vrifie cette death condition.
#/TIJ_PAGE05# #TIJ_PAGE06# Dans main( ), testez tous les scnarii possibles d'utilisation de Tank.
14. Crez une classe contenant un int et un char non initialiss et imprimez
leurs valeurs pour vrifier que Java effectue leurs initialisations par dfaut.
Exercices 15. Crez une classe contenant une rfrence non-initialise une String.
Montrez que cette rfrence est initialise null par Java.
Les solutions aux exercices choisis peuvent tre trouves dans le document 16. Crez une classe avec un champ String qui est initialis l'endroit de sa
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 109/459
dfinition et un autre qui est initialis par le constructeur. Quelle est la www.BruceEckel.com).
diffrence entre les deux approches ?
[31] Voir Thinking in C++, 2nde dition pour une description complte de
17. Crez une classe avec un champ static String qui est initialis l'endroit de
l'initialisation par agrgat en C++.
la dfinition et un autre qui est initialis par un bloc static. Ajoutez une
mthode statique qui imprime les deux champs et montre qu'ils sont #/TIJ_PAGE06#
initialiss avant d'tre utiliss.
"HTTP://WWW.W3.ORG/TR/HTML4/LOOSE.DTD"> #TIJ_PAGE01#
18. Crez une classe avec un champ String qui est initialis par une
initialisation d'instance . Dcrire une utilisation de cette fonctionnalit 05.07.01 - version 1.2 [Armel] :
(autre que celle spcifie dans cet ouvrage). - Ajout des tags de sparation des pages.
- Remplacement des "foo" par foo.
19. Ecrivez une mthode qui cre et initialise un tableau de double deux 25.04.2001 - version 1.1 [Armel] :
dimensions. La taille de ce tableau est dtermine par les arguments de la - Mise en forme du code html (titres-hx[verdana], paragraphes-
mthode. Les valeurs d'initialisation sont un intervalle dtermin par des p[Georgia], code-blockquote).
valeurs de dbut et de fin galement donn en paramtres de la mthode. 08.06.2000 - version 1.0 [Philippe BOITE] :
Crez une deuxime mthode qui imprimera le tableau gnr par la - Dernire mise jour de la version franaise
Traducteur :
premire. Dans main( ), testez les mthodes en creant et en imprimant - Philippe BOITE
plusieurs tableaux de diffrentes tailles. Texte original :
20.Recommencez l'exercice 19 pour un tableau trois dimensions. -Thinking in Java, 2nd edition, Revision 10
21. Mettez en commentaire la ligne marque (1) dans ExplicitStatic.java et 2000 by Bruce Eckel
vrifiez que la clause d'initialisation statique n'est pas appele. Maintenant
dcommentez une des lignes marques (2) et vrifiez que la clause
5 : Cacher l'Implmentation
d'initialisation statique est appele. Dcommentez maintenant l'autre ligne
marque (2) et vrifiez que l'initialisation statique n'est effectue qu'une
fois.
22.Faites des expriences avec Garbage.java en excutant le programme avec Une rgle principale en conception oriente objet est de sparer les choses qui
les arguments gc , finalize, ou all . Recommencez le processus et changent des choses qui ne changent pas .
voyez si vous dtectez des motifs rptitifs dans la sortie cran. Modifiez le
code pour que System.runFinalization( ) soit appel avant System.gc Ceci est particulirement important pour les bibliothques [libraries]. Les
( ) et regardez les rsultats. utilisateurs (programmeurs clients) de cette bibliothque doivent pouvoir s'appuyer
sur la partie qu'ils utilisent, et savoir qu'ils n'auront pas rcrire du code si une
[27] Dans certains articles crits par Sun relatifs Java, il est plutt fait rfrence au nouvelle version de la bibliothque sort. Inversement, le crateur de la bibliothque
terme maladroit bien que descriptif no-arg constructors . Le terme doit avoir la libert de faire des modifications et amliorations avec la certitude que
constructeur par dfaut est utilis depuis des annes et c'est donc celui que le code du programmeur client ne sera pas affect par ces modifications.
j'utiliserai.
On peut y parvenir l'aide de conventions. Par exemple le programmeur de
[28] Le seul cas dans lequel cela est possible, est si l'on passe une rfrence un bibliothque doit admettre de ne pas enlever des mthodes existantes quand il
objet dans la mthode statique. Ensuite, en utilisant la rfrence (qui est en fait modifie une classe dans la bibliothque, puisque cela casserait le code du
this maintenant), on peut appeler des mthodes non-statiques et accder des programmeur. La situation inverse est plus dlicate. Dans le cas d'un membre de
champs non-statiques. Mais, en gnral, lorsque l'on veut faire quelque chose donnes, comment le crateur de bibliothque peut-il savoir quels membres de
comme cela, on cre tout simplement un mthode non-statique. donnes ont t accds par les programmeurs clients ? C'est galement vrai avec les
[29] Un terme cr par Bill Venners (www.artima.com) pendant le sminaire que lui mthodes qui ne sont qu'une partie de l'implmentation d'une classe et qui ne sont
et moi avons donn ensemble. pas destines tre utilises directement par le programmeur client. Mais que se
passe-t-il si le crateur de bibliothque veut supprimer une ancienne
[30] En comparaison, C++ possde la liste d'initialisation du constructeur qui implmentation et en mettre une nouvelle ? Changer un de ces membres pourrait
dclenche l'initialisation avant d'entrer dans le corps du constructeur. Voir casser le code d'un programmeur client. De ce fait la marge de manoeuvre du
Thinking in C++, 2nde dition (disponible sur le CDROM de cet ouvrage et
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 110/459
crateur de bibliothque est plutt troite et il ne peut plus rien changer. les uns des autres. Une mthode f() dans une classe A ne sera pas en conflit avec
une f() qui a la mme signature (liste d'arguments) dans une classe B. Mais qu'en
Pour corriger ce problme, Java fournit des spcificateurs d'accs pour permettre
est-il des noms des classes ? Que se passe-t-il si on cre une classe stack qui est
au crateur de bibliothque de dire au programmeur client ce qui est disponible et ce
installe sur une machine qui a dj une classe stack crite par quelqu'un d'autre ?
qui ne l'est pas. Les niveaux de contrles d'accs, depuis le plus accessible
Avec Java sur Internet, ceci peut se passer sans que l'utilisateur le sache, puisque les
jusqu'au moins accessible sont public, protected (protg), friendly
classes peuvent tre tlcharges automatiquement au cours de l'excution d'un
(amical, qui n'a pas de mot-cl), et private (priv). Le paragraphe prcdent semble
programme Java.
montrer que, en tant que concepteur de bibliothque, on devrait tout garder aussi
priv [private] que possible, et n'exposer que les mthodes qu'on veut que le Ce conflit de noms potentiel est la raison pour laquelle il est important d'avoir un
programmeur client utilise. C'est bien ce qu'il faut faire, mme si c'est souvent non contrle complet sur les espaces de nommage en Java, et d'tre capable de crer des
intuitif pour des gens qui programment dans d'autres langages (particulirement en noms compltement uniques indpendamment des contraintes d'Internet.
C) et qui ont l'habitude d'accder tout sans restrictions. Avant la fin de ce chapitre
Jusqu'ici, la plupart des exemples de ce livre taient dans un seul fichier et ont t
vous devriez tre convaincus de l'importance du contrle d'accs en Java.
conus pour un usage en local, et ne se sont pas occups de noms de packages (dans
Le concept d'une bibliothque de composants et le contrle de qui peut accder aux ce cas le nom de la classe est plac dans le package par dfaut ). C'est
composants de cette bibliothque n'est cependant pas complet. Reste la question de certainement une possibilit, et dans un but de simplicit cette approche sera
savoir comment les composants sont lis entre eux dans une unit de bibliothque utilise autant que possible dans le reste de ce livre. Cependant, si on envisage de
cohrente. Ceci est contrl par le mot-cl package en Java, et les spcificateurs crer des bibliothques ou des programmes amicaux [friendly] vis--vis d'autres
d'accs varient selon que la classe est dans le mme package ou dans un autre programmes sur la mme machine, il faut penser se prmunir des conflits de noms
package. Donc, pour commencer ce chapitre, nous allons apprendre comment les de classes.
composants de bibliothques sont placs dans des packages. Nous serons alors
Quand on cre un fichier source pour Java, il est couramment appel une unit de
capables de comprendre la signification complte des spcificateurs d'accs.
compilation [compilation unit](parfois une unit de traduction [translation unit]).
Chaque unit de compilation doit avoir un nom se terminant par .java, et dans
package : l'unit de bibliothque l'unit de compilation il peut y avoir une classe public qui doit avoir le mme nom
que le fichier (y compris les majuscules et minuscules, mais sans l'extension .java ).
Il ne peut y avoir qu'une seule classe public dans chaque unit de compilation,
Un package est ce qu'on obtient lorsqu'on utilise le mot-cl import pour apporter sinon le compilateur sortira une erreur. Le reste des classes de cette unit de
une bibliothque complte, tel que compilation, s'il y en a, sont caches du monde extrieur parce qu'elles ne sont pas
import java.util.*; public, elles sont des classes support pour la classe public principale.
Quand on compile un fichier .java, on obtient un fichier de sortie avec exactement
Cette instruction apporte la bibliothque complte d'utilitaires qui font partie de la le mme nom mais avec une extension .class pour chaque classe du fichier .java. De
distribution Java standard. Comme par exemple la classe ArrayList est dans ce fait on peut obtenir un nombre important de fichiers .class partir d'un petit
java.util, on peut maintenant soit spcifier le nom complet java.util.ArrayList nombre de fichiers .java. Si vous avez programm avec un langage compil, vous
(ce qui peut se faire sans l'instruction import), ou on peut simplement dire avez sans doute remarqu que le compilateur gnre un fichier de forme
ArrayList (grce l'instruction import). intermdiaire (gnralement un fichier obj ) qui est ensuite assembl avec
Si on veut importer une seule classe, on peut la nommer dans l'instruction import : d'autres fichiers de ce type l'aide d'un diteur de liens [linker] (pour crer un
fichier excutable) ou un gestionnaire de bibliothque [librarian](pour crer une
import java.util.ArrayList;
bibliothque). Ce n'est pas comme cela que Java travaille ; un programme
excutable est un ensemble de fichiers .class, qui peuvent tre empaquets
Maintenant on peut utiliser ArrayList sans prcision. Cependant, aucune des autres [packaged] et compresss dans un fichier JAR (en utilisant l'archiveur Java jar).
classes de java.util n'est disponible. L'interprteur Java est responsable de la recherche, du chargement et de
La raison de tous ces imports est de fournir un mcanisme pour grer les espaces l'interprtation de ces fichiers [32].
de nommage [name spaces]. Les noms de tous les membres de classe sont isols Une bibliothque est aussi un ensemble de ces fichiers classes. Chaque fichier
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 111/459
possde une classe qui est public (on n'est pas oblig d'avoir une classe public,
mais c'est ce qu'on fait classiquement), de sorte qu'il y a un composant pour chaque
Crer des noms de packages uniques
fichier. Si on veut dire que tous ces composants (qui sont dans leurs propres fichiers
.java et .class spars) sont relis entre eux, c'est l que le mot-cl package On pourrait faire remarquer que, comme un package n'est jamais rellement
intervient. empaquet [packaged] dans un seul fichier, un package pourrait tre fait de
nombreux fichiers .class et les choses pourraient devenir un peu dsordonnes. Pour
Quand on dit : viter ceci, une chose logique faire est de placer tous les fichiers .class d'un
package mypackage; package donn dans un mme rpertoire ; c'est--dire utiliser son avantage la
structure hirarchique des fichiers dfinie par le systme d'exploitation. C'est un des
au dbut d'un fichier (si on utilise l'instruction package, elle doit apparatre la moyens par lequel Java traite le problme du dsordre ; on verra l'autre moyen plus
premire ligne du fichier, commentaires mis part), on dclare que cette unit de tard lorsque l'utilitaire jar sera prsent.
compilation fait partie d'une bibliothque appele mypackage. Ou, dit autrement, Runir les fichiers d'un package dans un mme rpertoire rsoud deux autres
cela signifie que le nom de la classe public dans cette unit de compilation est sous problmes : crer des noms de packages uniques, et trouver ces classes qui
la couverture du nom mypackage, et si quelqu'un veut utiliser ce nom, il doit soit pourraient tre enfouies quelque part dans la structure d'un rpertoire. Ceci est
spcifier le nom complet, soit utiliser le mot-cl import en combinaison avec ralis, comme prsent dans le chapitre 2, en codant le chemin o se trouvent les
mypackage (utilisation des choix donns prcdemment). Remarquez que la fichiers .class dans le nom du package. Le compilateur force cela ; aussi, par
convention pour les noms de packages Java est de n'utiliser que des lettres convention, la premire partie du nom de package est le nom de domaine Internet
minuscules, mme pour les mots intermdiaires. du crateur de la classe, renvers. Comme les noms de domaines Internet sont
Par exemple, supposons que le nom du fichier est MyClass.java. Ceci signifie qu'il garantis uniques, si on suit cette convention, il est garanti que notre nom de
peut y avoir une et une seule classe public dans ce fichier, et que le nom de cette package sera unique et donc qu'il n'y aura jamais de conflit de noms (c'est--dire,
classe doit tre MyClass (y compris les majuscules et minuscules) : jusqu' ce qu'on perde son nom de domaine au profit de quelqu'un qui
commencerait crire du code Java avec les mmes noms de rpertoires). Bien
package mypackage; entendu, si vous n'avez pas votre propre nom de domaine vous devez fabriquer une
public class MyClass {
// . . .
combinaison improbable (telle que votre prnom et votre nom) pour crer des noms
de packages uniques. Si vous avez dcid de publier du code Java, cela vaut la peine
d'effectuer l'effort relativement faible d'obtenir un nom de domaine.
Maintenant, si quelqu'un veut utiliser MyClass ou, aussi bien, une des autres
classes public de mypackage, il doit utiliser le mot-cl import pour avoir sa La deuxime partie de cette astuce consiste rsoudre le nom de package
disposition le ou les noms dfinis dans mypackage. L'autre solution est de donner l'intrieur d'un rpertoire de sa machine, de manire ce que lorsque le programme
le nom complet : Java s'excute et qu'il a besoin de charger le fichier .class (ce qu'il fait
dynamiquement, l'endroit du programme o il doit crer un objet de cette classe
mypackage.MyClass m = new mypackage.MyClass();
particulire, ou la premire fois qu'on accde un membre static de la classe), il
puisse localiser le rpertoire o se trouve le fichier .class.
Le mot-cl import peut rendre ceci beaucoup plus propre :
L'interprteur Java procde de la manire suivante. D'abord il trouve la variable
import mypackage.*;
// . . . d'environnement CLASSPATH (positionne l'aide du systme d'exploitation,
MyClass m = new MyClass(); parfois par le programme d'installation qui installe Java ou un outil Java sur votre
machine). CLASSPATH contient un ou plusieurs rpertoires qui sont utiliss comme
racines de recherche pour les fichiers .class. En commenant cette racine,
Il faut garder en tte que ce que permettent les mots-cls package et import, en
l'interprteur va prendre le nom de package et remplacer chaque point par un
tant que concepteur de bibliothque, c'est de diviser l'espace de nommage global
slash pour construire un nom de chemin depuis la racine CLASSPATH (de sorte
afin d'viter le conflit de nommages, indpendamment de combien il y a de
que package foo.bar.baz devient foo\bar\baz ou foo/bar/baz ou peut-tre
personnes qui vont sur Internet cire des classes en Java.
quelque chose d'autre, selon votre systme d'exploitation). Ceci est ensuite
concatn avec les diverses entres du CLASSPATH. C'est l qu'il recherche le
fichier .class portant le nom correspondant la classe qu'on est en train d'essayer de
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 112/459
crer (il recherche aussi certains rpertoires standards relativement l'endroit o se On voit que le CLASSPATH peut contenir plusieurs chemins de recherche.
trouve l'interprteur Java).
Il y a toutefois une variante lorsqu'on utilise des fichiers JAR. Il faut mettre
Pour comprendre ceci, prenons mon nom de domaine, qui est bruceeckel.com. En galement le nom du fichier JAR dans le classpath, et pas seulement le chemin o il
l'inversant, com.bruceeckel tablit le nom global unique pour mes classes (les se trouve. Donc pour un JAR nomm grape.jar le classpath doit contenir :
extensions com, edu, org, etc... taient auparavant en majuscules dans les packages CLASSPATH=.;D:\JAVA\LIB;C:\flavors\grape.jar
Java, mais ceci a t chang en Java 2 de sorte que le nom de package est
entirement en minuscules). Je peux ensuite subdiviser ceci en dcidant de crer un
rpertoire simplement nomm simple, de faon obtenir un nom de package : Une fois le classpath dfini correctement, le fichier suivant peut tre plac dans
n'importe quel rpertoire :
package com.bruceeckel.simple;
//: c05:LibTest.java
// Utilise la bibliothque.
Maintenant ce nom de package peut tre utilis comme un espace de nommage de import com.bruceeckel.simple.*;
couverture pour les deux fichiers suivants : public class LibTest {
public static void main(String[] args) {
//: com:bruceeckel:simple:Vector.java Vector v = new Vector();
// Cration d'un package. List l = new List();
package com.bruceeckel.simple; }
public class Vector { } ///:~
public Vector() {
System.out.println(
"com.bruceeckel.util.Vector"); Lorsque le compilateur rencontre l'instruction import, il commence rechercher
} dans les rpertoires spcifis par CLASSPATH, recherchant le sous-rpertoire
} ///:~ com\bruceeckel\simple, puis recherchant les fichiers compils de noms appropris
(Vector.class pour Vector et List.class pour List). Remarquez que chacune des
Lorsque vous crerez vos propres packages, vous allez dcouvrir que l'instruction classes et mthodes utilises de Vector et List doivent tre public.
package doit tre le premier code non-commentaire du fichier. Le deuxime fichier
Positionner le CLASSPATH a pos tellement de problmes aux utilisateurs
ressemble assez au premier :
dbutants de Java (a l'a t pour moi quand j'ai dmarr) que Sun a rendu le JDK
//: com:bruceeckel:simple:List.java un peu plus intelligent dans Java 2. Vous verrez, quand vous l'installerez, que vous
// Cration d'un package. pourrez compiler et excuter des programmes Java de base mme si vous ne
package com.bruceeckel.simple;
public class List { positionnez pas de CLASSPATH. Pour compiler et excuter le package des sources
public List() { de ce livre (disponible sur le CD ROM livr avec ce livre, ou sur
System.out.println( www.BruceEckel.com), vous devrez cependant faire quelques modifications de
"com.bruceeckel.util.List"); votre CLASSPATH (celles-ci sont expliques dans le package de sources).
}
} ///:~
Collisions
Chacun de ces fichiers est plac dans le sous-rpertoire suivant dans mon systme :
Que se passe-t-il si deux bibliothques sont importes l'aide de * et qu'elles
C:\DOC\JavaT\com\bruceeckel\simple
contiennent les mmes noms ? Par exemple, supposons qu'un programme fasse
ceci :
Dans ce nom de chemin, on peut voir le nom de package com.bruceeckel.simple,
import com.bruceeckel.simple.*;
mais qu'en est-il de la premire partie du chemin ? Elle est prise en compte dans la import java.util.*;
variable d'environnement CLASSPATH, qui est, sur ma machine :
CLASSPATH=.;D:\JAVA\LIB;C:\DOC\JavaT Comme java.util.* contient galement une classe Vector, ceci cre une collision
potentielle. Cependant, tant qu'on n'crit pas le code qui cause effectivement la
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 113/459
collision, tout va bien ; c'est une chance, sinon on pourrait se retrouver crire une public static void main(String[] args) {
quantit de code importante pour viter des collisions qui n'arriveraient jamais. P.rintln("Available from now on!");
P.rintln("" + 100); // Le force tre une String
La collision se produit si maintenant on essaye de crer un Vector : P.rintln("" + 100L);
P.rintln("" + 3.14159);
Vector v = new Vector(); }
} ///:~
A quelle classe Vector ceci se rfre-t-il ? Le compilateur ne peut pas le savoir, et le
lecteur non plus. Le compilateur se plaint et nous oblige tre explicite. Si je veux le Remarquez que chacun des objets peut facilement tre forc dans une
Vector Java standard, par exemple, je dois dire : reprsentation String en les plaant dans une expression String ; dans le cas ci-
java.util.Vector v =new java.util.Vector(); dessus, le fait de commencer l'expression avec une String vide fait l'affaire. Mais
ceci amne une observation intressante. Si on appelle System.out.println(100),
cela fonctionne sans le transformer [cast] en String. Avec un peu de surcharge
Comme ceci (avec le CLASSPATH) spcifie compltement l'emplacement de ce [overloading], on peut amener la classe P faire ceci galement (c'est un exercice
Vector, il n'y a pas besoin d'instruction import java.util.*, moins que j'utilise la fin de ce chapitre).
autre chose dans java.util.
A partir de maintenant, chaque fois que vous avez un nouvel utilitaire intressant,
vous pouvez l'ajouter au rpertoire tools (ou votre propre rpertoire util ou
Une bibliothque d'outils personnalise tools).
Avec ces connaissances, vous pouvez maintenant crer vos propres bibliothques #/TIJ_PAGE01# #TIJ_PAGE02#
d'outils pour rduire ou liminer les duplications de code. On peut par exemple
crer un alias pour System.out.println( ) pour rduire la frappe. Ceci peut faire Utilisation des imports pour modifier le
partie d'un package appel tools :
comportement
//: com:bruceeckel:tools:P.java
// Les raccourcis P.rint & P.rintln
package com.bruceeckel.tools; Une caractristique manquant Java est la compilation conditionelle du C, qui
public class P { permet de changer un commutateur pour obtenir un comportement diffrent sans
public static void rint(String s) { rien changer d'autre au code. La raison pour laquelle cette caractristique n'a pas t
System.out.print(s);
retenue en Java est probablement qu'elle est surtout utilise en C pour rsoudre des
}
public static void rintln(String s) { problmes de portabilit : des parties du code sont compiles diffremment selon la
System.out.println(s); plateforme pour laquelle le code est compil. Comme le but de Java est d'tre
} automatiquement portable, une telle caractristique ne devrait pas tre ncessaire.
} ///:~
Il y a cependant d'autres utilisations valables de la compilation conditionnelle. Un
usage trs courant est le debug de code. Les possibilits de debug sont valides
On peut utiliser ce raccourci pour imprimer une String , soit avec une nouvelle
pendant le dveloppement, et invalides dans le produit livr. Allen Holub
ligne (P.rintln( )) , ou sans (P.rint( )).
(www.holub.com) a eu l'ide d'utiliser les packages pour imiter la compilation
Vous pouvez deviner que l'emplacement de ce fichier doit tre dans un rpertoire conditionnelle. Il l'a utilise pour crer une version du trs utile mcanisme
qui commence un des rpertoire du CLASSPATH, puis continue dans d'affirmation [assertion mechanism] du C, dans lequel on peut dire ceci devrait
com/bruceeckel/tools. Aprs l'avoir compil, le fichier P.class peut tre utilis tre vrai ou ceci devrait tre faux et si l'instruction n'est pas d'accord avec cette
partout sur votre systme avec une instruction import : affirmation, on en sera averti. Un tel outil est trs utile pendant la phase de
//: c05:ToolTest.java debuggage.
// Utilise la bibliothque tools Voici une classe qu'on utilisera pour debugger :
import com.bruceeckel.tools.*;
public class ToolTest { //: com:bruceeckel:tools:debug:Assert.java
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 114/459
// Outil d'affirmation pour debugger import com.bruceeckel.tools.*;
package com.bruceeckel.tools.debug;
public class Assert {
private static void perr(String msg) { le programme n'affichera plus d'affirmations. Voici un exemple :
System.err.println(msg); //: c05:TestAssert.java
} // Dmonstration de l'outil d'affirmation.
public final static void is_true(boolean exp) { // Mettre en commentaires ce qui suit, et enlever
if(!exp) perr("Assertion failed"); // le commentaire de la ligne suivante
} // pour modifier le comportement de l'affirmation :
public final static void is_false(boolean exp){ import com.bruceeckel.tools.debug.*;
if(exp) perr("Assertion failed"); // import com.bruceeckel.tools.*;
} public class TestAssert {
public final static void public static void main(String[] args) {
is_true(boolean exp, String msg) { Assert.is_true((2 + 2) == 5);
if(!exp) perr("Assertion failed: " + msg); Assert.is_false((1 + 1) == 2);
} Assert.is_true((2 + 2) == 5, "2 + 2 == 5");
public final static void Assert.is_false((1 + 1) == 2, "1 +1 != 2");
is_false(boolean exp, String msg) { }
if(exp) perr("Assertion failed: " + msg); } ///:~
}
} ///:~
En changeant le package qui est import, on change le code de la version debug la
Cette classe encapsule simplement des tests boolens, qui impriment des messages version de production. Cette technique peut tre utilise pour toutes sortes de code
d'erreur en cas d'chec. Dans le chapitre 10, on apprendra utiliser un outil plus conditionnel.
sophistiqu pour traiter les erreurs, appel traitement d'exceptions [exception
handling], mais la mthode perr( ) conviendra bien en attendant. Avertissement sur les packages
La sortie est affiche sur la console dans le flux d'erreur standard [standard error
stream]en crivant avec System.err. Il faut se rappeler que chaque fois qu'on cre un package, on spcifie implicitement
une structure de rpertoire en donnant un nom un package. Le package doit se
Pour utiliser cette classe, ajoutez cette ligne votre programme : trouver dans le rpertoire indiqu par son nom, qui doit tre un rpertoire qui peut
import com.bruceeckel.tools.debug.*; tre trouv en partant du CLASSPATH. L'utilisation du mot-cl package peut tre
un peu frustrante au dbut, car moins d'adhrer la rgle nom-de-package -
Pour supprimer les affirmations afin de pouvoir livrer le code, une deuxime classe chemin-de-rpertoire, on obtient un tas de messages mystrieux l'excution
Assert est cre, mais dans un package diffrent : signalant l'impossibilit de trouver une classe donne, mme si la classe est l dans
le mme rpertoire. Si vous obtenez un message de ce type, essayez de mettre en
//: com:bruceeckel:tools:Assert.java commentaire l'instruction package, et si a tourne vous saurez o se trouve le
// Suppression de la sortie de l'affirmation
// pour pouvoir livrer le programme. problme.
package com.bruceeckel.tools;
Les spcificateurs d'accs Java
public class Assert {
public final static void is_true(boolean exp){}
public final static void is_false(boolean exp){}
public final static void
is_true(boolean exp, String msg) {} Quand on les utilise, les spcificateurs d'accs Java public, protected, et private
public final static void sont placs devant la dfinition de chaque membre de votre classe, qu'il s'agisse d'un
is_false(boolean exp, String msg) {} champ ou d'une mthode. Chaque spcificateur d'accs contrle l'accs pour
} ///:~ uniquement cette dfinition particulire. Ceci est diffrent du C++, o un
spcificateur d'accs contrle toutes les dfinitions le suivant jusqu' ce qu'un autre
Maintenant si on change l'instruction import prcdente en : spcificateur d'accs soit rencontr.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 115/459
D'une faon ou d'une autre, toute chose a un type d'accs spcifi. Dans les sections
suivantes, vous apprendrez utiliser les diffrents types d'accs, commencer par
public : accs d'interface
l'accs par dfaut.
Lorsqu'on utilise le mot-cl public, cela signifie que la dclaration du membre qui
suit immdiatement public est disponible pour tout le monde, en particulier pour le
Friendly programmeur client qui utilise la bibliothque. Supposons qu'on dfinisse un
package dessert contenant l'unit de compilation suivante :
Que se passe-t-il si on ne prcise aucun spcificateur d'accs, comme dans tous les //: c05:dessert:Cookie.java
exemples avant ce chapitre ? L'accs par dfaut n'a pas de mot-cl, mais on l'appelle // Cration d'une bibliothque.
couramment friendly (amical). Cela veut dire que toutes les autres classes du package c05.dessert;
package courant ont accs au membre amical, mais pour toutes les classes hors du public class Cookie {
package le membre apparat private. Comme une unit de compilation -un fichier- public Cookie() {
System.out.println("Cookie constructor");
ne peut appartenir qu' un seul package, toutes les classes d'une unit de }
compilation sont automatiquement amicales entre elles. De ce fait, on dit aussi que void bite() { System.out.println("bite"); }
les lments amicaux ont un accs de package[package access]. } ///:~
L'accs amical permet de grouper des classes ayant des points communs dans un
package, afin qu'elles puissent facilement interagir entre elles. Quand on met des Souvenez-vous, Cookie.java doit se trouver dans un sous-rpertoire appel
classes ensemble dans un package (leur accordant de ce fait un accs mutuel leurs dessert, en dessous de c05 (qui signifie le Chapitre 5 de ce livre) qui doit tre en-
membres amicaux, c'est dire en les rendant amicaux ) on possde le code dessous d'un des rpertoire du CLASSPATH. Ne faites pas l'erreur de croire que
de ce package. Il est logique que seul le code qu'on possde ait un accs amical un Java va toujours considrer le rpertoire courant comme l'un des points de dpart
autre code qu'on possde. On pourrait dire que l'accs amical donne une de la recherche. Si vous n'avez pas un . comme un des chemins dans votre
signification ou une raison pour regrouper des classes dans un package. Dans CLASSPATH, Java n'y regardera pas.
beaucoup de langages l'organisation des dfinitions dans des fichiers peut tre faite Maintenant si on cre un programme qui utilise Cookie :
tant bien que mal, mais en Java on est astreint les organiser d'une manire
//: c05:Dinner.java
logique. De plus, on exclura probablement les classes qui ne devraient pas avoir // Utilise la bibliothque.
accs aux classes dfinies dans le package courant. import c05.dessert.*;
public class Dinner {
La classe contrle quel code a accs ses membres. Il n'y a pas de moyen magique public Dinner() {
pour entrer par effraction . Le code d'un autre package ne peut pas dire System.out.println("Dinner constructor");
Bonjour, je suis un ami de Bob ! et voir les membres protected, friendly, et }
private de Bob. La seule faon d'accorder l'accs un membre est de : public static void main(String[] args) {
Cookie x = new Cookie();
1. Rendre le membre public. Ainsi tout le monde, partout, peut y accder. //! x.bite(); // Ne peut y accder
2. Rendre le membre amical en n'utilisant aucun spcificateur d'accs, et }
mettre les autres classes dans le mme package. Ainsi les autres classes } ///:~
peuvent accder ce membre.
3. Comme on le verra au Chapitre 6, lorsque l'hritage sera prsent, une on peut crer un objet Cookie, puisque son constructeur est public et que la classe
classe hrite peut avoir accs un membre protected ou public (mais est public. (Nous allons regarder plus en dtail le concept d'une classe public plus
pas des membres private). Elle peut accder des membres amicaux tard.) Cependant, le membre bite() est inaccessible depuis Dinner.java car bite()
seulement si les deux classes sont dans le mme package. Mais vous n'avez est amical uniquement l'intrieur du package dessert.
pas besoin de vous occuper de cela maintenant.
4. Fournir des mthodes accessor/mutator (connues aussi sous le nom de
mthodes get/set ) qui lisent et changent la valeur. Ceci est l'approche la
plus civilise en termes de programmation oriente objet, et elle est
fondamentale pour les JavaBeans, comme on le verra dans le Chapitre 13.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 116/459
Le package par dfaut (et c'est celui qu'on obtient si on oublie d'ajouter un contrle d'accs). De ce fait, on
ne pensera normalement qu'aux accs aux membres qu'on veut explicitement
rendre public pour le programmeur client, et donc on pourrait penser qu'on
Vous pourriez tre surpris de dcouvrir que le code suivant compile, bien qu'il
n'utilise pas souvent le mot-cl private puisqu'on peut s'en passer (ceci est une
semble ne pas suivre les rgles :
diffrence par rapport au C++). Cependant, il se fait que l'utilisation cohrente de
//: c05:Cake.java private est trs importante, particulirement lors du multithreading (comme on le
// Accde une classe dans verra au Chapitre 14).
// une unit de compilation spare.
class Cake { Voici un exemple de l'utilisation de private :
public static void main(String[] args) {
Pie x = new Pie(); //: c05:IceCream.java
x.f(); // Dmontre le mot-cl "private"
} class Sundae {
} ///:~ private Sundae() {}
static Sundae makeASundae() {
return new Sundae();
Dans un deuxime fichier, dans le mme rpertoire : }
//: c05:Pie.java }
// L'autre classe. public class IceCream {
class Pie { public static void main(String[] args) {
void f() { System.out.println("Pie.f()"); } //! Sundae x = new Sundae();
} ///:~ Sundae x = Sundae.makeASundae();
}
} ///:~
On pourrait premire vue considre ces fichiers comme compltement trangers
l'un l'autre, et cependant Cake est capable de crer l'objet Pie et d'appeler sa Ceci montre un cas o private vient propos : on peut vouloir contrler comment
mthode f() ! (Remarquez qu'il faut avoir . dans le CLASSPATH pour que ces un objet est cr et empcher quelqu'un d'accder un constructeur en particulier
fichiers puissent tre compils.) On penserait normalement que Pie et f() sont (ou tous). Dans l'exemple ci-dessus, on ne peut pas crer un objet Sundae l'aide
amicaux et donc non accessibles par Cake. Ils sont amicaux, cette partie-l est de son constructeur ; il faut plutt utiliser la mthode makeASundae() qui le fera
exacte. La raison pour laquelle ils sont accessible dans Cake.java est qu'ils sont pour nous [33].
dans le mme rpertoire et qu'ils n'ont pas de nom de package explicite. Java traite
de tels fichiers comme faisant partie du package par dfaut pour ce rpertoire, et Toute mthode dont on est certain qu'elle n'est utile qu' cette classe peut tre
donc amical pour tous les autres fichiers du rpertoire. rendue private, pour s'assurer qu'on ne l'utilisera pas ailleurs dans le package, nous
interdisant ainsi de la modifier ou de la supprimer. Rendre une mthode private
garantit cela.
private : ne pas toucher !
Ceci est galement vrai pour un champ private dans une classe. A moins qu'on ne
Le mot-cl private signifie que personne ne peut accder ce membre part la doive exposer une implmentation sous-jacente (ce qui est beaucoup plus rare qu'on
ne pourrait penser), on devrait dclarer tous les membres private. Cependant, le fait
classe en question, dans les mthodes de cette classe. Les autres classes du package
ne peuvent accder des membres private, et c'est donc un peu comme si on que la rfrence un objet est private dans une classe ne signifie pas qu'un autre
protgeait la classe contre soi-mme. D'un autre ct il n'est pas impossible qu'un objet ne puisse avoir une rfrence public cet objet (voir l'annexe A pour les
problmes au sujet de l'aliasing).
package soit cod par plusieurs personnes, et dans ce cas private permet de
modifier librement ce membre sans que cela affecte une autre classe dans le mme
package. protected : sorte d'amical
L'accs amical par dfaut dans un package cache souvent suffisamment les
choses ; souvenez-vous, un membre amical est inaccessible l'utilisateur du Le spcificateur d'accs protected demande un effort de comprhension . Tout
package. C'est parfait puisque l'accs par dfaut est celui qu'on utilise normalement d'abord, il faut savoir que vous n'avez pas besoin de comprendre cette partie pour
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 117/459
continuer ce livre jusqu' l'hritage (Chapitre 6). Mais pour tre complet, voici une System.out.println("bite");
brve description et un exemple d'utilisation de protected. }
}
Le mot-cl protected traite un concept appel hritage, qui prend une classe
existante et ajoute des membres cette classe sans modifier la classe existante, que alors bite() est toujours d'accs amical dans le package dessert, mais il est
nous appellerons la classe de base. On peut galement changer le comportement des aussi accessible tous ceux qui hritent de Cookie. Cependant, il n'est pas public.
membres d'une classe existants. Pour hriter d'une classe existante, on dit que le
nouvelle classe extends (tend) une classe existante, comme ceci : #/TIJ_PAGE02# #TIJ_PAGE03#
class Foo extends Bar {
Interface et implmentation
Le reste de la dfinition de la classe est inchang.
Si on cre un nouveau package et qu'on hrite d'une classe d'un autre package, les Le contrle d'accs est souvent appel cacher l'implmentation [implementation
seuls membres accessibles sont les membres public du package d'origine. (Bien sr, hiding] . L'enveloppement [wrapping] des donnes et mthodes l'intrieur des
si on effectue l'hritage dans le mme package, on a l'accs normal tous les classes combin au masquage de l'implmentation est souvent appel encapsulation
membres amicaux du package.) Parfois le crateur de la classe de base veut, [34]. Le rsultat est un type de donnes avec des caractristiques et des
pour un membre particulier, en accorder l'accs dans les classes drives mais pas comportements.
dans le monde entier en gnral. C'est ce que protected fait. Si on reprend le fichier Le contrle d'accs pose des limites sur un type de donnes pour deux raisons
Cookie.java, la classe suivante ne peut pas accder au membre amical : importantes. La premire est de dterminer ce que les programmeurs clients
//: c05:ChocolateChip.java peuvent et ne peuvent pas utiliser. On peut construire les mcanismes internes dans
// Nepeut pas accder un membre amical la structure sans se proccuper du risque que les programmeurs clients prennent ces
// dans une autre classe. mcanismes internes comme faisant partie de l'interface qu'ils doivent utiliser.
import c05.dessert.*;
public class ChocolateChip extends Cookie { Ceci amne directement la deuxime raison, qui est de sparer l'interface de son
public ChocolateChip() { implmentation. Si la structure est utilise dans un ensemble de programmes, mais
System.out.println(
que les programmeurs clients ne peuvent qu'envoyer des messages l'interface
"ChocolateChip constructor"); public, alors on peut modifier tout ce qui n'est pas public (c'est dire amical ,
} protected, ou private) sans que cela ncessite des modifications du code client.
public static void main(String[] args) {
ChocolateChip x = new ChocolateChip(); Nous sommes maintenant dans le monde de la programmation oriente objet, dans
//! x.bite(); // Ne peut pas accder bite lequel une class est en fait la description d' une classe d'objets , comme on
}
} ///:~ dcrirait une classe des poissons ou une classe des oiseaux. Tout objet appartenant
cette classe partage ces caractristiques et comportements. La classe est une
description de la faon dont les objets de ce type vont nous apparatre et se
Une des particularits intressantes de l'hritage est que si la mthode bite() existe
comporter.
dans la classe Cookie, alors elle existe aussi dans toute classe hrite de Cookie. Mais
comme bite() est amical dans un autre package, il nous est inaccessible dans Dans le langage de POO d'origine, Simula-67 , le mot-cl class tait utilis pour
celui-ci. Bien sr, on pourrait le rendre public, mais alors tout le monde y aurait dcrire un nouveau type de donnes. Le mme mot-cl a t repris dans la plupart
accs, ce qui ne serait peut-tre pas ce qu'on veut. Si on modifie la classe Cookie des langages orients objet. Ceci est le point central de tout le langage : la cration
comme ceci : de nouveaux types de donnes qui sont plus que simplement des botes contenant
public class Cookie { des donnes et des mthodes.
public Cookie() { La classe est le concept de POO fondamental en Java. C'est l'un des mots-cls qui ne
System.out.println("Cookie constructor");
} sera pas mis en gras dans ce livre, a devient lourd pour un mot aussi souvent
rpt que class .
protected void bite() {
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 118/459
Pour plus de clart, il est prfrable d'utiliser un style de cration des classes qui import mylib.Widget;
place les membres public au dbut, suivi par les membres protected, amicaux et
private. L'avantage de ceci est que l'utilisateur de la classe peut voir ce qui est ou
important pour lui (les membres public, parce qu'on peut y accder de l'extrieur import mylib.*;
du fichier), en lisant depuis le dbut et en s'arrtant lorsqu'il rencontre les membres
non-public, qui font partie de l'implmentation interne :
Il y a cependant un ensemble de contraintes supplmentaires :
public class X {
public void pub1( ) { /* . . . */ } 1. Il ne peut y avoir qu'une seule classe public par unit de compilation
public void pub2( ) { /* . . . */ } (fichier). L'ide est que chaque unit de compilation a une seule interface
public void pub3( ) { /* . . . */ } publique reprsente par cette classe public . Elle peut avoir autant de
private void priv1( ) { /* . . . */ }
private void priv2( ) {/* . . . */ } classes amicales de support qu'on veut. Si on a plus d'une classe public
private void priv3( ) { /* . . . */ } dans une unit de compilation, le compilateur gnrera un message
private int i; d'erreur.
// . . . 2. Le nom de la classe public doit correspondre exactement au nom du fichier
} contenant l'unit de compilation, y compris les majuscules et minuscules.
Par exemple pour Widget, le nom du fichier doit tre Widget.java, et pas
Ceci ne la rendra que partiellement plus lisible parce que l'interface et widget.java ou WIDGET.java. L aussi on obtient des erreurs de
l'implmentation sont encore mlangs. C'est--dire qu'on voit toujours le code compilation s'ils ne correspondent pas.
source (l'implmentation) parce qu'il est l dans la classe. Cependant, la 3. Il est possible, bien que non habituel, d'avoir une unit de compilation sans
documentation sous forme de commentaires supporte par javadoc (dcrite au aucune classe public. Dans ce cas, on peut appeler le fichier comme on
Chapitre 2) diminue l'importance de la lisibilit du code par le programmeur client. veut.
Afficher l'interface au consommateur d'une classe est normalement le travail du
class browser, un outil dont le travail consiste inspecter toutes les classes Que se passe-t-il si on a une classe dans mylib qu'on utilise uniquement pour
disponibles et de montrer ce qu'on peut en faire (c'est dire quels membres sont accomplir les tches effectues par Widget ou une autre classe public de mylib ?
disponibles) de faon pratique. Au moment o vous lisez ceci, les browsers devraient On ne veut pas crer de documentation pour un programmeur client, et on pense
faire partie de tout bon outil de dveloppement Java. que peut-tre plus tard on modifiera tout et qu'on refera toute la classe en lui en
substituant une nouvelle. Pour garder cette possibilit, il faut s'assurer qu'aucun
programmeur client ne devienne dpendant des dtails d'implmentation cachs
L'accs aux classes dans mylib. Pour raliser ceci il suffit d'enlever le mot-cl public de la classe, qui
devient dans ce cas amicale. (Cette classe ne peut tre utilise que dans ce package.)
En Java, les spcificateurs d'accs peuvent aussi tre utiliss pour dterminer Remarquez qu'une classe ne peut pas tre private (cela ne la rendrait accessible
quelles classes d'une bibliothque seront accessibles aux utilisateurs de cette personne d'autre que cette classe), ou protected [35]. Il n'y a donc que deux choix
bibliothque. Si on dsire qu'une classe soit disponible pour un programmeur client, pour l'accs aux classes : amical ou public. Si on ne veut pas que quelqu'un
on place le mot-cl public quelque part devant l'accolade ouvrante du corps de la d'autre accde cette classe, on peut rendre tous les constructeurs private, ce qui
classe. Ceci permet de contrler le fait mme qu'un programmeur client puisse crer empche tout le monde de crer un objet de cette classe, part soi-mme dans un
un objet de cette classe. membre static de la classe [36]. Voici un exemple :
Pour contrler l'accs la classe, le spcificateur doit apparatre avant le mot-cl //: c05:Lunch.java
class. Donc on peut dire : // Dmontre les spcificateurs
public class Widget { d'accs de classes.
// Faire une classe effectivement private
// avec des constructeurs private :
Maintenant, si le nom de la bibliothque est mylib, tout programmeur client peut class Soup {
accder Widget en disant private Soup() {}
// (1) Permettre la cration l'aide d'une mthode static
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 119/459
: garder un compteur du nombre d'objets Soup crs (peut-tre pour restreindre leur
public static Soup makeSoup() { population).
return new Soup();
} La seconde possibilit utilise ce qu'on appelle un patron de conception [design
// (2) Crer un objet static et pattern], qui est expliqu dans Thinking in Patterns with Java, tlchargeable sur
// retourner une rfrence la demande.
// (le patron "Singleton"): www.BruceEckel.com. Ce patron particulier est appel un singleton parce qu'il
private static Soup ps1 = new Soup(); n'autorise la cration que d'un seul objet. L'objet de classe Soup est cr comme un
public static Soup access() { membre static private de Soup, ce qui fait qu'il n'y en a qu'un seul, et on ne peut y
return ps1; accder qu' travers la mthode public access().
}
public void f() {} Comme mentionn prcdemment, si on ne met pas de spcificateur d'accs il est
} amical par dfaut. Ceci signifie qu'un objet de cette classe peut tre cr par
class Sandwich { // Utilise Lunch toute autre classe du package, mais pas en dehors du package (souvenez-vous que
void f() { new Lunch(); }
} tous les fichiers dans le mme rpertoire qui n'ont pas de dclaration package
// Une seule classe public autorise par fichier : explicite font implicitement partie du package par dfaut pour ce rpertoire).
public class Lunch { Cependant, si un membre static de cette classe est public, le programmeur client
void test() { peut encore accder ce membre static mme s'il ne peut pas crer un objet de
// Ne peut pas faire ceci ! Constructeur priv : cette classe.
//! Soup priv1 = new Soup();
Soup priv2 = Soup.makeSoup();
Sandwich f1 = new Sandwich();
Soup.access().f(); Rsum
}
} ///:~
Dans toute relation il est important d'avoir des limites respectes par toutes les
parties concernes. Lorsqu'on cre une bibliothque, on tablit une relation avec
Jusqu'ici, la plupart des mthodes retournaient soit void soit un type primitif, ce l'utilisateur de cette bibliothque (le programmeur client) qui est un autre
qui fait que la dfinition : programmeur, mais qui construit une application ou qui utilise la bibliothque pour
public static Soup access() { crer une bibliothque plus grande.
return ps1;
} Sans rgles, les programmeurs clients peuvent faire tout ce qu'ils veulent des
membres de la classe, mme si vous prfreriez qu'ils ne manipulent pas
directement certains des membres. Tout est dcouvert dans le monde entier.
pourrait paratre un peu confuse. Le mot devant le nom de la mthode (access) dit
ce que retourne la mthode. Jusqu'ici cela a t le plus souvent void, ce qui signifie Ce chapitre a dcrit comment les classes sont construites pour former des
qu'elle ne retourne rien. Mais on peut aussi retourner la rfrence un objet, bibliothques ; d'abord, comment un groupe de classes est empaquet [packaged]
comme c'est le cas ici. Cette mthode retourne une rfrence un objet de la classe dans une bibliothque, et ensuite comment la classe contrle l'accs ses membres.
Soup.
On estime qu'un projet programm en C commence s'crouler losqu'il atteint 50K
La classe Soup montre comment empcher la cration directe d'une classe en 100K de lignes de code, parce que le C a un seul espace de nommage , et donc
rendant tous les constructeurs private. Souvenez-vous que si vous ne crez pas les noms commencent entrer en conflit, provoquant un surcrot de gestion. En
explicitement au moins un constructeur, le constructeur par dfaut (un constructeur Java, le mot-cl package, le principe de nommage des packages et le mot-cl
sans arguments) sera cr pour vous. En crivant ce constructeur par dfaut, il ne import donnent un contrle complet sur les noms, et le problme de conflit de
sera pas cr automatiquement. En le rendant private, personne ne pourra crer un nommage est facilement vit.
objet de cette classe. Mais alors comment utilise-t-on cette classe ? L'exemple ci-
dessus montre deux possibilits. Premirement, une mthode static est cre, elle Il y a deux raisons pour contrler l'accs aux membres. La premire est d'carter les
cree un nouveau Soup et en retourne la rfrence. Ceci peut tre utile si on veut utilisateurs des outils qu'ils ne doivent pas utiliser ; outils qui sont ncessaires pour
faire des oprations supplmentaires sur Soup avant de le retourner, ou si on veut les traitements internes des types de donnes, mais qui ne font pas partie de
l'interface dont les utilisateurs ont besoin pour rsoudre leurs problmes
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 120/459
particuliers. Donc crer des mthodes et des champs private est un service rendu 3. Dans la section appele Collisions , prenez les fragments de code et
aux utilisateurs parce qu'ils peuvent facilement voir ce qui est important pour eux et transformez les en programme, et vrifiez qu'en fait les collisions arrivent.
ce qu'ils peuvent ignorer. Cela leur simplifie la comprhension de la classe. 4. Gnralisez la classe P dfinie dans ce chapitre en ajoutant toutes les
versions surcharges de rint( ) et rintln( ) ncessaires pour grer tous les
La deuxime raison, et la plus importante, pour le contrle d'accs, est de permettre
types Java de base.
au concepteur de bibliothque de modifier les fonctionnements internes de la classe
5. Modifiez l'instruction import de TestAssert.java pour autoriser ou inhiber
sans se soucier de la faon dont cela peut affecter le programmeur client. On peut
le mcanisme d'assertion.
construire une classe d'une faon, et ensuite dcouvrir qu'une restructuration du
6. Crez une classe avec public, private, protected, et des membres de
code amliorera grandement sa vitesse. Si l'interface et l'implmentation sont
donnes et des mthodes amicaux . Faites attention au fait que des
clairement spares et protges, on peut y arriver sans forcer l'utilisateur rcrire
classes dans un mme rpertoire font partie d'un package par dfaut .
son code.
7. Crez une classe avec des donnes protected. Crez une deuxime classe
Les spcificateurs d'accs en Java donnent un contrle prcieux au crateur d'une dans le mme fichier, qui a une mthode qui manipule les donnes
class. Les utilisateurs de la class peuvent voir clairement et exactement ce qu'ils protected de la premire classe.
peuvent utiliser et ce qu'ils peuvent ignorer. Encore plus important, on a la 8. Modifiez la classe Cookie comme spcifi dans la section "protected :
possiblit de garantir qu'aucun utilisateur ne deviendra dpendant d'une sorte d'amical . Vrifiez que bite() n'est pas public.
quelconque partie de l'implmentation d'une class. Sachant cela en tant que 9. Dans la section nomme Accs aux classes vous trouverez des fragments
crateur d'une class, on peut en modifier l'implmentation en sachant qu'aucun de code dcrivant mylib etWidget. Crez cette bibliothque, et ensuite
programmeur client ne sera affect par les modifications car il ne peut accder crez un Widget dans une classe qui ne fait pas partie du package mylib.
cette partie de la class. 10. Crez un nouveau rpertoire et modifiez votre CLASSPATH pour inclure ce
nouveau rpertoire. Copiez le fichier P.class (produit par la compilation de
Lorsqu'on a la possibilit de modifier l'implmentation, on peut non seulement com.bruceeckel.tools.P.java) dans votre nouveau rpertoire et changez
amliorer la conception plus tard, mais on a aussi le droit de faire des erreurs .
ensuite le nom du fichier, la classe P l'intrieur, et les noms de mthodes
Quelles que soient les soins que vous apportez votre planning et votre (vous pouvez aussi ajouter des sorties supplmentaires pour observer
conception, vous ferez des erreurs. Savoir qu'il est relativement peu dangereux de comment cela fonctionne). Crez un autre programme dans un autre
faire ces erreurs veut dire que vous ferez plus d'expriences, vous apprendrez plus
rpertoire, qui utilise votre nouvelle classe.
vite, et vous finirez plus vite votre projet. 11. En suivant la forme de l'exemple Lunch.java, crez une classe appele
L'interface publique d'une classe est ce que l'utilisateur voit, donc c'est la partie qui ConnectionManager qui gre un tableau fixe d'objets Connection. Le
doit tre correcte lors de l'analyse et la conception. Et mme ici vous avez encore programmeur client ne doit pas pouvoir crer explicitement des objets
quelques possibilits de modifications. Si vous n'avez pas la bonne interface du Connection, mais doit seulement pouvoir les obtenir l'aide d'une
premier coup, vous pouvez ajouter des mthodes , pour autant que vous ne mthode static dans ConnectionManager. Lorsque le
supprimiez pas celles que les programmeurs clients ont dj utilis dans leur code. ConnectionManager tombe court d'objets, il retourne une rfrence
null. Testez la classe dans main().
12. Crez le fichier suivant dans le rpertoire c05/local (suppos tre dans votre
Exercices CLASSPATH) :
13.///: c05:local:PackagedClass.java
package c05.local;
Les solutions des exercices slectionns sont disponibles dans le document class PackagedClass {
lectronique The Thinking in Java Annotated Solution Guide, disponible un prix public PackagedClass() {
raisonnable sur www.BruceEckel.com. System.out.println(
"Creating a packaged class");
1. Ecrivez un programme qui cre un objet ArrayList sans importer }
explicitement java.util.*. }///:~
2. Dans la section nomme package : l'unit de bibliothque , transformez
les fragments de code concernant mypackage en un ensemble de fichiers Crez enuite le fichier suivant dans un rpertoire autre que c05 :
Java qui peuvent tre compils et qui tournent.
///: c05:foreign:Foreign.java
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 121/459
package c05.foreign;
import c05.local.*; changer.
public class Foreign {
public static void main (String[] args) {
C'est l'approche utilise dans les langages procduraux comme C, et a n'a pas trs
PackagedClass pc = new PackagedClass(); bien fonctionn. Comme tout en Java, la solution rside dans les classes. On
} rutilise du code en crant de nouvelles classes, mais au lieu de les crer depuis zro,
} ///:~ on utilise les classes que quelqu'un a construit et test.
L'astuce est d'utiliser les classes sans dtriorer le code existant. Dans ce chapitre
Expliquez pourquoi le compilateur gnre une erreur. Le fait de mettre la nous verrons deux manires de faire. La premire est plutt directe : On cre
classe Foreign dans le package c05.local changerait-il quelque chose ? simplement des objets de nos classes existantes l'intrieur de la nouvelle classe. a
[32] Rien en Java n'oblige utiliser un interprteur. Il existe des compilateurs Java s'appelle la composition, parce que la nouvelle classe se compose d'objets de classes
de code natif qui gnrent un seul fichier excutable. existantes. On rutilise simplement les fonctionnalits du code et non sa forme.
[33] Il y a un autre effet dans ce cas. Comme le constructeur par dfaut est le seul La seconde approche est plus subtile. On cre une nouvelle classe comme un type
dfini, et qu'il est private, il empchera l'hritage de cette classe. (Un sujet qui sera d'une classe existante. On prend littralement la forme d'une classe existante et on
prsent dans le Chapitre 6.) lui ajoute du code sans modifier la classe existante. Cette magie s'appelle l'hritage,
et le compilateur fait le plus gros du travail. L'hritage est une des pierres angulaires
[34] Cependant, on parle souvent aussi d'encapsulation pour le seul fait de cacher de la programmation par objets, et a bien d'autres implications qui seront explores
l'implmentation. au chapitre 7.
[35] En fait, une classe interne[inner class] peut tre private ou protected, mais il Il s'avre que beaucoup de la syntaxe et du comportement sont identiques pour la
s'agit d'un cas particulier. Ceux-ci seront prsents au Chapitre 7. composition et l' hritage (cela se comprend parce qu'ils sont tous deux des moyens
[36] On peut aussi le faire en hritant (Chapitre 6) de cette classe. de construire des nouveaux types partir de types existants). Dans ce chapitre, nous
apprendrons ces mcanismes de rutilisation de code.
#/TIJ_PAGE03#
"HTTP://WWW.W3.ORG/TR/HTML4/LOOSE.DTD"> #TIJ_PAGE01#
Syntaxe de composition
05.07.01 - version 1.2 [Armel] :
- Ajout des tags de sparation des pages.
25.04.2001 - version 1.1 : Jusqu' maintenant, la composition a t utilise assez frquemment. On utilise
- Mise en forme du code html (titres-hx[verdana], paragraphes- simplement des rfrences sur des objets dans de nouvelles classes. Par exemple,
p[Georgia], code-blockquote). supposons que l'on souhaite un objet qui contient plusieurs objets de type String,
Traducteur :
- Olivier THOMANN
quelques types primitifs et un objet d'une autre classe. Pour les objets, on met des
Texte original : rfrences l'intrieur de notre nouvelle classe, mais on dfinit directement les
-Thinking in Java, 2nd edition, Revision 10 types primitifs:
2000 by Bruce Eckel
// ! c06:SprinklerSystem.java
// La composition pour rutiliser du code.
class WaterSource {
6 : Rutiliser les classes
private String s;
WaterSource() {
System.out.println("WaterSource()");
s = new String("Constructed");
Une des caractristiques les plus excitantes de Java est la }
public String toString() { return s; }
rutilisation du code. Mais pour tre vraiment }
public class SprinklerSystem {
rvolutionnaire, il faut faire plus que copier du code et le private String valve1, valve2, valve3, valve4;
WaterSource source;
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 122/459
int i; obtient une exception. En fait il est bon (et utile) qu'on puisse les afficher sans
float f; lancer d'exception.
void print() {
System.out.println("valve1 = " + valve1); On comprend bien que le compilateur ne cre pas un objet par dfaut pour chaque
System.out.println("valve2 = " + valve2); rfrence parce que cela induirait souvent une surcharge inutile. Si on veut
System.out.println("valve3 = " + valve3);
System.out.println("valve4 = " + valve4); initialiser les rfrences, on peut faire :
System.out.println("i = " + i); 1. Au moment o les objets sont dfinis. Cela signifie qu'ils seront toujours
System.out.println("f = " + f);
System.out.println("source = " + source); initialiss avant que le constructeur ne soit appel ;
} 2. Dans le constructeur pour la classe ;
public static void main(String[] args) { 3. Juste avant d'utiliser l'objet, ce qui est souvent appel initialisation
SprinklerSystem x = new SprinklerSystem(); paresseuse.
x.print();
} Cela peut rduire la surcharge dans les situations o l'objet n'a pas besoin d'tre cr
} ///:~ chaque fois.
Les trois approches sont montres ici:
Une des mthodes dfinies dans WaterSource est spciale : toString( ). Vous
apprendrez plus tard que chaque type non primitif a une mthode toString( ), et // ! c06:Bath.java
elle est appele dans des situations spciales lorsque le compilateur attend une // Initialisation dans le constructeur avec composition.
class Soap {
String alors qu'il ne trouve qu'un objet. Donc dans une expression: private String s;
System.out.println("source = " + source); Soap() {
System.out.println("Soap()");
s = new String("Constructed");
le compilateur voit que vous essayez d'ajouter un objet String ("source = ") un }
WaterSource. Ceci n'a pas de sens parce qu'on peut seulement ajouter une String public String toString() { return s; }
une autre String, donc il se dit qu'il va convertir source en une String en }
public class Bath {
appelant toString( ) ! Aprs avoir fait cela il combine les deux Strings et passe la private String
String rsultante System.out.println( ). Ds qu'on veut permettre ce // Initialisation au moment de la dfinition:
comportement avec une classe qu'on cre, il suffit simplement de dfinir une s1 = new String("Happy"),
mthode toString( ). s2 = "Happy",
s3, s4;
Au premier regard, on pourrait supposer Java tant sr et prudent comme il Soap castille;
l'est que le compilateur construirait automatiquement des objets pour chaque int i;
rfrence dans le code ci-dessus ; par exemple, en appelant le constructeur par float toy;
Bath() {
dfaut pour WaterSource pour initialiser source. Le rsultat de l'instruction System.out.println("Inside Bath()");
d'impression affich est en fait : s3 = new String("Joy");
valve1 = null i = 47;
valve2 = null toy = 3.14f;
valve3 = null castille = new Soap();
valve4 = null }
i = 0 void print() {
f = 0.0 // Initialisation diffre:
source = null if(s4 == null)
s4 = new String("Joy");
System.out.println("s1 = " + s1);
Les types primitifs qui sont des champs d'une classe sont automatiquement System.out.println("s2 = " + s2);
initialiss zro, comme prcis dans le chapitre 2. Mais les rfrences objet sont System.out.println("s3 = " + s3);
initialises null, et si on essaye d'appeler des mthodes pour l'un d'entre eux, on System.out.println("s4 = " + s4);
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 123/459
System.out.println("i = " + i); private String s = new String("Cleanser");
System.out.println("toy = " + toy); public void append(String a) { s += a; }
System.out.println("castille = " + castille); public void dilute() { append(" dilute()"); }
} public void apply() { append(" apply()"); }
public static void main(String[] args) { public void scrub() { append(" scrub()"); }
Bath b = new Bath(); public void print() { System.out.println(s); }
b.print(); public static void main(String[] args) {
} Cleanser x = new Cleanser();
} ///:~ x.dilute(); x.apply(); x.scrub();
x.print();
}
Notez que dans le constructeur de Bath une instruction est excute avant que }
toute initialisation ait lieu. Quand on n'initialise pas au moment de la dfinition, il public class Detergent extends Cleanser {
n'est pas encore garanti qu'on excutera une initialisation avant qu'on envoie un // Change une mthode:
message un objet sauf l'invitable exception l'excution. public void scrub() {
append(" Detergent.scrub()");
Ici la sortie pour le programme est : super.scrub(); // Appel de la version de la classe de base
}
Inside Bath() // Ajoute une mthode l'interface:
Soap() public void foam() { append(" foam()"); }
s1 = Happy // Test de la nouvelle classe:
s2 = Happy public static void main(String[] args) {
s3 = Joy Detergent x = new Detergent();
s4 = Joy x.dilute();
i = 47 x.apply();
toy = 3.14 x.scrub();
castille = Constructed x.foam();
x.print();
Quand print( ) est appel, il remplit s4 donc tout les champs sont proprement System.out.println("Testing base class:");
Cleanser.main(args);
initialiss au moment o ils sont utiliss. }
} ///:~
La syntaxe de l'hritage Ceci montre un certain nombre de caractristiques. Premirement, dans Cleanser
la mthode append( ), les Strings sont concatnes dans s en utilisant l'oprateur
L'hritage est une partie primordiale de Java (et des langages de programmation par +=, qui est l'un des oprateurs (avec + ) que les crateurs de Java ont
objets en gnral). Il s'avre qu'on utilise toujours l'hritage quand on veut crer une surcharg pour travailler avec les Strings.
classe, parce qu' moins d'hriter explicitement d'une autre classe, on hrite
implicitement de la classe racine standard Object. Deuximement, tant Cleanser que Detergent contiennent une mthode main( ).
On peut crer une main( ) pour chacune de nos classes, et il est souvent
La syntaxe de composition est vidente, mais pour raliser l'hritage il y a une forme recommand de coder de cette manire afin de garder le code de test dans la classe.
distinctement diffrente. Quand on hrite, on dit Cette nouvelle classe est comme Mme si on a beaucoup de classes dans un programme, seulement la mthode main
l'ancienne classe . On stipule ceci dans le code en donnant le nom de la classe ( ) pour une classe invoque sur la ligne de commande sera appele. Aussi
comme d'habitude, mais avant l'accolade ouvrante du corps de la classe, on met le longtemps que main( ) est public, il importe peu que la classe dont elle fait partie
mot cl extends suivi par le nom de la classe de base. Quand on fait cela, on soit public ou non. Donc dans ce cas, quand on crit java Detergent,
rcupre automatiquement toutes les donnes membres et mthodes de la classe de Detergent.main( ) sera appele. Mais on peut galement crire java Cleanser
base. Voici un exemple: pour invoquer Cleanser.main( ), mme si Cleanser n'est pas une classe public.
// ! c06:Detergent.java Cette technique de mettre une main( ) dans chaque classe permet de tester
// Syntaxe d'hritage & proprits. facilement chaque classe. Et on n'a pas besoin d'enlever la mthode main( ) quand
class Cleanser {
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 124/459
on a finit de tester ; on peut la laisser pour tester plus tard. lieu d'une seule, il peut tre un peu troublant d'essayer d'imaginer l'objet rsultant
produit par la classe drive. De l'extrieur, il semble que la nouvelle classe a la
Ici, on peut voir que Detergent.main( ) appelle Cleanser.main( ) explicitement,
mme interface que la classe de base et peut-tre quelques mthodes et champs
en passant les mme arguments depuis la ligne de commande (quoiqu'il en soit, on
additionnels. Mais l'hritage ne se contente pas simplement de copier l'interface de
peut passer n'importe quel tableau de String).
la classe de base. Quand on cre un objet de la classe drive, il contient en lui un
Il est important que toutes les mthodes de Cleanser soient public. Il faut se sous-objet de la classe de base. Ce sous-objet est le mme que si on cre un objet de
souvenir que si on nglige tout modifieur d'accs, par dfaut l'accs sera friendly , la classe de base elle-mme. C'est simplement que, depuis l'extrieur, le sous-objet
lequel permet d'accder seulement aux membres du mme package. Donc, au sein de la classe de base est enrob au sein de l'objet de la classe drive.
d'un mme package, n'importe qui peut utiliser ces mthodes s'il n'y a pas de
Bien sr, il est essentiel que le sous-objet de la classe de base soit correctement
spcificateur d'accs. Detergent n'aurait aucun problme, par exemple. Quoiqu'il
initialis et il y a un seul moyen de garantir cela: excuter l'initialisation dans le
en soit, si une classe d'un autre package devait hriter de Cleanser il pourrait
constructeur, en appelant la constructeur de la classe de base, lequel a tous les
accder seulement aux membres public. Donc pour planifier l'hritage, en rgle
connaissances et les privilges appropris pour excuter l'initialisation de la classe
gnrale mettre tous les champs private et toutes les mthodes public (les
de base. Java insre automatiquement les appels au constructeur de la classe de
membres protected permettent galement d'accder depuis une classe drive ;
base au sein du constructeur de la classe drive. L'exemple suivant montre
nous verrons cela plus tard). Bien sr, dans des cas particuliers on devra faire des
comment cela fonctionne avec 3 niveaux d'hritage :
ajustements, mais cela est une rgle utile.
// ! c06:Cartoon.java
Notez que Cleanser contient un ensemble de mthodes dans son // Appels de constructeur durant l'initialisation
interface : append( ), dilute( ), apply( ), scrub( ), et print( ). Parce que class Art {
Detergent est driv de Cleanser ( l'aide du mot-cl extends) il rcupre Art() {
automatiquement toutes les mthodes de son interface , mme si elles ne sont pas System.out.println("Art constructor");
}
toutes dfinies explicitement dans Detergent. On peut penser l'hritage comme }
une rutilisation de l'interface (l'implmentation vient galement avec elle, mais class Drawing extends Art {
ceci n'est pas le point principal). Drawing() {
System.out.println("Drawing constructor");
Comme vu dans scrub( ), il est possible de prendre une mthode qui a t dfinie }
dans la classe de base et la modifier. Dans ce cas, on pourrait vouloir appeler la }
mthode de la classe de base dans la nouvelle version. Mais l'intrieur de scrub( ) public class Cartoon extends Drawing {
on ne peut pas simplement appeler scrub( ), car cela produirait un appel rcursif, Cartoon() {
System.out.println("Cartoon constructor");
ce qui n'est pas ce que l'on veut. Pour rsoudre ce problme, Java a le mot-cl super }
qui rfre la super classe de la classe courante. Donc l'expression super.scrub( ) public static void main(String[] args) {
appelle la version de la classe de base de la mthode scrub( ). Cartoon x = new Cartoon();
}
Quand on hrite, on n'est pas tenu de n'utiliser que les mthodes de la classe de } ///:~
base. On peut galement ajouter de nouvelles mthodes la classe drive
exactement de la manire dont on met une mthode dans une classe : il suffit de la La sortie de ce programme montre les appels automatiques:
dfinir. La mthode foam( ) en est un exemple.
Art constructor
Dans Detergent.main( ) on peut voir que pour un objet Detergent on peut Drawing constructor
appeler toutes les mthodes disponible dans Cleanser aussi bien que dans Cartoon constructor
Detergent (e.g., foam( )).
On peut voir que la construction commence par la classe la plus haute dans la
Initialiser la classe de base hirarchie, donc la classe de base est initialise avant que les constructeurs de la
classe drive puisse y accder.
Depuis qu'il y a deux classes concernes - la classe de base et la classe drive - au Mme si on ne cre pas de constructeur pour Cartoon( ), le compilateur fournira
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 125/459
un constructeur. drive. Cela signifie que rien ne peut tre plac avant lui. Comme vous le verrez
dans le chapitre 10, cela empche galement le constructeur de la classe drive
Constructeurs avec paramtres d'attraper une exception qui provient de la classe de base. Ceci peut tre un
inconvnient de temps en temps.
L'exemple ci-dessus a des constructeurs par dfaut ; ils n'ont pas de paramtres.
C'est facile pour le compilateur d'appeler ceux-ci parce qu'il n'y a pas de questions
se poser au sujet des arguments passer. Si notre classe n'a pas de paramtres par
Combiner composition et hritage.
dfaut, ou si on veut appeler le constructeur d'une classe de base avec paramtre, on
doit explicitement crire les appels au contructeur de la classe de base en utilisant le Il est trs classique d'utiliser ensemble la composition et l'hritage. L'exemple
mot cl super ainsi que la liste de paramtres approprie : super et la liste de suivant montre la cration d'une classe plus complexe, utilisant la fois l'hritage et
paramtres approprie: la composition, avec la ncessaire initialisation des contructeurs:
// ! c06:Chess.java // ! c06:PlaceSetting.java
// Hritage, constructeurs et paramtres. // Mlanger composition & hritage.
class Game { class Plate {
Game(int i) { Plate(int i) {
System.out.println("Game constructor"); System.out.println("Plate constructor");
} }
} }
class BoardGame extends Game { class DinnerPlate extends Plate {
BoardGame(int i) { DinnerPlate(int i) {
super(i); super(i);
System.out.println("BoardGame constructor"); System.out.println(
} "DinnerPlate constructor");
} }
public class Chess extends BoardGame { }
Chess() { class Utensil {
super(11); Utensil(int i) {
System.out.println("Chess constructor"); System.out.println("Utensil constructor");
} }
public static void main(String[] args) { }
Chess x = new Chess(); class Spoon extends Utensil {
} Spoon(int i) {
} ///:~ super(i);
System.out.println("Spoon constructor");
}
Si on n'appelle pas le constructeur de la classe de base dans BoardGame( ), le }
compilateur va se plaindre qu'il ne peut pas trouver le constructeur de la forme class Fork extends Utensil {
Fork(int i) {
Game( ). De plus, l'appel du constructeur de la classe de base doit tre la premire super(i);
chose que l'on fait dans le constructeur de la classe drive. Le compilateur va le System.out.println("Fork constructor");
rappeler si on se trompe. }
}
#/TIJ_PAGE01# #TIJ_PAGE02# class Knife extends Utensil {
Knife(int i) {
Attraper les exceptions du constructeur de base. super(i);
System.out.println("Knife constructor");
}
Comme nous venons de le prciser, le compilateur nous force placer l'appel du }
constructeur de la classe de base en premier dans le constructeur de la classe // Une manire culturelle de faire quelque chose:
class Custom {
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 126/459
Custom(int i) { // Assurer un nettoyage propre.
System.out.println("Custom constructor"); import java.util.*;
} class Shape {
} Shape(int i) {
public class PlaceSetting extends Custom { System.out.println("Shape constructor");
Spoon sp; }
Fork frk; void cleanup() {
Knife kn; System.out.println("Shape cleanup");
DinnerPlate pl; }
PlaceSetting(int i) { }
super(i + 1); class Circle extends Shape {
sp = new Spoon(i + 2); Circle(int i) {
frk = new Fork(i + 3); super(i);
kn = new Knife(i + 4); System.out.println("Drawing a Circle");
pl = new DinnerPlate(i + 5); }
System.out.println( void cleanup() {
"PlaceSetting constructor"); System.out.println("Erasing a Circle");
} super.cleanup();
public static void main(String[] args) { }
PlaceSetting x = new PlaceSetting(9); }
} class Triangle extends Shape {
} ///:~ Triangle(int i) {
super(i);
System.out.println("Drawing a Triangle");
Tant que le compilateur nous force initialiser les classes de base, et requiert que }
nous le fassions directement au dbut du constructeur, il ne vrifie pas que nous void cleanup() {
initialisons les objets membres, donc nous devons nous souvenir de faire attention System.out.println("Erasing a Triangle");
cela. super.cleanup();
}
}
Garantir un nettoyage propre class Line extends Shape {
private int start, end;
Line(int start, int end) {
Java ne possde pas le concept C++ de destructeur, une mthode qui est super(start);
automatiquement appele quand un objet est dtruit. La raison est probablement this.start = start;
qu'en Java la pratique est simplement d'oublier les objets plutt que les dtruire, this.end = end;
System.out.println("Drawing a Line : " +
laissant le ramasse-miette rclamer la mmoire selon les besoins. start + ", " + end);
Souvent cela convient, mais il existe des cas o votre classe pourrait, durant son }
void cleanup() {
existence, excuter des tches ncessitant un nettoyage. Comme mentionn dans le System.out.println("Erasing a Line : " +
chapitre 4, on ne peut pas savoir quand le ramasse-miettes sera excut, ou s'il sera start + ", " + end);
appel. Donc si on veut nettoyer quelque chose pour une classe, on doit crire une super.cleanup();
mthode particulire, et tre sr que l'usager sait qu'il doit appeler cette mthode. }
Par dessus tout, comme dcrit dans le chapitre 10 ( Gestion d'erreurs avec les }
public class CADSystem extends Shape {
exceptions ) - on doit se protger contre une exception en mettant un tel nettoyage private Circle c;
dans une clause finally. private Triangle t;
private Line[] lines = new Line[10];
Considrons un exemple d'un systme de conception assist par ordinateur qui CADSystem(int i) {
dessine des images sur l'cran: super(i + 1);
// ! c06:CADSystem.java for(int j = 0; j < 10; j++)
lines[j] = new Line(j, j*j);
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 127/459
c = new Circle(1); excuter tout le nettoyage spcifique votre classe, dans l'ordre inverse de la
t = new Triangle(1); cration. En gnral, cela ncessite que les lments de la classe de base soient
System.out.println("Combined constructor");
} encore viable. Ensuite appeler la mthode cleanup de la classe de base, comme
void cleanup() { dmontr ici.
System.out.println("CADSystem.cleanup()");
// L'ordre de nettoyage est l'inverse Il y a beaucoup de cas pour lesquels le problme de nettoyage n'est pas un
// de l'ordre d'initialisation problme ; on laisse le ramasse-miettes faire le travail. Mais quand on doit le faire
t.cleanup(); explicitement, diligence et attention sont requis.
c.cleanup();
for(int i = lines.length - 1; i >= 0; i--)
lines[i].cleanup(); L'ordre du ramasse-miettes
super.cleanup();
} Il n'y a pas grand chose sur quoi on puisse se fier quand il s'agit de ramasse-miettes.
public static void main(String[] args) {
CADSystem x = new CADSystem(47); Le ramasse-miette peut ne jamais tre appel. S'il l'est, il peut rclamer les objets
try { dans n'importe quel ordre. Il est prfrable de ne pas se fier au ramasse-miette pour
// Code et gestion des exceptions... autre chose que librer la mmoire. Si on veut que le nettoyage ait lieu, faites vos
} finally { propre mthodes de nettoyage et ne vous fiez pas finalize( ). Comme mentionn
x.cleanup(); dans le chapitre 4, Java peut tre forc d'appeler tous les finalizers.
}
}
} ///:~ Cacher les noms
Tout dans ce systme est une sorte de Shape (lequel est une sorte d'Object Seuls les programmeurs C++ pourraient tre surpris par le masquage de noms, tant
puisqu'il hrite implicitement de la classe racine). Chaque classe redfinit la donn que le fonctionnement est diffrent dans ce langage. Si une classe de base
mthode cleanup( ) de Shape en plus d'appeler la mthode de la classe de base en Java a un nom de mthode qui est surcharg plusieurs fois, redfinir ce nom de
utilisant super. Les classes Shape spcifiques Circle, Triangle et Line ont mthode dans une sous-classe ne cachera aucune des versions de la classe de base.
toutes des constructeurs qui dessinent , bien que n'importe quelle mthode Donc la surcharge fonctionne sans savoir si la mthode tait dfinie ce niveau ou
appele durant la dure de vie d'un objet pourrait tre responsable de faire quelque dans une classe de base:
chose qui ncessite un nettoyage. Chaque classe possde sa propre mthode
cleanup( ) pour restaurer les choses de la manire dont elles taient avant que // ! c06:Hide.java
// Surchage le nom d'une mthode de la classe de base
l'objet n'existe. // dans une classe drive ne cache pas
main( ), on peut noter deux nouveaux mot-cls qui ne seront pas officiellement // les versions de la classe de base.
class Homer {
introduits avant le chapitre 10 : try et finally. Le mot-cl try indique que le bloc char doh(char c) {
qui suit (dlimit par les accolades) est une rgion garde, ce qui signifie qu'elle a System.out.println("doh(char)");
un traitement particulier. Un de ces traitements particuliers est que le code dans la return 'd';
clause finally suivant la rgion garde est toujours excut, quelle que soit la }
manire dont le bloc try termine. Avec la gestion des exceptions, il est possible de float doh(float f) {
System.out.println("doh(float)");
quitter le bloc try de manire non ordinaire. Ici la clause finally dit de toujours return 1.0f;
appeler cleanup( ) pour x, quoiqu'il arrive. Ces mot-cls seront expliqus plus en }
profondeur dans le chapitre 10. }
class Milhouse {}
Notez que dans votre mthode cleanup vous devez faire attention l'ordre d'appel class Bart extends Homer {
pour les mthodes cleanup de la classe de base et celle des objet-membres au cas o void doh(Milhouse m) {}
un des sous-objets dpend des autres. En gnral, vous devriez suivre la mme }
forme qui est impose pour le compilateur C++ sur ses destructeurs : premirement class Hide {
public static void main(String[] args) {
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 128/459
Bart b = new Bart(); public void rollup() {}
b.doh(1); // doh(float) utilis public void rolldown() {}
b.doh('x'); }
b.doh(1.0f); class Door {
b.doh(new Milhouse()); public Window window = new Window();
} public void open() {}
} ///:~ public void close() {}
}
public class Car {
Comme nous le verrons dans le prochain chapitre, il est beaucoup plus courant de public Engine engine = new Engine();
surcharger les mthodes de mme nom et utilisant exactement la mme signature et public Wheel[] wheel = new Wheel[4];
le type retour que dans la classe de base. Sinon cela peut tre source de confusion. public Door left = new Door(),
C'est pourquoi le C++ ne le permet pas, pour empcher de faire ce qui est right = new Door(); // 2-door
public Car() {
probablement une erreur. for(int i = 0; i < 4; i++)
wheel[i] = new Wheel();
Choisir la composition la place de }
public static void main(String[] args) {
l'hritage
Car car = new Car();
car.left.window.rollup();
car.wheel[0].inflate(72);
}
La composition et l'hritage permettent tous les deux de placer des sous-objets } ///:~
l'intrieur de votre nouvelle classe. Vous devriez vous demander quelle est la
diffrence entre les deux et quand choisir l'une plutt que l'autre. Du fait que la composition de la voiture fait partie de l'analyse du problme (et non
La composition est gnralement utilise quand on a besoin des caractristiques pas simplement de la conception sous-jacente), rendre les membre publics aide le
d'une classe existante dans une nouvelle classe, mais pas son interface. On inclut un programmeur client comprendre comment utiliser la classe et ncessite moins de
objet donc on peut l'utiliser pour implmenter une fonctionnalit dans la nouvelle complexit de code pour le crateur de la classe. Quoiqu'il en soit, gardez l'esprit
classe, mais l'utilisateur de la nouvelle classe voit l'interface qu'on a dfini et non que c'est un cas spcial et qu'en gnral on devrait dfinir les champs privs.
celle de l'objet inclus. Pour ce faire, il suffit d'inclure des objets private de classes Quand on hrite, on prend la classe existante et on en fait une version spciale. En
existantes dans la nouvelle classe. gnral, cela signifie qu'on prend une classe d'usage gnral et on l'adapte un cas
Parfois il est sens de permettre l'utilisateur d'une classe d'accder directement particulier. Avec un peu de bon sens, vous verrez que a n'a pas de sens de composer
la composition de notre nouvelle classe ; pour ce faire on dclare les objets membres une voiture en utilisant un objet vhicule. Une voiture ne contient pas un vhicule,
public. Les objets membres utilisent l'implmentation en se cachant les uns des c'est un vhicule. La relation est-un s'exprime avec l'hritage et la relation a-un
autres, ce qui est une bonne chose. Quand l'utilisateur sait qu'on assemble un s'exprime avec la composition.
ensemble de parties, cela rend l'interface plus facile comprendre. Un objet car
(voiture en anglais) est un bon exemple:
// ! c06:Car.java
protected
// Composition avec des objets publics.
class Engine { Maintenant que nous avons introduit l'hritage, le mot cl protected prend
public void start() {} finalement un sens. Dans un monde idal, les membres private devraient toujours
public void rev() {} tre des membres private purs et durs, mais dans les projets rels il arrive souvent
public void stop() {}
}
qu'on veuille cacher quelque chose au monde au sens large et qu'on veuille
class Wheel { permettre l'accs pour les membres des classes drives. Le mot cl protected est
public void inflate(int psi) {} un moyen pragmatique de faire. Il dit Ceci est private en ce qui concerne la classe
} utilisatrice, mais c'est disponible pour quiconque hrite de cette classe ou appartient
class Window { au mme package . C'est pourquoi protected en Java est automatiquement
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 129/459
friendly . Bien que l'hritage pour l'exprimentation puisse tre une technique utile, un
moment donn les choses se stabilisent et vous devez jeter un regard neuf votre
La meilleure approche est de laisser les membres de donnes private. Vous devriez
hirarchie de classes pour la rduire en une structure plus logique. Souvenons nous
toujours prserver le droit de changer l'implmentation sous jacente. Ensuite vous
qu'en dessous de tout, l'hritage est utilis pour exprimer une relation qui
pouvez permettre l'accs contrl pour les hritiers de votre classe travers les
dit : Cette nouvelle classe est du type de l'ancienne classe . Votre programme ne
mthodes protected :
devrait pas tre concern par la manipulation de bits ici ou l, mais par la cration et
// ! c06:Orc.java la manipulation d'objets de diffrents types afin d'exprimer un modle dans les
// Le mot cl protected . termes propres l'espace du problme.
import java.util.*;
class Villain {
private int i;
protected int read() { return i; } Transtypage ascendant
protected void set(int ii) { i = ii; }
public Villain(int ii) { i = ii; }
public int value(int m) { return m*i; } L'aspect le plus important de l'hritage n'est pas qu'il fournisse des mthodes pour
} les nouvelles classes. C'est la relation exprime entre la nouvelle classe et la classe de
public class Orc extends Villain { base. Cette relation peut tre rsume en disant : La nouvelle classe est un type de
private int j; la classe existante .
public Orc(int jj) { super(jj); j = jj; }
public void change(int x) { set(x); } Cette description n'est pas simplement une manire amusante d'expliquer l'hritage
} ///:~ - c'est support directement par le langage. Comme exemple, considrons une classe
de base appele Instrument qui reprsente les instruments de musique et une
On peut voir que change( ) a accs set( ) parce qu'il est protected. classe drive appele Wind. Puisque l'hritage signifie que toutes les mthodes de
la classe de base sont galement disponibles pour la classe drive, n'importe quel
message envoy la classe de base peut galement tre envoy la classe drive. Si
Dveloppement incrmental la classe Instrument a une mthode play( ), les instruments Wind galement.
Cela signifie qu'il est exact de dire qu'un objet Wind est galement un type de
Un des avantages de l'hritage est qu'il supporte le dveloppement incrmental en Instrument. L'exemple suivant montre comment le compilateur implmente cette
permettant d'ajouter du code sans crer de bogues dans le code existant. Ceci notion :
permet galement d'isoler les nouveaux bogues dans le nouveau code. En hritant // ! c06:Wind.java
d'une classe existante et fonctionnelle et en ajoutant des donnes membres et des // Hritage & transtypage ascendant.
mthodes et en redfinissant des mthodes existantes, on laisse le code existant - import java.util.*;
class Instrument {
que quelqu'un d'autre peut encore utiliser - inchang et non bogu. Si un bogue public void play() {}
survient, on sait alors qu'il est dans le nouveau code, lequel est beaucoup plus rapide static void tune(Instrument i) {
et facile lire que si on avait modifi le code existant. // ...
i.play();
Il est plutt surprenant de voir que les classes sont spares proprement. Nous }
n'avons mme pas besoin du code source des mthodes afin de pouvoir les utiliser. }
Au pire, on importe simplement un package. Ceci est vrai la fois pour l'hritage et // Les objets Wind sont des instruments
la composition. // parce qu'ils ont la mme interface:
class Wind extends Instrument {
Il est important de raliser que le dveloppement d'un programme est un processus public static void main(String[] args) {
incrmental, exactement comme l'apprentissage humain. On peut analyser autant Wind flute = new Wind();
Instrument.tune(flute); // Transtypage ascendant
que l'on veut, mais on ne connatra pas toutes les rponses au dmarrage d'un }
projet. Vous aurez beaucoup plus de succs et de retour immdiat si vous } ///:~
commencez par faire grandir votre projet comme un organisme organique et
volutif plutt que de le construire comme un gratte-ciel en verre.
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 130/459
#/TIJ_PAGE02# #TIJ_PAGE03# Composition la place de l'hritage revisit
Le point intressant de cet exemple est la mthode tune( ), qui accepte une
rfrence Instrument. Cependant, dans Wind.main( ) la mthode tune( ) est En programmation orient objet, la manire la plus probable pour crer et utiliser
appele en lui donnant une rfrence Wind. tant donn que Java est strict au sujet du code est simplement de mettre des mthodes et des donnes ensemble dans une
de la vrification de type, il semble trange qu'une mthode qui accepte un type classe puis d'utiliser les objets de cette classe. On utilisera galement les classes
acceptera littralement un autre type jusqu' ce qu'on ralise qu'un objet Wind est existantes pour construire les nouvelles classes avec la composition. Moins
galement un objet Instrument, et il n'y a pas de mthode que tune( ) pourrait frquemment on utilisera l'hritage. Donc bien qu'on insiste beaucoup sur l'hritage
appeler pour un Instrument qui ne serait galement dans Wind. l'intrieur de en apprenant la programmation oriente objet, cela ne signifie pas qu'on doive
tune( ), le code fonctionne pour Instrument et tout ce qui drive de Instrument, l'utiliser partout o l'on peut. Au contraire, on devrait l'utiliser avec parcimonie,
et l'acte de convertir une rfrence Wind en une rfrence Instrument est appel seulement quand il est clair que l'hritage est utile. Un des moyens les plus clairs
transtypage ascendant. pour dterminer si on doit utiliser la composition ou l'hritage est de se demander si
on aura jamais besoin de faire un transtypage ascendant de la nouvelle classe vers la
classe de base. Si on doit faire un transtypage ascendant, alors l'hritage est
Pourquoi le transtypage ascendant ? ncessaire, mais si on n'a pas besoin de faire un transtypage ascendant, alors il faut
regarder avec attention pour savoir si on a besoin de l'hritage. Le prochain chapitre
La raison de ce terme est historique et base sur la manire dont les diagrammes (polymorphisme) fournit une des plus excitantes raisons pour le transtypage
d'hritage ont t traditionnellement dessins : avec la racine au sommet de la page, ascendant, mais si vous vous rappelez de vous demander Ai-je besoin de
et grandissant vers le bas. Bien sr vous pouvez dessiner vos diagrammes de la transtypage ascendant ? , vous aurez un bon outil pour dcider entre composition
manire que vous trouvez le plus pratique. Le diagramme d'hritage pour et hritage.
Wind.java est :
Le mot cl final
Le mot cl Java final a des sens lgrement diffrents suivant le contexte, mais en
gnral il signifie Cela ne peut pas changer . Vous pourriez vouloir empcher les
changements pour deux raisons : conception ou efficacit. Parce que ces deux
raisons sont quelque peu diffrentes, il est possible de mal utiliser le mot cl final.
Les sections suivantes parlent des trois endroits o le mot cl final peut tre
Transtyper depuis une classe drive vers la classe de base nous dplace vers le utilis : donnes, mthodes et classes.
haut dans le diagramme, on fait donc communment rfrence un transtypage
ascendant. Le transtypage ascendant est toujours sans danger parce qu'on va d'un
type plus spcifique vers un type plus gnral. La classe drive est un sur-ensemble
Donnes finales
de la classe de base. Elle peut contenir plus de mthodes que la classe de base, mais
elle contient au moins les mthodes de la classe de base. La seule chose qui puisse Beaucoup de langages de programmation ont un moyen de dire au compilateur que
arriver une classe pendant le transtypage ascendant est de perdre des mthodes et cette donne est constante. Une constante est utile pour deux raisons:
non en gagner. C'est pourquoi le compilateur permet le transtypage ascendant sans 1. Elle peut tre une constante lors de la compilation qui ne changera jamais ;
transtypage explicite ou une notation spciale. 2. Elle peut tre une valeur initialise l'excution qu'on ne veut pas changer.
On peut galement faire l'inverse du transtypage ascendant, appel transtypage Dans le cas d'une constante la compilation, le compilateur inclut en dur la
descendant, mais cela gnre un dilemme qui est le sujet du chapitre 12. valeur de la constante pour tous les calculs o elle intervient ; dans ce cas, le calcul
peut tre effectu la compilation, liminant ainsi un surcot l'excution. En Java,
ces sortes de constantes doivent tre des primitives et sont exprimes en utilisant le
mot-cl final. Une valeur doit tre donne au moment de la dfinition d'une telle
Traduction de Thinking in Java 2nd Edition - <http://penserenjava.free.fr><version_2.4> - Page 131/459
constante. System.out.println("Creating new FinalData");
FinalData fd2 = new FinalData();
Un champ qui est la fois static et final a un emplacement de stockage fixe qui ne fd1.print("fd1");
peut pas tre chang. fd2.print("fd2");
}
Quand on utilise final avec des objets rfrences plutt qu'avec des types primitifs } ///:~
la signification devient un peu confuse. Avec un type primitif, final fait de la valeur
une constante, mais avec un objet rfrence, final fait de la rfrence une Etant donn que i1 et VAL_TWO sont des primitives final ayant une valeur la
constante. Une fois la rfrence lie un objet, elle ne peut jamais changer pour compilation, elles peuvent tre toutes les deux utilises comme constantes la
pointer vers un autre objet. Quoiqu'il en soit, l'objet lui mme peut tre compilation et ne sont pas vraiment diffrentes. VAL_THREE nous montre la
modifi ; Java ne fournit pas de moyen de rendre un objet arbitraire une constante. manire la plus typique de dfinir ces constantes : public afin qu'elles puissent tre
On peut quoiqu'il en soit crire notre classe de manire que les objets paraissent utilises en dehors du package, static pour souligner qu'il ne peut y en avoir qu'une
constants. Cette restriction inclut les tableaux, qui sont galement des objets. seulement, et final pour dire que c'est une constante. Notez que les primitives final
Voici un exemple qui montre les champs final: static avec des valeurs initiales constantes (ce sont des constantes la compilation)
sont nommes avec des lettre capitales par convention, avec des mots spars par
// ! c06:FinalData.java des underscores. Ce sont comme des constantes C, d'o cette convention est
// L'effet de final sur les champs.
class Value { originaire. Notons galement que i5 ne peut pas tre connu la compilation, donc
int i = 1; elle n'est pas en lettres capitales.
}
public class FinalData { Le fait que quelque chose soit final ne signifie pas que sa valeur est connue la
// Peut tre des constantes la compilation compilation. Ceci est montr par l'initialisation de i4 et i5 l'excution en utilisant
final int i1 = 9; des nombres gnrs alatoirement. La portion de cet exemple montre galement la
static final int VAL_TWO = 99; diffrence entre mettre une valeur final static ou non static. Cette diffrence n'est
// Constantes publiques typiques: visible que quand les valeurs sont initialises l'excution, tandis que les valeurs la
public static final int VAL_THREE = 39;
// Ne peuvent pas tre des constantes la compilation: compilation sont traites de mme par le compilateur. Et vraisemblablement
final int i4 = (int)(Math.random()*20); optimises la compilation. La diffrence est montre par la sortie d'une excution:
static final int i5 = (int)(Math.random()*20); fd1 : i4 = 15, i5 = 9
Value v1 = new Value(); Creating new FinalData
f