Java Pour Les Nuls, 4e Éd. (Barry BURD) [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

 

Java

 

4e édition  

  Barry Burd  

 

  Java pour les Nuls (4e édition)  

Titre de l’édition originale  : Beginning Programming with Java® For Dummies®, 5th Edition   Pour les Nuls est une marque déposée de Wiley Publishing, Inc. For Dummies est une marque déposée de Wiley Publishing, Inc.   Collection dirigée par Jean-Pierre Cano Traduction : Daniel Rougé Mise en page : maged   Edition française publiée en accord avec Wiley Publishing, Inc. © Éditions First, un département d’Édi8, 2019 Éditions First, un département d’Édi8 12 avenue d’Italie 75013 Paris Tél. : 01 44 16 09 00 Fax : 01 44 16 09 01 E-mail : [email protected] Web : www.editionsfirst.fr

  ISBN : 978-2-412-04663-0 ISBN numérique : 978-2-412-04983-9 Dépôt légal : 2e trimestre 2019

  Cette œuvre est protégée par le droit d’auteur et strictement réservée à l’usage privé du client. Toute reproduction ou diffusion au profit de tiers, à titre gratuit ou onéreux, de tout ou partie de cette œuvre est strictement interdite et constitue une contrefaçon prévue par les articles L 335-2 et suivants du Code de la propriété intellectuelle. L’éditeur se réserve le droit de poursuivre toute atteinte à ses droits de propriété intellectuelle devant les juridictions civiles ou pénales. Ce livre numérique a été converti initialement au format EPUB par Isako www.isako.com à partir de l'édition papier du même ouvrage.

Introduction Q uelle est votre histoire ? » Êtes-vous un travailleur acharné, intéressé à en apprendre toujours plus sur la manière dont les ordinateurs de votre entreprise fonctionnent ? » Êtes-vous un étudiant qui a besoin de faire d’autres lectures pour ne pas manquer son examen de premier cycle ? » Êtes-vous un utilisateur qui a déjà épuisé les joies du traitement de texte et qui voudrait faire quelque chose de plus intéressant avec son ordinateur ? » Êtes-vous à la recherche d’un emploi et avez-vous besoin d’améliorer votre CV en y ajoutant une ligne « expérience de programmation en Java » ?

Bien.

Si

vous

voulez

ou

devez

écrire

des

programmes informatiques, ce livre est fait pour vous. Loin des formules prétentieuses, il vous prend tel que vous êtes et il vous suivra jusqu’où vous voudrez bien aller.

À propos de ce livre Ce livre vous parle de Java, un langage de programmation puissant et très généraliste. Mais son objet n’est pas de vous faire entrer dans les arcanes,

les

subtilités

et

autres

excentricités

servant juste à essayer de briller dans les soirées mondaines. processus  :

Non. celui

Ce qui

livre

s’appuie

consiste

à

sur

un

créer

des

instructions qu’un ordinateur doit exécuter. Il existe de nombreux ouvrages qui décrivent les mécanismes de ce type de processus et qui alignent règles, conventions et formalismes divers et variés. Mais ces autres livres ne sont pas écrits pour les vraies gens. Ils ne vous prennent pas là où vous êtes pour vous amener là où vous voulez aller. Dans tout ce qui va suivre, je fais très peu de suppositions sur votre expérience dans le domaine des ordinateurs. En lisant chaque section, vous allez voir ce qui se passe dans ma tête. Vous

découvrirez les problèmes et leurs solutions en même temps que moi. Je me souviens avoir affronté certains de ces problèmes lorsque je débutais. Et d’autres continuent à me travailler maintenant que je suis devenu un expert (du moins, au dire de mes étudiants qui cherchent évidemment à se faire bien voir). Je vais vous aider à comprendre, à visualiser, et à créer vos propres solutions. Et je vous raconterai même quelques histoires au passage.

Comment utiliser ce livre J’aimerais pouvoir vous dire  : «  Ouvrez le livre au hasard et commencez à écrire du code Java. Contentez-vous de remplir les vides et ne regardez pas en arrière. » Dans un sens, c’est vrai. Vous ne pouvez rien endommager en écrivant du code Java, et vous avez donc à chaque instant une totale liberté pour tenter vos propres expériences. Mais je me dois d’être honnête avec vous. Si vous ne comprenez pas les idées générales, écrire un programme

est

difficile.

Et

c’est

vrai

pour

n’importe quel langage de programmation, pas simplement Java. Si vous tapez du code sans savoir exactement ce que vous faites, et si ce code ne se

comporte pas comme vous l’espériez, vous risquez fort de rester en panne sèche. C’est pourquoi j’ai divisé dans ce livre les notions que vous devez connaître en petites parties bien plus

gérables.

Chacune

de

ces

«  parties  »

correspond (plus ou moins) à un chapitre. Vous pouvez sauter là où vous vous voulez  –  au Chapitre 5, au Chapitre 10 ou ailleurs. Vous pouvez même commencer par le milieu d’un chapitre. J’ai essayé de vous proposer des exemples concrets, et si possible intéressants, sans que l’un d’entre eux ne vous oblige à avaler tout ce qui le précède. Et si je me sers d’une idée importante qui a été déjà développée ailleurs, je vous en préviens pour vous aider à la retrouver. Ma philosophie est somme toute plutôt simple : » Ne perdez pas votre temps à lire ou relire ce que vous savez déjà. » Si vous êtes du genre curieux, n’hésitez pas à foncer vers l’avant. Vous pourrez toujours reprendre un chapitre antérieur lorsque vous en aurez besoin. » Mais ne vous précipitez tout de même pas tout de suite sur la dernière page du livre : je n’y donne

pas le nom de l’assassin. C’est à vous d’écrire le programme qui vous le révélera…

Conventions utilisées dans ce livre Pratiquement n’importe quel ouvrage technique débute

par

quelques

explications

sur

les

conventions typographiques qu’il utilise. Celui-ci n’échappe donc pas à la règle, même si celle-ci est au final très simple : » Les nouveaux termes sont mis en italiques. » Si je veux que vous tapiez quelque chose de court, ou que vous exécutiez une certaine étape, je l’indique avec des caractères gras. » Pour bien distinguer le code Java, les noms de fichiers, les messages ou encore les adresses de pages Web, j’utilise cette police de caractères. C’est aussi le cas si je vous demande de taper quelque chose d’assez long. » Parfois, je vous indique que vous pouvez saisir un nom à votre convenance. Dans ce cas, j’utilise une expression générique, par exemple :

class Nomquelconque Ceci signifie que vous devriez taper le mot class, puis un nom que vous choisissez comme vous l’entendez.

Ce que vous n’avez pas à lire Prenez le premier chapitre ou la première section où vous trouverez des notions que vous ne connaissez pas encore, et commencez à lire. Bien entendu, il se peut que vous haïssiez ce genre de décision. Dans ce cas, suivez ces quelques conseils : » Si vous savez déjà ce que veut dire programmer sur un ordinateur, passez la première moitié du Chapitre 1. Aucun problème. » Si on vous impose un environnement de développement autre qu’Eclipse, vous pouvez passer le Chapitre 2. Ceci vaut si vous prévoyez d’utiliser NetBeans, IntelliJ IDEA, ou un autre environnement de développement. La plupart des exemples de ce livre réclament une version 5.0 ou plus de Java. De surcroît, certains exemples nécessitent en fait Java 7.0 ou plus.

Vérifiez que votre système utilise effectivement Java 7.0 ou plus. Si vous avez un doute à ce sujet, voire même une certaine liberté quant au choix de votre environnement de développement, je vous conseille vivement de vous rendre au Chapitre 3. » Si vous avez déjà quelques notions de programmation, vous pouvez survoler les Chapitres 6 à 8. Par contre, lisez attentivement le Chapitre 9. Si vous ne vous sentez pas très à l’aise avec ce qu’il vous explique, relisez les Chapitres 6, 7 et 8. » Si vous avez une solide expérience d’utilisation d’un langage de programmation autre que Java, il n’est pas certain que ce livre soit écrit pour vous. Conservez-le à des fins de référence, et voyez ce que les Éditions First vous proposent de plus avancé dans ce domaine. Il y a aussi les encadrés et les notes en marge. Si vous en avez envie, lisez-les. Sinon, vous pouvez également ranger ce livre sur un rayon de votre bibliothèque sans même l’ouvrir. Après tout, c’est votre problème, non ?

Quelques suppositions stupides

Dans ce livre, il faut bien que je fasse quelques suppositions sur vous, ami lecteur. Si une ou deux d’entre elles sont fausses, ce n’est pas bien grave. Et si j’ai faux partout… Bon. Achetez quand même ce livre. Vous me ferez plaisir. » Je suppose que vous avez accès à un ordinateur. Bonne nouvelle. Vous pouvez exécuter le code présenté dans ce livre sur pratiquement n’importe quel ordinateur. Enfin, sur une machine qui a moins de sept ou huit ans d’âge. Ou quelque chose de ce genre. Pour faire court, les dernières versions de Java fonctionnent sur pratiquement tous les ordinateurs sous Windows, Macintosh ou Linux. » Je suppose que vous savez naviguer dans les menus et les boîtes de dialogue les plus courants sur votre ordinateur. Vous n’avez pas besoin d’être un super utilisateur de Windows, Mac ou Linux. Par contre, vous devez savoir ce que veut dire exécuter un programme, placer un fichier dans un certain dossier, enfin ce genre de trucs. La plupart du temps, dans ce livre, je vous demanderai de taper quelque chose sur votre clavier, pas de pointer et de cliquer avec votre souris.

Dans de rares occasions, lorsqu’il faudra faire glisser et déposer, couper et coller, et ainsi de suite, je vous guiderai pour réaliser ces étapes. Mais il existe des milliards de manières de configurer un ordinateur, et je ne peux pas tout savoir sur tout. Si certaines étapes sont spécifiques à un ordinateur en particulier, lisez la description que je vous donne. Si cela n’est pas suffisant, consultez l’aide qui accompagne votre ordinateur ou allumez quelques rangées de bougies. » Je suppose que vous êtes capable de raisonner logiquement. Quand on veut écrire des programmes pour ordinateur, c’est un prérequis indispensable. Si vous pouvez raisonner logiquement, vous avez gagné. Et si vous croyez que vous n’en êtes pas capable, lisez ce qui va suivre. Vous allez être agréablement surpris de vos compétences. » Je suppose que vos connaissances sur la programmation des ordinateurs sont très limitées. Ce n’est pas un livre du genre « tout savoir pour tout le monde ». Je ne flatte pas plus le novice que je n’encense l’expert. Même si le premier (celui qui n’a jamais programmé ou qui ne

s’est jamais senti particulièrement à l’aise avec un ordinateur) est le premier visé. Cher novice, bienvenue. Et les autres aussi ! » Je suppose enfin que vous avez quelques connaissances en anglais. Oui, tous les langages de programmation sont basés sur des mots anglais. Comme les noms des classes ou des variables utilisés dans ce livre. Mais je ne vous demande pas de fournir une copie de vos diplômes de troisième cycle. Votre vocabulaire de base suffira certainement, et une traduction sera fournie lorsqu’elle sera nécessaire.

Comment ce livre est organisé Ce livre est découpé en chapitres, eux-mêmes partagés en sections, elles-mêmes découpées en sous-sections lorsque c’est nécessaire. Et mon tout est formé de cinq parties. Voyons cela de plus près.

Première partie : Programmer en Java, vos premiers pas Les chapitres de cette partie vous préparent à votre nouvelle expérience de programmeur Java. Vous

allez vous y familiariser avec les notions de programmation, et préparer votre ordinateur pour l’écriture

et

la

vérification

de

vos

futurs

programmes.

Deuxième partie : Écrire vos propres programmes Java Dans cette partie, vous allez découvrir les blocs de construction de vos programmes, autrement dit les éléments du langage Java, comme de tout langage comparable. Vous y apprendrez à présenter vos données, et à obtenir de nouvelles valeurs à partir de valeurs existantes. Les exemples de programmes proposés ici sont courts, mais sympathiques.

Troisième partie : Contrôler les flux Cette

partie

contient

quelques-uns

de

mes

chapitres préférés. Dans ces chapitres, vous faites naviguer votre ordinateur d’une partie de votre programme vers une autre. Imaginez que votre programme est comme un grand château, avec un ordinateur qui se déplace de pièce en pièce. Il doit parfois choisir le couloir qu’il doit prendre, ou

repasser dans une pièce qu’il a déjà visitée. En tant que programmeur, votre rôle consiste à planifier le trajet de l’ordinateur dans le château. Amusant, n’est-ce pas ?

Quatrième partie : Programmer par unités Vous avez certainement déjà eu à résoudre un gros problème en le décomposant en petites unités, plus faciles à gérer. C’est exactement ce que vous allez faire dans cette partie. Comme réinventer la roue n’est pas la tasse de thé des programmeurs, vous y verrez aussi comment utiliser des solutions déjà trouvées par d’autres personnes. Voilà qui pourrait ressembler à du vol, mais ce n’en est pas. Cette

partie

contient

également

un

chapitre

concernant la programmation de fenêtres, de boutons et autres objets graphiques. Si votre souris se sent délaissée par les exemples de ce livre, offrez-lui le Chapitre 20.

Cinquième partie : Les Dix Commandements

C’est la cerise sur le gâteau. Vous y trouverez des ressources utiles et des informations à creuser sur l’API de Java. J’ai

ajouté

un

article

(évidemment,

c’est

an

anglais  ! ) sur www.dummies.com pour vous aider à vous sentir à l’aise avec la documentation Java (à l’adresse

dont

la

version

raccourcie

est

https://bit.ly/2Py8iPf, pour être précis). Je ne peux

pas

écrire

de

programmes

sans

ma

documentation de programmation Java. En fait, aucun

programmeur

Java

ne

peut

écrire

des

programmes sans ces documents très importants. Ces documents se présentent sous forme de pages Web, ils sont donc faciles à trouver et faciles à naviguer. Si vous n’êtes pas habitué à toute cette terminologie, la documentation peut être écrasante. Courage et persévérance !

Icônes utilisées dans ce livre Si

vous

pouviez

me

voir

assis

devant

mon

ordinateur, en train d’écrire ce livre, vous seriez surpris de me voir parler autant. En fait, je me parle à moi-même en répétant chaque phrase à voix haute. Oui, je sais, c’est un peu bizarre. De temps en temps, j’ai un petit sursaut en me disant

que tel ou tel point, tel ou tel sujet, mérite une mention spéciale. Je hoche la tête, et j’ajoute une icône dans la marge. Bien entendu, vous ne me voyez pas hocher la tête. C’est pourquoi je vous signale tout de suite les icônes que vous allez retrouver dans ce livre : C’est une information supplémentaire, quelque chose d’utile que les autres livres pourraient oublier

de

vous

dire,

ou

encore

une

astuce

susceptible de vous faire gagner du temps. De temps à autre, il faut bien que j’attire votre attention sur un point dont vous devez absolument vous souvenir. Rassurez-vous, il n’y en a pas tant que

cela.

C’est

pourquoi

cette

icône

est

si

importante. Tout le monde fait des erreurs. Pour ma part, j’en ai fait des tas dans ma vie de programmeur. C’est pourquoi, quand je sais par expérience qu’une peau de banane pourrait bien se glisser sous les touches de votre clavier, je vous en préviens à l’avance avec cette icône. Il faut bien dans un livre comme celui-ci insérer quelques

explications

plutôt

techniques,

par

exemple pour vous aider à mieux comprendre ce

que les types qui ont développé Java avaient dans la tête. Vous n’êtes pas forcé de lire ces notes. Mais cela pourra vous servir un jour, disons si l’envie vous prenait de lire un autre ouvrage sur Java. Écrire du code informatique est une activité, et la meilleure façon d'apprendre une activité est de la pratiquer. C'est pourquoi j'ai créé des choses que vous

pouvez

essayer

afin

de

renforcer

vos

connaissances. Certaines sont des bâtisseurs de confiance, mais d’autres sont un peu plus difficiles. Lorsque vous commencerez à mettre les choses en pratique,

vous

découvrirez

toutes

sortes

de

problèmes, de dilemmes et d'obstacles qui ne vous sont pas venus à l'esprit lorsque vous avez commencé votre lecture sur ce sujet. Mais c'est une bonne chose. Continuez comme ça ! Ne soyez pas frustré(e).

Ou,

si

frustré(e),

visitez

vous le

devenez

site

Web

malgré

tout

de

livre

ce

(www.allmycode.com/BeginProg) pour des conseils et des solutions.

Et maintenant ? Il ne vous reste plus qu’à vous lancer dans le grand bain. Pendant quelques centaines de pages, je vais vous servir de guide, d’hôte ou encore d’assistant

(choisissez le mot que vous préférez). Je me suis efforcé en permanence de rendre les choses si possible

intéressantes,

ou

du

moins

compréhensibles. Bonne lecture, et surtout bonne programmation ! Au fait… Je me suis dit que vous n’aimeriez pas du tout retaper tous les programmes que je vous propose dans ce livre. J’ai donc décidé de faire preuve de bonne volonté en vous facilitant le travail. Vous pouvez donc télécharger ces programmes sur le site de l’éditeur. Le Chapitre 2 vous dit tout à ce sujet. Le

Chapitre  2  vous

dit

tout

au

sujet

du

téléchargement des programmes développés dans ce livre. Si vous ne lisez pas le paragraphe précédent, vous risquez de vous en mordre les doigts !

PARTIE 1 Programmer en Java, vos premiers pas DANS CETTE PARTIE… Se préparer à devenir un développeur Java Installer le logiciel Exécuter quelques exemples de programmes

Chapitre 1

Pour bien débuter DANS CE CHAPITRE : » Réaliser ce qu’est la programmation sur ordinateur » Comprendre le logiciel qui vous permet d’écrire des programmes » Se préparer à utiliser un environnement de développement intégré

P veut

rogrammer sur un ordinateur ? Qu’est-ce que ça dire  ? C’est un truc technique  ? C’est

dangereux ? Et pourquoi quelqu’un voudrait-il faire ce genre de chose ? Moi, vous croyez ? Est-ce que je peux apprendre à le faire ?

De quoi allons-nous parler ? Vous

avez

très

probablement

déjà

utilisé

un

ordinateur pour faire du traitement de texte. Par exemple pour taper une lettre, l’imprimer et l’envoyer à quelqu’un que vous aimez. Et si vous pouvez facilement accéder à un ordinateur, vous

avez tout aussi probablement surfé sur le Web. Vous savez donc comment visiter une page, cliquer sur un lien pour passer à une autre page, et ainsi de suite. Facile, non ? Mais pourquoi est-ce facile  ? Parce que quelqu’un d’autre que vous a indiqué à l’ordinateur ce qu’il devait

faire

exactement.

ordinateur

tout

fabrication

et

Si

vous

prenez

un

des

chaînes

de

juste

sorti

que

personne

ne

fournit

d’instructions à la machine, elle sera incapable de faire du traitement de texte, de surfer sur le Web, et tout le reste. Ce n’est qu’un objet inanimé dépourvu d’âme. Tout ce qu’un ordinateur est capable de faire, c’est de suivre les instructions que des types extrêmement compétents lui donnent (et je ne parle pas là de vous ni de moi). Imaginons maintenant que vous utilisiez Microsoft Word pour écrire le prochain Prix Goncourt. Vous arrivez à la fin d’une ligne (pas d’une phrase, juste d’une ligne). Vous continuez à saisir le prochain mot, et, instantanément, le curseur du traitement de texte passe automatiquement à la ligne suivante en affichant la suite de votre futur chef-d’œuvre. Que s’est-il donc passé ?

En fait, quelqu’un a écrit un programme d’ordinateur (ou un programme informatique, au choix), c’est-àdire

une

série

d’instructions

qui

explique

à

l’ordinateur comment il doit se comporter. Les gros programmes, on les appelle généralement des logiciels (les petits aussi, d’ailleurs). Mais il y a aussi un autre nom pour désigner un programme, ou simplement un morceau de programme : le code. Le Listing  1.1  vous montre à quoi peut ressembler un morceau du code qui permet à Microsoft Word de vous accompagner dans la rédaction de votre prochain roman. LISTING

1.1 Quelques lignes de code dans un

programme. if (columnNumber > 60) { wrapToNextLine(); } else { continueSameLine(); } En

programmation,

la

langue

de

base,

c’est

l’anglais. Impossible d’y échapper. Mais rassurezvous  : même si vous n’êtes pas capable de lire Shakespeare dans le texte, connaître un peu de vocabulaire anglo-saxon devrait suffire pour vous y

retrouver. Essayons de traduire ces quelques lignes de code dans un français plus à notre portée : Si le numéro de la colonne est plus grand que 60, alors passer à la ligne suivante. Sinon (donc si le numéro de la colonne courante dans le texte n’est pas plus grand que 60), alors continuer sur la même ligne. Eh oui, pour que votre texte se poursuive gentiment sur la ligne suivante, quelqu’un a écrit un code du même genre que celui montré sur le Listing 1.1. Et ce code, parmi des millions d’autres lignes de code, donne un programme, un logiciel, appelé Microsoft Word. Incroyable, n’est-ce pas ? Et pour surfer sur le Web  ? Vous cliquez par exemple sur un lien qui est censé vous amener directement sur le site de Microsoft. Derrière la scène, quelqu’un a écrit du code qui pourrait ressembler à cela : Visitez le site de Microsoft

En réalité, les types de chez Microsoft ont fait en sorte que cette ligne se traduise plutôt par ceci : https://www.microsoft.com/fr-fr/ Pourquoi  ? Tout simplement parce qu’ils sont tellement intelligents qu’ils savent que vous parlez français (d’où le /fr-fr/), et que, en plus, ils ont compris que vous vouliez naviguer d’une manière sécurisée (d’où également le https). En résumé, d’une manière ou d’une autre, un ordinateur ne sert à quelque chose que si quelqu’un a écrit un programme. Et ce quelqu’un est tout bêtement appelé un programmeur.

Expliquer à un ordinateur ce qu’il doit faire Tout ce que vous faites avec un ordinateur est basé sur de gigantesques quantités de code. Par exemple, un jeu n’est rien d’autre qu’un gros (en fait, très gros) tas de code. Quelque part dans ce code, il y a par exemple les lignes (ou instructions) suivantes : if (person.touches(goldenRing)) { person.getPoints(10); }

Essayons de réviser nos souvenirs d’anglais pour mieux comprendre ce qui se passe : Si le joueur (appelé person) touche l’anneau en or, alors il gagne 10 points. Sans aucun doute, une personne qui écrit des programmes a des compétences remarquables. En fait, les programmeurs doivent posséder deux qualités importantes : » Ils savent comment décomposer de grands problèmes en plus petites procédures fonctionnant étape par étape. » Ils peuvent transcrire ces étapes dans un langage très précis. Ce genre de langage est appelé un langage de programmation. Et Java fait justement partie de cette

grande

famille

des

langages

de

programmation. Ainsi, l’exemple du Listing  1.1  est écrit dans le langage de programmation Java (pour faire plus simple, nous dirons qu’il est écrit en Java).

Choisissez votre poison

Ce livre ne traite pas des différences entre les langages de programmation, mais vous devriez tout de même vous faire une petite idée de la manière dont se présente un code dans divers langages de manière à vous familiariser avec ce monde. Prenons comme exemple Visual Basic. Dans cet autre langage

de

programmation

classique,

notre

Listing 1.1 pourrait s’y écrire ainsi : If columnNumber > 60 Then Call wrapToNextLine Else Call continueSameLine End If Désolé, c’est tout aussi anglo-saxon que Java. Mais, encore une fois, vous n’y échapperez pas. Et que penser du même code, mais écrit cette fois dans le langage COBOL : IF COLUMN-NUMBER IS GREATER THAN 60 THEN PERFORM WRAP-TO-NEXT-LINE ELSE PERFORM CONTINUE-SAME-LINE END-IF. À l’autre bout du spectre, vous trouvez des langages comme le moins connu Forth. En voici un tout petit

aperçu : : WRAP? 60 > IF WRAP_TO_NEXT_LINE? ELSE CONTINUE_SAME_LINE? THEN ; Et voici le encore moins connu Haskel : median aList = [ x | x 60). Il suffit juste d’effectuer une substitution mentale pour passer d’un jeu de symboles à un autre. Et, au fil du

temps,

écrire

(columnNumber

quelque >

60)

chose

comme

if

devient

comme

une

seconde nature.

Le grand voyage de l’esprit Ce grand voyage, c’est celui qui conduit de votre cerveau

au

processeur

de

l’ordinateur.

Toute

création de programme part d’une pensée qui va se traduire au final par un code exécutable par un ordinateur. Cette démarche est un processus plus ou moins complexe, et qui comporte un nombre plus ou moins grand d’étapes. Au cours de ce processus,

trois

outils

importants

sont

indispensables : » Compilateur : son rôle est de traduire votre code, écrit dans un langage plus ou moins humain, en instructions compréhensibles par l’ordinateur (mais pas par vous ou moi). » Machine virtuelle : elle sert à exécuter les instructions produites par le compilateur. » API : cet acronyme signifie Application Programming Interface (interface de programmation d’application). Disons qu’il s’agit

de code déjà écrit et qui est bien utile pour vous éviter un tas de travail. Ces trois outils sont décrits plus en détail dans les sections qui suivent.

Traduire votre code Vous avez sans doute déjà entendu dire que les ordinateurs ne savent que calculer avec des zéros et des un. C’est vrai, mais qu’est-ce que cela signifie ? Disons que les circuits électroniques qui peuplent les ordinateurs ne connaissent rien aux lettres de l’alphabet. Si vous voyez par exemple le mot Start écrit sur l’écran de votre ordinateur, il est en fait enregistré mémoire

dans sous

un la

recoin

quelconque

forme  01010011

de

sa

01110100

01100001 01110010 01110100. Le fait que vous arriviez à lire un mot n’est rien d’autre que l’interprétation que vous faites des pixels qui sont affichés sur l’écran, et c’est tout. Les ordinateurs décomposent

absolument

tout

en

séquences

imbuvables de zéros et de un, puis ils remettent tout cela dans le bon ordre de manière à ce que les êtres humains que nous sommes puissent en tirer quelque chose.

Lorsque vous écrivez un programme d’ordinateur, ce programme doit donc à un moment ou à un autre être transcrit sous la forme de zéros et de un. Le nom officiel de cette traduction est compilation. Sans cette compilation, aucun ordinateur au monde ne pourrait exécuter votre programme. La bouillie compilée qu’illustre la Figure  1.1  peut prendre différents noms : » La plupart des programmeurs Java l’appellent bytecode. » Je l’appelle souvent un fichier .class. En effet, en Java, le bytecode est enregistré dans des fichiers d’extension .class (comme dans UneCertaineChose. class). » Pour mettre en évidence la différence, les programmes Java appellent ce que montre le Listing 1.1 du code source, et la suite de zéros et de un illustrée sur la Figure 1.1 du code objet.

FIGURE 1.1

Mon ordinateur comprend ces zéros et ces un, pas moi.

Pour visualiser les relations entre le code source et le code objet, regardez la Figure 1.2. Vous écrivez le code source, et vous demandez ensuite à ce qu’il soit

converti

en

code

objet.

Pour

y

arriver,

l’ordinateur se sert d’un logiciel spécial appelé un compilateur.

FIGURE 1.2 objet.

L’ordinateur compile le code source pour créer le code

Le disque dur de votre ordinateur peut contenir un fichier appelé javac

ou encore javac.exe. Ce

fichier, c’est justement ce logiciel spécial, le compilateur (d’où le c à la fin du nom). En tant que programmeur Java, vous allez souvent demander à votre ordinateur de fabriquer du nouveau code objet. L’ordinateur répond à votre souhait en toute discrétion (c’est-à-dire en travaillant en arrièreplan), et il exécute pour cela les instructions du fichier javac.

Exécuter du code Il y a plusieurs années de cela, j’ai passé une semaine à Copenhague. J’étais avec un ami qui parlait couramment l’anglais et le danois. Pendant que

nous

bavardions

dans

un

parc,

j’avais

vaguement remarqué que des gamins tournaient autour de nous. Comme je ne parle pas un mot de danois, je supposais qu’ils discutaient de choses de leur âge. Puis mon ami me dit que ces jeunes ne parlaient pas danois. En fait, ils prononçaient des syllabes sans

aucun

sens,

mais

qui

s’efforçaient

reproduire phonétiquement mes propres paroles.

de

Revenons au temps présent. Si je regarde à nouveau la Figure  1.1, je me rappelle ces enfants de Copenhague. Tous ces zéros et ces un ne veulent rien dire pour moi. Par contre, ils ont un sens précis pour mon ordinateur. Lorsque ces chiffres traversent les circuits électroniques de l’ordinateur, celui-ci «  pense  » comme sur l’illustration de la Figure 1.3 (enfin, c’est ce que je crois).

FIGURE 1.3

Ce que l’ordinateur glane à partir d’un fichier de bytecode.

Tout le monde sait bien qu’un ordinateur ne pense pas… Par contre, il est capable de déchiffrer les

instructions de la Figure  1.3. Avec la plupart des langages de programmation (comme le C++ ou le COBOL,

par

exemple),

les

choses

se

passent

exactement comme je les décris ici. Un ordinateur engloutit un grand plat de code objet, et il exécute ce que ce code objet lui dit de faire. Par contre, en Java, la démarche se présente différemment (même si le résultat est identique). Elle est illustrée sur la Figure 1.4. Les instructions de la Figure  1.4  indiquent à l’ordinateur comment il doit suivre les autres instructions. Au lieu de commencer par quelque chose comme Get columnNumber from memory, la première instruction donnée à l’ordinateur est «  Fais ce qu’il est spécifié dans le fichier de bytecode  » (bien entendu, dans le fichier de bytecode, la première instruction est justement Get columnNumber from memory). Là encore, c’est un logiciel spécial qui se charge d’exécuter les instructions de la Figure  1.4. Ce logiciel spécial est appelé JVM (pour Java Virtual Machine, ou Machine Virtuelle Java). Lorsque vous exécutez un programme Java, votre ordinateur lance en fait ce JVM. C’est lui qui examine votre

bytecode, zéro après zéro, un après un, et exécute les instructions qu’il y trouve.

FIGURE 1.4

Comment un ordinateur exécute un programme Java.

On pourrait trouver des métaphores variées pour caractériser

la

machine

virtuelle

Java 

:

intermédiaire, fille errante, ou tout ce que vous pouvez imaginer d’autre. Dans tous les cas, vous vous trouvez dans la situation illustrée sur la Figure  1.5. Le côté (a) représente ce qui se passe avec la plupart des langages de programmation  : l’ordinateur exécute un certain code objet. Le côté

(b) illustre l’histoire vue par Java  : l’ordinateur lance le JVM, et c’est celui-ci qui exécute les instructions du bytecode.

FIGURE 1.5

Deux manières d’exécuter un programme informatique.

Sur votre ordinateur, vous devriez trouver deux fichiers, l’un appelé javac et l’autre java (ou encore

javac.exe

et

java.exe).

Le

second

contient les instructions illustrées plus haut sur la Figure 1.4, autrement dit c’est la machine virtuelle Java. En tant que programmeur Java, vous allez souvent demander à votre ordinateur d’exécuter un programme Java. L’ordinateur exauce votre souhait en lançant les instructions contenues dans le fichier java.

C’EST QUOI FINALEMENT, LE BYTECODE ? Regardez le Listing 1.1, et sa traduction en bytecode illustrée sur la Figure  1.1. Vous pourriez être tenté de penser qu’un fichier de bytecode est juste un cryptogramme dans lequel les lettres, les mots et les chiffres du listing sont remplacés par des zéros et des uns. Mais c’est totalement faux. La partie la plus importante du bytecode est l’encodage de la logique du programme. Tous ces zéros et ces un décrivent le flux des données entre deux parties de votre ordinateur. La figure qui suit illustre ce flux. Mais ce n’est évidemment qu’une image à l’usage des humains. Votre ordinateur ne se sert pas de cette image pour faire son travail, ni même d’ailleurs de rien de semblable. Il lit de longues séries de zéros et de un pour décider ce qui va se passer ensuite. Point. N’essayez pas d’absorber les détails de ce que j’ai tenté de représenter sur la figure. Cela n’en vaudrait pas le temps que vous y passeriez. Tout ce que vous devez retenir, c’est que le bytecode (le contenu du fichier .class) contient une description complète des opérations que l’ordinateur doit effectuer. Lorsque vous écrivez un programme informatique, votre code source décrit une stratégie globale. Et le bytecode compilé transforme cette stratégie globale en des centaines et des centaines de petits détails qui permettent de

l’exécuter pas à pas. Lorsque l’ordinateur «  exécute votre programme », il examine en réalité ce bytecode et il exécute chacun de ces petits détails les uns après les autres.

ÉCRIRE UNE FOIS, EXÉCUTER PARTOUT Lorsque Java est apparu sur la scène techno (je parle de technologie, pas de musique, bien sûr), en 1995, ce langage est devenu presque immédiatement populaire. Ce succès était en partie dû à la présence de la machine virtuelle Java, le fameux JVM. Le JVM, c’est un peu comme un interprète (là encore, je ne parle pas de musique, mais de la personne qui vous aide à vous faire comprendre dans un pays étranger). Il transforme le bytecode Java en une sorte de langue indigène qu’un ordinateur particulier est capable de comprendre. Si, par exemple, je lance sur mon ordinateur sous Windows un fichier de bytecode Java, le JVM interprète son contenu en fonction de cet environnement. Et si je donne ce même fichier de bytecode Java à un collègue qui travaille sur un Mac, son propre JVM interprétera ce code pour cet autre environnement. Regardez à nouveau la Figure  1.5. Sans cette machine virtuelle, il faudrait un type différent de code objet pour chaque système d’exploitation. Avec le JVM, le même bytecode Java fonctionne aussi bien sous Windows ou sous Unix que sur un Mac, etc. Cela s’appelle de la portabilité, chose extrêmement précieuse dans le monde de la programmation. Songez à tous les gens qui se servent d’un ordinateur pour naviguer sur Internet. Ils n’utilisent pas tous

Microsoft Windows, mais tous ont sans même le savoir leur propre interpréteur de bytecode Java, et donc leur propre JVM. Les types chargés du marketing chez Oracle emploient une formule du genre « Écrire une fois, exécuter partout ». Pour moi, c’est d’abord une excellente manière de créer des programmes, des applications ou des logiciels (c’est au choix).

Du code réutilisable Autrefois, de nombreux programmeurs passaient le plus clair de leur temps à réécrire sans cesse pratiquement le même code, sans cesse, sans cesse et sans cesse. Le mari de ma cousine, Chris, travaillait dans les années  1980  pour une société qui produisait du logiciel à façon. Il m’a raconté des tas de fois l’histoire  : «  J’ai commencé par écrire un programme de recherche et de remplacement. Ensuite, j’ai écrit un correcteur orthographique. Et puis un autre programme de recherche et de remplacement.

Et

puis

un

correcteur

orthographique différent. Après, j’ai développé un programme de recherche et de remplacement plus performant. Et ainsi de suite. »

Comment Chris pouvait-il continuer à s’intéresser à son travail, alors qu’il devait réinventer la roue pratiquement chaque mois  ? Cette façon de faire était inefficace. Pire, terriblement ennuyeuse. Pendant

des

années,

les

professionnels

de

l’informatique sont partis à la quête du Saint Graal, une manière d’écrire du code qui serait facile à réutiliser.

Ne

plus

écrire

et

réécrire

des

programmes de recherche et de remplacement. Juste partager le travail en tâches simples. Une s’occuperait de rechercher un seul caractère, une autre se chargerait des espaces, tandis qu’une troisième remplacerait une lettre par une autre… Une fois toutes les pièces construites, il suffirait de les assembler pour construire le programme de recherche et de remplacement voulu. Le jour où votre traitement de texte aurait besoin d’une nouvelle fonctionnalité, il suffirait d’ajouter une pièce, puis de réassembler le tout d’une manière légèrement différente. Voilà une façon de faire plus efficace, bien moins coûteuse, et aussi bien plus amusante. Dès la fin des années  1980  et au début des années 1990, le développement logiciel a connu des avancées

sensibles,

et

de

nombreux

projets

importants ont été écrits à partir de composants préfabriqués. Java est arrivé en  1995, et il était naturel

pour

ses

concepteurs

de

créer

une

bibliothèque de code réutilisable. Cette bibliothèque contenait environ 250 programmes, avec y compris du code pour gérer les fichiers sur les disques, du code pour créer des fenêtres, ou encore du code pour transférer des informations sur Internet. Depuis cette époque, la bibliothèque de Java a pris de l’ampleur pour inclure de nos jours largement plus de  4  000  programmes. Cette bibliothèque est appelée API (pour Application Programming Interface, ou interface de programmation d’application). Chaque programme Java, même le plus petit, repose sur du code qui se trouve dans cette API. Celle-ci est à la fois utile et formidable. Elle est utile parce qu’elle vous permet de faire des tas et des tas de choses. Elle est formidable parce qu’elle est extrêmement extensible. Personne ne s’amuse à mémoriser toutes les fonctions qui sont disponibles grâce à l’API Java. Les programmeurs retiennent seulement ce qu’ils utilisent couramment, et ils font des recherches pour trouver des informations selon leurs besoins du moment. Ces informations sont disponibles dans une documentation en ligne

appelée API spécification (mais les programmeurs préfèrent utiliser le mot Javadoc). Cette documentation est écrite en anglais, et vous la

trouvez

via

l’adresse

Internet

http://docs.oracle.com/javase/9/docs/api/. Elle décrit les milliers de fonctions de l’API Java. En tant que programmeur Java, sachez que vous allez certainement la consulter chaque jour. Vous pouvez enregistrer les pages qui vous sont les plus utiles dans vos favoris, et même télécharger le tout en visitant

la

page

http://www.oracle.com/technetwork/java/java se/downloads/index.html (nous reviendrons plu loin sur les versions de Java SE).

La boîte à outils du programmeur Java Pour écrire des programmes Java, vous avez besoin des outils décrits dans les sections qui précèdent : » Un compilateur Java (voir la section « Traduire votre code »). » Une machine virtuelle Java (voir la section « Exécuter du code »).

» L’API Java (voir la section « Du code réutilisable »). » Un accès à la documentation de l’API Java (voyez également la section « Du code réutilisable »). Il vous faut également quelques outils moins exotiques : » Un éditeur pour composer vos programmes Java. Le Listing 1.1 montre un morceau de programme Java pour ordinateur. Pour ce qui vous concerne directement, un tel programme se présente finalement sous la forme d’un texte plus ou moins copieux. Pour l’écrire, vous avez besoin d’un éditeur, autrement dit d’un outil servant à créer des documents de type texte. Un éditeur, c’est un peu comme un traitement de texte, disons Microsoft Word pour fixer les esprits. Mais la grande différence est qu’un tel éditeur de code n’ajoute aucun formatage à votre texte : ici, pas de caractères gras, pas d’italiques, pas de polices décoratives, et ainsi de suite. Rien de tout cela. Un programme, c’est du texte pur, des chiffres, et des caractères particuliers disponibles sur votre clavier.

Lorsque vous éditez un programme, il se peut que vous voyiez du texte en gras, du texte en italique, ou encore du texte affiché dans différentes couleurs. Mais ce n’est pas du formatage. Cela signifie simplement que votre éditeur reconnaît le langage Java et qu’il met en évidence (ou en surbrillance) les mots de ce langage. Croyez-moi, c’est une aide précieuse pour éviter ou corriger bien des erreurs de saisie. » Vous avez besoin d’une méthode pour exécuter des commandes. Il faut évidemment que vous soyez à même de dire des choses comme « compile ce programme » et « exécute le JVM ». D’accord, il est possible d’y arriver en faisant un double clic sur une icône ou en tapant une certaine commande dans une boîte de dialogue du genre Exécuter. Mais, avec nos ordinateurs modernes, vous avez l’habitude de passer d’une fenêtre à une autre. Vous ouvrez une fenêtre pour consulter la documentation de Java, une autre pour éditer votre programme, et une troisième encore pour exécuter le compilateur Java. Ce processus peut être assez délicat.

Un outil pour créer du code

Dans le meilleur des mondes possibles, tout cela devrait se passer au sein d’une seule et même fenêtre. Ce genre d’interface existe évidemment. On l’appelle un environnement de développement intégré (ou IDE, pour Integrated Development Environment). Un

environnement

de

développement

intégré

typique divise votre écran de travail en plusieurs volets, ou panneaux. Il y en a un pour éditer les programmes, un autre servant à lister les noms de ces programmes, et d’autres encore pour vous aider à composer et tester vos programmes. Et vous pouvez redisposer tout cela à votre guise selon vos propres méthodes de travail. Mieux encore, si vous changez quelque chose dans un volet, tous les autres sont automatiquement mis à jour. Un tel environnement vous aide à passer plus facilement d’une tâche à une autre. De plus, vous n’avez pas à basculer en permanence entre édition, compilation et exécution. C’est un souci de moins. De cette manière, vous pouvez plus facilement vous concentrer sur l’essentiel, c’est-à-dire sur la logique de vos programmes (d’accord, c’est un autre genre de souci). Dans les chapitres qui suivent, je décris les fonctionnalités de base de l’IDE d’Eclipse. Eclipse a

beaucoup de « cloches et de sifflets » , mais vous pouvez ignorer la plupart d’entre eux et apprendre à

répéter

quelques

séquences

de

routines

classiques. Après avoir utilisé Eclipse plusieurs fois, votre cerveau finira par exécuter automatiquement ces étapes de routine. Dès lors, vous pouvez arrêter de vous soucier d’Eclipse et vous concentrer sur la programmation Java. En lisant ce qui va suivre, souvenez-vous que Java et Eclipse ne sont pas liés l’un à l’autre. Les programmes

de

ce

livre

fonctionnent

avec

n’importe quel IDE capable d’exécuter Java. Au lieu de faire appel à Eclipse, vous pouvez utiliser IntelliJ IDEA, NetBeans, BlueJ, ou tout autre IDE Java. En fait,

vous

pourriez

écrire

et

exécuter

les

programmes de ce livre sans aucun IDE. Autrement dit, vous pouvez parfaitement utiliser Notepad, TextEdit ou autre, qu’il s’agisse de l’invite de commande de votre système d’exploitation ou de Terminal. C’est à vous de voir.

C’était déjà sur votre disque dur ?

Il est très possible que vous ayez déjà sur votre ordinateur certains outils utiles à la création de programmes Java. Mais il est aussi possible que ceux-ci soient obsolètes. La plupart des exemples de ce livre fonctionnent avec toutes les versions de Java. Mais certains réclament au moins la version 5. Et d’autres aussi ne s’exécuteront qu’en présence de Java 6, Java 7, Java 8 voire plus. Le mieux à faire, c’est de télécharger les outils les plus

récents

sur

le

site

Web

d’Oracle.

Le

Chapitre 2 explique tout cela en détail.

Eclipse Jy reviens, mais c’est bien sûr volontairement. Les programmes

de

ce

livre

fonctionnent

avec

n’importe quel environnement de développement intégré compatible avec Java. Il peut par exemple s’agir de NetBeans, IntelliJ IDEA, JDeveloper, JCreator, et ainsi de suite. Vous pouvez même exécuter ces programmes sans aucun IDE. Mais, pour illustrer mon propos, j’ai choisi le logiciel Eclipse, et cela pour plusieurs raisons : » Eclipse est gratuit.

» Parmi tous les environnements de développement intégrés dédiés à Java, Eclipse est celui qui est le plus couramment utilisé par les programmeurs professionnels. » Eclipse a de nombreuses fonctionnalités, mais vous pouvez parfaitement ignorer la plupart d’entre elles pour apprendre à composer et exécuter des séquences d’instructions simples. Lorsque vous aurez travaillé plusieurs fois avec Eclipse, votre cerveau sera capable de dérouler automatiquement ces séquences. Vous pourrez alors arrêter de paniquer devant Eclipse pour vous concentrer sur la programmation en Java. » Eclipse est gratuit (je me répète, mais c’est volontaire). En fait, vous avez parfaitement le droit de contribuer au projet Eclipse afin de le soutenir financièrement. Ce n’est évidemment pas obligatoire, mais c’est moralement une bonne idée.

Chapitre 2

Configurer votre ordinateur DANS CE CHAPITRE : » Installer Java » Télécharger et installer l’environnement de développement intégré Eclipse » Vérifier votre configuration Eclipse » Récupérer le code pour les exemples du livre

chapitre est beaucoup plus détaillé que ce dont C evous avez normalement besoin. Si vous êtes comme la plupart des lecteurs, vous suivrez les étapes de la section «  Si vous n’aimez pas lire les instructions…  » . Ensuite, vous passerez à la section « Importer les exemples de ce livre » , vers la fin de ce chapitre. Avec environ vingt pour cent du contenu de ce chapitre, vous aurez cent pour cent des logiciels requis. Bien sûr, il y a toujours des problèmes. Une personne a un ordinateur plus ancien. Une autre

personne a des logiciels qui rentrent en conflit. Jean a un PC et Jeanne a un Mac. Le PC de Jean fonctionne sous Windows  10, mais Gilles est sous Windows 8. Jean lit mal une de mes instructions et, par conséquent, rien sur son écran ne correspond aux étapes que je décris. Quatre-vingts pour cent de ce chapitre décrit ce que vous faites dans les rares situations



vous

devez

diagnostiquer

un

problème. Si rien ne va, vous pouvez toujours m’envoyer un mail à l’adresse BeginProg@ allmycode.com. Mais merci de ne pas en abuser, et de m’écrire uniquement en anglais (je répondrai de même). Molière et moi ne sommes pas de francs amis ! Donc, sautez tout ce que vous n’avez pas besoin de lire dans ce chapitre. Vous ne casserez rien en suivant votre instinct. Et si vous cassez quand même quelque chose, il y aura toujours un moyen de le réparer.

Si vous n’aimez pas lire les instructions… Pour commencer à écrire des programmes Java, vous avez besoin du logiciel que je décris au

Chapitre  1  : un compilateur Java et une machine virtuelle Java (JVM, en abrégé). Vous pouvez également

utiliser

un

bon

environnement

de

développement intégré (IDE) et du code exemple pour vous lancer dans le grand bain. Tous les logiciels dont vous avez besoin pour écrire des programmes Java sont gratuits. Tout cela se présente sous la forme de trois téléchargements  : un à partir du site Web de ce livre, un autre d’Oracle et un troisième d’eclipse.org. Voyons donc comment charger tout ce dont vous avez besoin pour créer des programmes Java : 1. Visitez la page http://www.pourlesnuls.fr/, accédez à la fiche du livre et téléchargez le fichier qui contient tous les exemples de ce livre. Ndt : Une autre possibilité consiste à télécharger tout le code source directement sur le site de l’auteur à l’adresse https://users.drew.edu/bburd/BeginProg/ index.html en cliquant sur le lien Download the code. Bien entendu, les textes des messages contenus dans le code ne seront dans ce cas pas localisés.

2. Visitez ensuite le site http://www.oracle.com/technetwork/java/ javase/downloads/index.html pour obtenir la dernière version disponible du JDK (autrement dit, le Java Development Kit). Acceptez la nouvelle licence d’utilisation d’Oracle (tant que vous ne faites pas du développement professionnel, il n’y a aucun souci de ce côté), et choisissez une version adaptée à votre système d’exploitation (Windows, Macintosh ou autre). Vous avez également le choix entre une version directement exécutable ou bien compressée (voir la Figure 2.1). Chacun peut avoir ses préférences… À ce jour, la dernière version en date publiée par Oracle est le JDK 12. Cette version apporte des nouveautés, comme les expressions switch, qui sont clairement hors du champ couvert par ce livre. Nous nous en tiendrons dans tout ce qui suit à notre objectif de base : apprendre à programmer en Java.

FIGURE 2.1

Choisir la version du JDK à installer.

Si vous êtes pressé (et qui ne l’est pas ?), songez à vous rendre sur le site http://java.com (il a l’avantage de se présenter en français). Il offre une procédure d’installation rapide : vous ne pouvez pas manquer le bouton de téléchargement. Ce bouton ne marche pas sur tous les ordinateurs. Mais si vous avez un peu de chance, et si les dieux informatiques sont avec vous, votre bonheur devrait être assuré. Par contre, vérifiez quelle version de Java vous est proposée : il est possible que ce site ait un peu de retard sur les derniers événements en s’en tenant à Java 8. Cela ne devrait cependant pas poser de problèmes majeurs avec la plupart des exemples développés dans ce livre. 3. Une fois le fichier voulu téléchargé, localisez-le sur votre système et faites un double clic sur

son icône pour procéder à l’installation de Java. 4. Visitez maintenant le site http://eclipse.org/downloads pour télécharger le logiciel Eclipse. La plupart du temps, le site Web d’Eclipse vérifie automatiquement le système d’exploitation de votre ordinateur et vous offre un téléchargement optimisé pour votre système. Le téléchargement résultant est normalement un fichier d’installation exécutable. 5. Une fois le fichier voulu téléchargé, localisez-le sur votre système et faites un double clic sur son icône pour procéder à l’installation d’Eclipse. Si le programme d’installation d’Eclipse appelle à l’aide au sujet d’une machine virtuelle Java, acceptez et naviguez jusqu’au sous-dossier bin du dossier d’installation du JDK afin d’y localiser le fichier javaw.exe. Parmi les choix proposés dans l’interface de l’installation, sélectionnez comme il se doit Eclipse IDE for Java Developers. Le plus simple est ensuite d’accepter les propositions par défaut. Cliquez sur

Install, acceptez les termes de la licence utilisateur et attendez la suite des événements. Sous Windows, l’espace qui se trouve par exemple au milieu de Program Files (le vrai nom de Programmes) peut tromper certains programmes Java. Je ne pense pas que les exemples de ce livre en soient perturbés, mais je ne peux pas vous le garantir. En cas de doute, vous pouvez toujours installer Eclipse dans un dossier dont le nom soit aussi simple que possible (par exemple c : \eclipse sous Windows). 6. Lancez Eclipse et acceptez l’espace de travail proposé par défaut (C:\ Users\votre_nom\eclipse_workspace). Si ce nom a déjà été utilisé par une autre application, ou par une ancienne version d’Eclipse, changez-le de manière à créer un nouveau dossier vierge. Vous voyez apparaître l’écran de bienvenue d’Eclipse. Cliquez sur l’icône qui indique Workbench dans l’écran d’accueil.

CES SATANÉES EXTENSIONS DE FICHIERS Les noms de fichiers affichés dans l’Explorateur Windows ou dans une fenêtre Finder peuvent vous désorienter. Dans un dossier, vous voyez par exemple apparaître le mot Amortissement. Mais le vrai nom de ce fichier pourrait être Amortissement.java,

Amortissement.class,

Amortissement.autreChose, ou même tout simplement Amortissement. L’expression qui suit le point dans le nom d’un fichier, par exemple .zip, .java et .class, est son extension. L’ennui, c’est que Windows comme Mac OS X masquent par défaut ces extensions, ce qui a tendance à rendre les choses plutôt confuses. Je vous conseille donc vivement de révéler ces extensions. » Dans Windows, vous pouvez par exemple ouvrir un dossier quelconque dans l’Explorateur (une autre possibilité consiste à passer par la combinaison touche Windows+Q, puis à taper comme critère de recherche Options des dossiers). Ouvrez la boîte de dialogue Options des dossiers (via Affichage puis Options), et activez l’onglet Affichage. Faites défiler les options pour localiser la ligne qui indique  : Masquer les extensions des fichiers dont le type est connu. Décochez-la. Cliquez

sur OK pour confirmer. Refermez éventuellement la fenêtre du dossier. » Sous Mac OS X, sélectionnez Préférences dans le Finder. Choisissez ensuite l’onglet Avancé et cochez si nécessaire la case de l’option qui indique Afficher toutes les extensions de fichiers. » Le cas de Linux est un peu différent, puisque la plupart des distributions ne masquent pas les extensions des fichiers.

Vérifiez

le

cas

échéant

ce

que

dit

la

documentation de votre propre distribution. 7. Dans Eclipse, importez le code que vous aurez téléchargé lors de l’Étape 1. Pour plus de détails sur la suite des événements, reportez-vous aux sections qui suivent.

Télécharger les exemples de programmes de ce livre Pour récupérer les exemples de ce livre, rendezvous sur le site http://www.pourlesnuls.fr/. Descendez en bas de la page et cliquez sur le lien Téléchargement.

Sélectionnez

dans

la

liste

la

collection Pour les Nuls GF informatique. Il ne vous

reste plus qu’à localiser ce livre, cliquer sur son image, puis sur le fichier Java2019.zip pour le télécharger.

UNE AFFAIRE D’ARCHIVES Lorsque vous téléchargez les exemples de ce livre, le fichier que vous récupérez possède l’extension .zip. C’est ce que l’on appelle une archive, ou encore un fichier compressé. Il contient en l’occurrence une série de dossiers, appelés par exemple 06-01, 06-02 et ainsi de suite. À leur tour, ces dossiers contiennent des sous-dossiers correspondant à un certain

projet

de

programme.

Ainsi,

le

dossier  06-

02 regroupe tout le code utile au développement du second programme proposé dans le Chapitre 6. Le format Zip n’est pas le seul dans son genre. Certaines archives ont pour extension .tar.gz, .rar ou encore .cab. Décompresser, ou décompacter, une archive signifie extraire les fichiers qu’elle contient. Normalement, cette procédure recrée la structure des dossiers et sous-dossiers enregistrés dans l’archive. Une fois décompressés les programmes de ce livre, vous allez donc vous retrouver avec un dossier principal plein de sous-dossiers et de fichiers. Si vous ouvrez par exemple le dossier appelé  06-02, vous y trouverez les sous-dossiers src et bin, qui à leur tour contiennent

des

fichiers

dénommés

VersatileSnitSoft.java, VersatileSnitSoft.class, etc.

Si votre navigateur ne se charge pas automatiquement de cette décompression, vous pourrez voir le contenu de l’archive en faisant un double clic sur l’icône du fichier .zip. Mais, en réalité, il n’est même pas indispensable de se préoccuper de ces détails plus ou moins techniques. En suivant les instructions données dans ce chapitre, vous constaterez qu’il est possible d’importer directement le fichier .zip dans Eclipse, et que c’est lui qui va se charger de décompresser les fichiers et de les placer au bon endroit. Si votre navigateur ne vous propose pas de télécharger le fichier lorsque vous cliquez dessus, ne vous affolez pas. Faites un clic droit (ou un Ctrl+clic sur un Mac). Un menu contextuel va s’ouvrir. Choisissez l’option de téléchargement qui est proposée par votre navigateur. Comme cela a été mentionné plus haut, vous pouvez

également

partir

de

la

source

en

téléchargeant les exemples de code depuis l’adresse https://users.drew.edu/bburd/BeginProg/index.htm l. Normalement, le fichier devrait être placé par défaut dans un dossier appelé Téléchargements, ou encore Downloads. Si votre configuration est différente, ou si vous avez choisi un autre dossier

au moment de lancer le téléchargement, notez soigneusement cet emplacement pour le retrouver rapidement plus tard.

Configurer Java Les dernières versions de Java sont disponibles sur le site d’Oracle, à l’adresse : http://www.oracle.com/technetwork/java/ja vase/downloads/index.html Recherchez la dernière version en date du JDK. Sélectionnez

la

version

qui

convient

à

votre

système d’exploitation. Sur la Figure  2.2, il s’agit de la version 12 de Java. Si vous aviez installé il y a quelque temps de cela Java  8, ou encore Java  9, sachez que vous avez parfaitement le droit de vous dispenser de ces étapes. En effet, les exemples de ce livre sont compatibles avec Java 8. Si vous avez du mal à identifier la bonne version, ou si vous voulez en savoir plus sur la signification des acronymes JRE et JDK, voyez l’encadré « C’est quoi ça ? » .

Une fois que vous avez cliqué sur le bon lien et accepté le contrat de licence, votre ordinateur devrait soit : » Télécharger et installer Java sur votre système. » Télécharger le fichier d’installation de Java et sauvegarder les fichiers sur votre ordinateur.

FIGURE 2.2

Télécharger le JDK.

Si l’installation commence toute seule, suivez les instructions qui vous sont données en répondant par Oui ou OK à tous les messages (à moins d’avoir d’excellentes raisons de faire autre chose). Sinon,

lancez cette installation en faisant un double clic sur l’icône du fichier d’installation. Si vous êtes sous Linux, le fichier à télécharger devrait être une archive de type .tar.gz. Procédez à son extraction dans un dossier de votre choix et suivez les instructions d’installation données sur le site Web d’Oracle. Pour plus d’informations sur les noms et les types de fichiers, ainsi que sur les archives, revoyez les encadrés « Ces satanées extensions de fichiers » et «  Une affaire d’archives  » , plus haut dans ce chapitre. Tant que vous vous trouvez encore sur le site Web http://www.oracle.com/technetwork/java/java se/downloads/index.html,

vous

pouvez

aussi

télécharger une copie de la documentation de l’API Java. Recherchez dans les téléchargements un nom du genre Java SE Development Kit (ou quelque chose du même genre). Acceptez le contrat de licence pour procéder au téléchargement. Le fichier est également une archive au format Zip, que vous décompacterez

ensuite

normalement.

Vous

obtiendrez alors des hordes de pages Web. Pour commencer à naviguer dans la documentation, recherchez à la racine du dossier un fichier appelé

index

ou index.

html. Faites un double clic

dessus pour commencer votre lecture.

C’EST QUOI ÇA ? La page de téléchargement de l’édition standard de Java comporte de nombreuses options. Si vous n’êtes pas familier avec elles, il y a effectivement de quoi être intimidé. Voyons donc cela d’un peu plus près : » 32 ou 64 bits ? Pour la plupart des systèmes d’exploitation, vous avez le choix entre deux versions  : 32  bits (x86) ou  64  bits (x64). Si vous ne savez pas laquelle choisir, commencez par essayer la version 32 bits. Pour plus d’informations à ce sujet, reportez-vous à l’encadré « Mon ordinateur, il a combien de bits ? ». » Numéro de version de Java La page de téléchargement de Java peut proposer plusieurs versions. En cas de doute, contentez-vous de télécharger la dernière version en date. La plupart des exemples de ce livre peuvent ainsi se contenter d’une installation Java  5. Mais certains nécessitent au moins Java 8. La manière dont les versions successives de Java sont numérotées peut prêter à confusion. Sans entrer dans des détails que vous aurez immédiatement oubliés, il est amusant de noter que le nom officiel formel de la

version 1.5 était « Java 2 Platform, Standard Edition 6 ». Il y a effectivement de quoi s’y perdre ! Heureusement, depuis la version  6  de Java, les appellations sont plus cohérentes. Par exemple, la version  12  est dénommée «  Java Platform, Standard Edition 12 », laquelle se décline au fil de ses évolutions avec un suffixe du genre  12.0.1, autrement dit version 12 mise à jour 0.1. » JDK ou JRE ? Pour certaines versions (disons jusqu’à la 8), la page principale du téléchargement vous propose deux variantes  : JDK (Java Development Kit) et JRE (Java Runtime Environment). Sachez que le JDK est plus complet que le JRE. Ce dernier contient une machine virtuelle Java (JVM) et l’interface de programmation d’application (API). Revoyez à ce sujet le Chapitre  1. Le JDK contient la même chose, plus un compilateur Java (à nouveau, reportez-vous au Chapitre  1). De tout manière, ne vous posez même pas la question  : c’est JDK, et rien d’autre. En passant, un autre nom du JDK est Java SDK (Java Software Development Kit). Si vous avez l’occasion de rencontrer cette dénomination, vous saurez de quoi il retourne.

» Java SE, Java EE ou bien Java ME ? Si vous regardez le bandeau affiché sur la gauche de la page de téléchargement de Java, vous allez voir des liens qui indiquent Java EE et Java ME. Si vous savez de quoi il s’agit, et si vous savez aussi que vous allez en avoir besoin, téléchargez ces versions. Si vous n’êtes pas sûr de vous, contentez-vous de Java SE (pour Standard Edition). L’abréviation Java EE signifie Java Enterprise Edition, plus spécifiquement dédiée aux grandes entreprises. Le ME de Java ME veut dire Micro Edition. Elle contient du logiciel destiné à la création de programmes pour les appareils

portables

(Android

de

Google

a

une

ressemblance plus ou moins lointaine avec Java ME, mais, par de multiples aspects, Android et Java ME sont des animaux très différents). Vous n’avez besoin ni de Java EE ni de Java ME pour exécuter tous les exemples de ce livre. » Logiciel complémentaire Vous pouvez télécharger Java seul, ou avec en supplément l’environnement de développement intégré d’Oracle, NetBeans. Vous avez aussi à votre disposition des démonstrations et des exemples. En fait, il est possible de charger des tas de choses supplémentaires,

peut-être même une version de Java avec apéritif et chips, mais ce dont vous avez besoin pour ce livre, c’est uniquement le JDK Java. » Type d’installation Il se peut que vous ayez le choix entre une installation en ligne (online) ou hors ligne (offline). Dans le second cas, vous téléchargez un (très) gros fichier

d’installation,

disons

d’un

poids

compris

entre 30 et 150 Mo selon le choix que vous avez fait. Le côté pratique de l’affaire, c’est que ce fichier sera toujours à votre disposition si vous avez besoin de procéder à une nouvelle installation, du moins tant qu’une nouvelle et importante version du JDK n’est pas publiée. Pourquoi donc installer une seconde fois la même version du JDK  ? Il y a deux raisons possibles. La première, c’est que vous voulez créer une seconde configuration sur un autre ordinateur. La seconde, c’est que vous avez besoin de désinstaller puis de réinstaller votre configuration actuelle à la suite d’un problème. Avec une installation dite en ligne, vous téléchargez simplement un petit fichier qui va se charger du reste de l’opération, et en particulier d’aller chercher les éléments du gros fichier de  30  ou  150  Mo en fonction

de vos besoins. Cela vous permet de gagner de la place sur votre disque dur. Par contre, vous devrez tout reprendre depuis le début si vous voulez procéder à une nouvelle installation. Entre nous, étant donné la capacité de nos disques durs modernes, je préfère tout télécharger d’un coup. Pour une introduction à la documentation de l’API Java, reportez-vous au Chapitre 1. La plupart des gens ne rencontrent aucun problème pour installer Java à partir du site Web d’Oracle. Mais votre propre situation peut être un peu différente, un peu plus compliquée, disons plus «  intéressante  » . Nous allons donc nous pencher sur ces scénarii « intéressants » dans les quelques sections qui suivent.

MON ORDINATEUR, IL A COMBIEN DE BITS ? Nous avons vu qu’au moment de choisir la version d’un logiciel que vous allez installer sur votre ordinateur (disons par exemple Java), deux possibilités peuvent vous être offertes : une version  32 bits, et une version  64 bits. Quelle est la différence, et pourquoi faut-il s’en préoccuper ? Un bit, c’est la plus petite quantité d’information qui puisse être enregistrée sur un ordinateur, disons pour simplifier le fameux zéro, ou le non moins fameux un. Pour représenter un nombre quelconque, il faut empiler une série de bits et faire de jolis calculs avec des puissances de deux. Ne rentrons pas dans les détails. Ce qu’il est important de retenir, c’est que chaque morceau de circuit dans votre ordinateur enregistre le même nombre de bits (d’accord, il y en a qui jouent leur partition un peu différemment, mais vous voyez ce que je veux dire). Dans les anciens ordinateurs (pas les plus vieux), chaque morceau de circuit stockait 32 bits. Dans les ordinateurs plus récents, chaque morceau de circuit stocke  64  bits. Dans les deux cas, on appelle généralement cela un mot. Il y a donc les vieux mots de 32 bits, et les jeunes mots de 64 bits. Vous allez me dire  : «  Parfait  ! J’ai acheté mon ordinateur la semaine dernière, donc il fonctionne sur 64  bits.  » En fait,

l’histoire n’est pas forcément aussi simple que cela. Il y a bien les circuits de votre ordinateur, mais ceux-ci ne sont rien sans le système d’exploitation qui y est installé. Les instructions traitées par le système d’exploitation ont en effet leur propre conception de la longueur des mots. Disons qu’un système d’exploitation  32  bits est capable de tourner sur un ordinateur 32 bits ou 64 bits (qui peut le plus peut le moins, dit-on). Par contre, un système d’exploitation  64  bits ne peut fonctionner qu’avec un ordinateur  64  bits. Et, pour compliquer encore plus la situation, chaque programme que vous exécutez (qu’il s’agisse d’un navigateur Web, d’un traitement de texte, ou de l’un de vos programmes Java) est soit de conception 32  bits, soit de conception  64  bits. Par exemple, un navigateur 32 bits s’exécutera avec un système d’exploitation 

64 

bits

installé

sur

un

ordinateur

également  64  bits. Et c’est également vrai pour un système d’exploitation  32  bits installé sur un ordinateur  64  bits… Résumons-nous un peu : » Avec un système d’exploitation 32 bits, vous ne pouvez exécuter que des applications 32 bits. » Avec un système d’exploitation  64  bits, vous pouvez exécuter

aussi

(généralement

bien sans

applications 64 bits.

des souci

applications  32  bits particulier)

que

des

La figure jointe à cet encadré détaille tout cela d’une façon plus visuelle.

Lorsqu’un site Web vous demande de choisir entre la version  32  bits et la version  64  bits d’un logiciel, l’élément principal à prendre en compte, c’est la longueur de mot de votre système d’exploitation, pas de votre ordinateur. Vous pouvez par exemple exécuter un traitement de texte 32 bits avec un système d’exploitation 64 bits, mais l’inverse est faux (et cela, quels que soient les circuits de votre ordinateur). Une version  64  bits présente potentiellement un immense avantage, puisqu’elle est capable d’accéder à plus de 3 Go de

mémoire. Et, selon mon expérience, plus de mémoire signifie un fonctionnement plus rapide. Maintenant, en quoi toute cette affaire de longueur de mot concerne-t-elle vos téléchargements de Java et d’Eclipse  ? Voici toute l’histoire : » Avec un système d’exploitation  64  bits, vous pourriez avoir deux versions du même programme. Par exemple, sur mon ordinateur Windows, j’ai deux installations d’Internet Explorer, une en  32  bits et une en 64 bits. Normalement, Windows place les programmes  32  bits dans son dossier Program

files

(x86), et les

programmes 64 bits dans le dossier Programmes. » La force d’une chaîne (de mots en l’occurrence) dépend toujours de son maillon le plus faible. Par exemple, si je me rends sur le site http://java.com et que je clique sur le lien Est-ce que je dispose de Java  ?, la réponse que j’obtiens dépend de la correspondance entre la version de Java installée sur mon ordinateur et le navigateur Web que j’utilise. Si j’ai seulement une version 64  bits de Java et que j’ai cliqué sur ce lien dans une version  32  de Firefox, la réponse sera non (c’est dit d’une manière un peu plus polie). Par contre, le même

clic dans la version  64  bits d’Internet Explorer m’assurera que tout va pour le mieux dans le meilleur des mondes, tout en m’apprenant éventuellement qu’une nouvelle version de Java est disponible. Sur un Mac, Safari et Firefox existent uniquement en 64 bits, alors que Chrome est un navigateur 32 bits. Là encore, la réponse dépend donc de l’origine de la question. » Et voici le plus important, du moins pour ce livre et votre avenir de programmeur Java  : en suivant les instructions données dans ce chapitre, vous allez installer Java et Eclipse. La longueur de mot de Java et celle d’Eclipse doivent être identiques. En d’autres termes, Eclipse  32  bits fonctionne avec Java  32  bits, et Eclipse 64 bits avec Java 64 bits. Point. » Enfin,

certains

sites

utilisent

pour

leurs

téléchargements des noms dont le moins qu’on puisse dire est qu’ils ne sont pas intuitifs. Si vous voyez par exemple quelque chose comme i365  ou i586  dans un nom, cela signifie généralement qu’il s’agit d’une version  32  bits. Un x86  sans autre précision désigne également une application  32  bits. Par contre, si vous voyez  64  dans le nom (avec ou sans désignation du genre x86), il s’agit clairement d’une application 64 bits.

Trouver Java sur votre ordinateur Le Chapitre 1  décrit l’écosystème de Java, avec son compilateur, sa machine virtuelle et ses autres composants. Il se peut très bien qu’une partie de tout cela se trouve déjà sur votre ordinateur. Dans ce cas, vous pouvez soit continuer à vivre avec ce que vous possédez déjà, soit installer la dernière version en date de Java en plus de ce qui se trouve actuellement sur votre disque dur. Les versions de Java ne sont pas comme les chats d’appartement. Elles peuvent coexister sur le même ordinateur sans se battre et sans émettre des cris stridents. Aucun problème. Vous pouvez même mixer des versions  32  bits et  64  bits. Bien sûr, il vous faudra au moins une version ayant la même longueur de mot qu’Eclipse. J’ai par exemple trois versions

de

Java

sur

mon

ordinateur

sous

Windows  10, et je n’ai jamais rencontré de problème. D’accord, il peut arriver qu’on se perde entre toutes ces installations. Mais tout devrait rentrer dans l’ordre grâce à la section « Configurer Java dans Eclipse » de ce chapitre.

Sous Windows Pour savoir ce qui est déjà installé sous Windows, il vous suffit d’ouvrir les Paramètres (autrefois le Panneau

de

configuration),

puis

de

choisir

Applications et enfin Applications et fonctionnalités (sous

Windows

XP,

l’appellation

est

un

peu

différente, mais qui s’en soucie encore ?). Sous Windows 8.1, ouvrez votre bureau, puis placez le pointeur de la souris dans le coin inférieur gauche de l’écran et faites un clic droit. Dans le menu qui s’affiche, choisissez la première option, Programmes et fonctionnalités. Dans la liste des applications installées, recherchez tout ce qui commence par Java (voir la Figure 2.3). Si vous voyez Java  8  (voire plus), c’est parfait. Si vous ne voyez que des numéros de version plus petits que  8  (par exemple  1.4.2, 5.0  ou encore  6), votre ordinateur pourra exécuter la plupart des programmes de ce livre, mais pas tous.

Sur un Mac Un Mac peut supporter deux parfums différents de Java : l’un est développé par M. Apple en personne, et l’autre est placé sous les auspices d’Oracle.

Certaines commandes et procédures s’appliquent uniquement à l’un de ces parfums, mais pas à l’autre. Par exemple, pour trouver la version Apple de

Java,

vous

regardez

dans

le

dossier

/System/Library/Java/ Java Virtual Machines ou

bien

dans

/System/Library/Frameworks/JavaVM.framework /Versions. Par contre, le Java d’Oracle se trouve dans

le

dossier

/Library/Java/JavaVirtualMachines. Mais il se peut

aussi

que

/Library/Internet

vous

le

trouviez

dans Plug-

Ins/JavaAppletPlugin.plugin/ Contents/Home.

FIGURE 2.3

La boîte de dialogue Applications et fonctionnalités, avec

une installation de Java toute fraîche.

Java est préinstallé sous Tiger, Leopard, et Snow Leopard (OS X  10.4, OS X  10.5, et OS X  10.6). Par contre, ce n’est pas le cas sous les versions ultérieures des systèmes d’exploitation des Mac. Dans ce cas, il vous est demandé si vous voulez installer le Java d’Apple ou celui d’Oracle la première fois que vous lancez une application qui réclame la présence de Java (cela peut être par exemple le cas lorsque vous exécutez Eclipse pour la première fois). Le Tableau  2.1  décrit les corrélations entre les versions de Mac OS et de Java.

Pour trouver la version de votre OS, choisissez l’option À propos dans le menu Pomme. Vous devriez alors voir par exemple quelque chose dans le genre 10.12.4. Les

informations

données

dans

le

Tableau 2.1 s’appliquent à des versions de Mac OS X mises à jour. Si vous négligez les mises à jour du système d’exploitation, votre propre numéro de version peut différer de ce qui est indiqué dans le tableau (par exemple, vous voyez  10.8.1  au lieu de  10.8.5). Je ne peux que vous conseiller de vous intéresser à l’option de mise à jour du système. Ici et là sur le Web, j’ai pu voir des messages dans des forums qui expliquent comment installer Java  5.0  sur OS X  10.3, et autres manières de contourner

les

Tableau  2.1.

restrictions

À

moins

indiquées

d’être

un

dans

le

spécialiste

chevronné, je vous recommande vivement de ne pas vous lancer dans une telle aventure. TABLEAU

2.1

Versions Mac OS X Versions et versions Java.

Si vous avez cette Alors vous avez

Et vous pouvez

version de Mac OS cette version de

installer cette

X…

version…

Java…

OS X 10.4.11 (Tiger) Java 5.0 (Apple)

 

Java 5.0 (Apple) OS X 10.5.8

 

 

Java 5.0 (Apple)

Java 5.0 (Apple)

 

 

Intel et 64bits

Java 6 (Apple)

Java 6 (Apple)

OS X 10.6.8 (Snow

Java 6 (Apple)

Java 6 (Apple)

OS X 10.7.5 (Lion)

(pas de Java)

Java 6 (Apple)

OS X 10.8.5

 

Java 9 (Oracle)

 

 

 

 

 

 

 

 

(Leopard) PowerPC et/ou 32bit OS X 10.5.8 (Leopard)

Leopard)

(Mountain Lion) OS X 10.9 (Mavericks) OS X 10.10 (Yosemite) OS X 10.11 (El Capitan) macOS 10.12 (Sierra)

Si vous doutez de ce que vous explique le Tableau 2.1 (et c’est votre droit le plus absolu), vous pouvez essayer ce qui suit pour savoir si Java est bien installé sur votre Mac et son numéro de version.

Avec OS X 10.6 et antérieur » Tapez Java Preferences dans le champ de recherche Spotlight. La fenêtre illustrée sur la Figure 2.4 devrait apparaître. Les figures qui suivent correspondent à une version de Java non localisée. Mais cela ne devrait pas poser de problème, même si votre anglais est approximatif. Sur l’exemple de la Figure 2.4, on peut constater que quatre versions de Java sont installées : les versions 32 bits de Java 6 et 7, et les versions 64 bits de Java 6 et 7.

FIGURE 2.4

Java et ses préférences.

Avec OS X 10.7 ou plus » Avec une version plus récente du système d’exploitation d’Apple, sélectionnez les préférences système dans le menu Pomme. » Recherchez alors l’icône Java. Si vous la trouvez, cliquez sur cette icône pour faire apparaître le panneau de configuration Java. Celui-ci peut se présenter comme sur la Figure 2.5 ou sur la Figure 2.6.

FIGURE 2.5 ceci.

Le panneau de configuration de Java peut ressembler à

FIGURE 2.6

Le panneau de configuration de Java peut aussi

ressembler à cela.

» Si votre panneau de contrôle Java ressemble à celui de la Figure 2.5, vous devriez voir votre version de Java sous le premier onglet. En l’occurrence, il s’agit de Java 9. C’est parfait. Vous pouvez passer à la suite.

» Si votre panneau de contrôle Java ressemble à celui de la Figure 2.6, activez l’onglet Java, puis cliquez sur le bouton View (ou Visualiser en meilleur français). Les paramètres de Java Runtime Environment vont apparaître. Sur la Figure 2.7, on constate que l’ordinateur exécute Java 1.8 (que les amis de Java appellent familièrement Java 8).

FIGURE 2.7

L’onglet User (Utilisateur) dans les paramètres de Java

Runtime Environment.

Vous retrouvez le même panneau de configuration sous Windows. Pour y accéder, ouvrez le panneau de configuration. Choisissez alors Programmes, puis cliquez sur l’icône Java.

Sous Linux

Pour vérifier votre installation Java (ou son absence d’installation), commencez par rechercher dans les menus du bureau quelque chose qui s’appelle Terminal

(également

connu

sous

le

nom

de

Konsole). Dans la fenêtre Terminal (elle affiche généralement du texte blanc sur un fond noir), tapez java – version et appuyez sur Entrée. Sur un de mes ordinateurs Linux, Terminal répond en affichant ceci : java version 1.8.0_111 Sur un autre, je vois ceci : java version 9 Entre Java 8 et Java 9, Oracle a changé son système de

numérotation.

En

d’autres

termes,

la

version 9 suit immédiatement les versions 1.8.0. De toute manière, si vous voyez chez vous un numéro supérieur ou égal à  9, vous pouvez sabler le champagne et vous frotter les mains avant de vous atteler aux exemples de ce livre. Si la réponse est 1.5 ou plus, vous pourrez exécuter la plupart de ces exemples, mais pas tous. Et si le message vous

indique que Terminal n’a rien trouvé, c’est que, très probablement, Java n’est pas installé sur votre ordinateur.

Configurer l’environnement de développement intégré Eclipse Dans les sections précédentes, vous vous êtes procuré tous les outils dont votre ordinateur a besoin pour exécuter des programmes Java. Cette section est différente. Ici, nous allons nous occuper de l’outil dont vous avez besoin pour composer et tester vos programmes Java. Cet outil, c’est Eclipse, un environnement de développement intégré dédié à Java. Un environnement de développement intégré (ou IDE) est une application qui fournit les instruments grâce auxquels vous pouvez créer des programmes avec facilité et efficacité. Vous pourriez bien sûr vous en passer, mais le gain de temps et d’efforts que procure un IDE valent vraiment la peine d’en passer par là (certains programmeurs purs et durs ne seront pas d’accord avec moi, mais c’est une autre histoire).

Si Eclipse est le plus souvent considéré par les programmeurs

comme

une

interface

pour

le

développement d’applications Java, il faut savoir qu’il dispose aussi d’outils pour travailler en C++, en PHP et dans de nombreux autres langages. C’est donc un environnement très versatile. Et j’ai même vu des incarnations d’Eclipse qui n’ont rien à voir avec la programmation (c’est par exemple le cas de Lively Browser, un navigateur Internet dont les onglets sont construits à partir de composants Eclipse, ou encore de Dynaspace, un outil de suivi de grandes infrastructures).

Télécharger Eclipse Voici comment télécharger Eclipse : 1. Rendez-vous sur le site eclipse.org. 2. Vous devriez voir, en haut et à droite de la fenêtre, un bouton marqué Download (voir la Figure 2.8).

FIGURE 2.8

La page d’accueil du site eclipse.org.

L’aspect de la page peut bien sûr évoluer au fil du temps, mais votre objectif doit être dans tous les cas de repérer ce bouton. 3. Cliquez sur le bouton Download. Vous devriez voir quelques options de téléchargement possibles (voir la Figure 2.9). Notez que la numérotation de version d’Eclipse est basée sur l’année et le mois, ce qui n’était pas le cas autrefois.

FIGURE 2.9

Eclipse propose de télécharger la dernière version en

date.

4. Cliquez à nouveau sur le bouton Download. Notez qu’Eclipse ayant déjà reconnu votre système sait quel type de fichier d’installation il doit vous proposer. La page qui suit vous propose un site de téléchargement. Vous pouvez choisir ici un serveur miroir différent (voir la Figure 2.10). Mais inutile de se casser la tête : cliquez simplement sur Download sans vous soucier de gagner éventuellement quelques petites secondes pour le transfert !

FIGURE 2.10

Encore un clic, et c’est parti pour Eclipse !

5. Il ne vous reste plus qu’à vous décider entre la version 32 bits et la version 64 bits de l’application. Pendant que le téléchargement s’effectue, vous pouvez prendre quelques instants pour lire les quelques compléments. Remarquez Packages

en

particulier

(Télécharger

des

le

lien

paquets)

Download sur

la

Figure 2.10. Si vous cliquez sur ce lien, vous pouvez télécharger une copie d’Eclipse avec certaines fonctionnalités en plus. Par exemple, le package Eclipse IDE for Enterprise Java Developers inclut des fonctionnalités lourdes pour le développement industriel. Le package Eclipse IDE for JavaScript and Web Developers offre des fonctionnalités pour aider à créer des pages Web. Si vous atterrissez sur

cette page, recherchez le paquet nommé Eclipse IDE for Java Developers (le second de la liste). Notez en même temps que, alors que la page principale vous propose un téléchargement adapté à votre système, vous avez ici la possibilité de choisir une version pour Windows, Mac ou Linux.

Installer Eclipse La méthode d’installation d’Eclipse dépend de votre système d’exploitation, et éventuellement du type de fichier téléchargé sur le site d’Eclipse. » Vous êtes sous Windows et le fichier téléchargé est un exécutable (.exe). Faites un double clic sur l’icône du fichier. » Vous êtes sous Windows et le fichier téléchargé est une archive (.zip). Extrayez le contenu de l’archive dans un dossier de votre choix. En d’autres termes, localisez l’emplacement du fichier Zip dans l’Explorateur Windows. Faites un double clic dessus pour l’ouvrir. Vous allez voir un unique dossier appelé eclipse. Cliquez dessus,

et faites-le glisser vers un emplacement de votre disque dur que vous jugez adéquat. Pour plus d’informations, sur les fichiers .zip, reportez-vous plus haut dans ce chapitre à l’encadré « Une affaire d’archives ». Personnellement, je préfère copier directement le dossier eclipse sur mon disque dur principal (C:). De cette manière, je peux facilement retrouver mes ouailles dans les dossiers Programmes, Windows et eclipse. J’évite de copier Eclipse sous Program Files (x86) pour éviter tout problème avec la présence d’une espace dans le nom du dossier (et n’oubliez pas que le vrai nom de Programmes est Program Files). » Vous travaillez sous Mac OS X : Le téléchargement d’Eclipse va vous donner un fichier de type .tar.gz ou .dmg. •

Un fichier .tar.gz est une archive. En théorie, votre navigateur devrait s’occuper pour vous de tout ou partie de la décompression. Dans ce cas, vous trouverez dans votre dossier Téléchargements un fichier d’extension .tar (si la partie .gz a été

décompressée) ou un dossier eclipse (si le navigateur a déjà fait tout le travail). Si le dossier des téléchargements contient un fichier .tar ou .tar.gz, faites un double clic dessus jusqu’à ce que le dossier eclipse apparaisse. Faites-le alors glisser sur votre dossier Applications, et le tour est joué. •

Si vous avez téléchargé un fichier .dmg, votre navigateur peut l’ouvrir pour vous. Sinon, localisez-le dans le dossier des téléchargements et faites un double clic dessus. Suivez les instructions qui apparaissent ensuite. Là encore, je vous conseille de placer au final le dossier eclipse dans vos applications.

» Vous travaillez sous Linux : Selon le cas, le fichier téléchargé aura pour extension .tar.gz ou .bin. Extrayez le fichier .tar.gz vers votre dossier favori, ou exécutez le fichier auto-extractible .bin. N’essayez pas de lancer Eclipse tout de suite ! Lisez d’abord la prochaine section.

Avant de lancer Eclipse… J’espère que vous avez fait preuve de patience et que vous n’avez pas encore essayé de voir à quoi ressemblait Eclipse. Si  ? Alors vous avez pu constater que cette application est en anglais, totalement en anglais, et qu’aucune option n’existe pour changer de langue. Mais, bien sûr, vous vous sentiriez plus à l’aise si Eclipse vous parlait en français. Et c’est possible à condition de faire preuve d’un minimum de précision. Voyons cela de plus près. Les programmeurs purs et durs ont l’habitude des IDE et autres outils en anglais. Ils préfèrent ne rien changer, d’autant que la traduction d’Eclipse n’est pas complète (du moins au moment où ce livre est écrit). Comme nous ne sommes que des débutants, nous allons nous passer de leur avis ! 1. Si vous avez déjà lancé Eclipse au moins une fois, refermez-le et supprimez totalement votre dossier d’installation. D’accord, ce n’est pas une obligation absolue. Mais tenter dans ce cas d’installer la traduction française d’Eclipse vous obligerait à créer une ligne de

commande spécifique pour lancer ensuite l’application : eclipse.exe –nl fr Ce n’est pas particulièrement complexe, mais autant faire le travail proprement. 2. Recommencez normalement l’installation d’Eclipse (voir ci-dessus). Ne faites rien de plus, ne passez pas par la case Lancement, et ne touchez pas 20 000 Javas ! 3. Dans votre navigateur Web, ouvrez maintenant l’adresse http://eclipse.org/babel/downloads.php. Une page semblable à celle qui est illustrée sur la Figure 2.11 va s’afficher.

FIGURE 2.11

Eclipse et sa tour de Babel.

4. Localisez la section intitulée Babel Language Pack Zips (normalement, c’est la première). Cliquez ensuite sur le nom de la dernière version en date localisée d’Eclipse (au moment où ce livre est écrit, elle est dénommée 201812). 5. Une longue page de fichiers de langages pour Eclipse va apparaître. Faites-la défiler vers le bas pour accéder à la section French.

6. Le lien qui nous intéresse ici est celui qui commence par BabelLanguagePack-eclipsefr. Le nom est suivi d’une série de chiffres de référence (voir la Figure 2.12). Cliquez sur cette ligne pour procéder au téléchargement. Choisissez éventuellement un serveur miroir et cliquez sur Download.

FIGURE 2.12

Télécharger un fichier de langue pour Eclipse.

À l’heure où ce livre est écrit, le nom complet du fichier est : BabelLanguagePack-eclipsefr_4.10.0.v20190126060001.zip 7. Une fois le chargement terminé, ouvrez l’archive et copiez tout simplement son contenu

dans votre dossier eclipse. Si un message vous indique que les dossiers features et plugins existent déjà, confirmez la copie. Vous ne faites que compléter leur contenu. C’est donc sans risque. C’est fait. Vous êtes maintenant paré pour affronter Eclipse dans sa livrée francisée (même si ce n’est pas en totalité). Pour ceux qui n’auraient pas envie de se lancer dans cet exercice et qui préféreraient conserver la version standard d’Eclipse, je donnerai chaque fois que ce sera utile les deux appellations, française et anglaise, des noms de commandes et autres éléments de la syntaxe propre à cette application.

Exécuter Eclipse pour la première fois Lors du premier lancement d’Eclipse, la première chose que vous allez remarquer, c’est qu’il y a quelques étapes préliminaires à respecter : 1. Lancez Eclipse. Sous Windows, vous ne trouverez peut-être pas d’icône Eclipse sur votre bureau ou dans le menu

Démarrer. Dans ce cas, ouvrez l’Explorateur de fichiers et localisez votre dossier eclipse. Faites un double clic sur la ligne qui indique eclipse.exe (si vous voyez uniquement eclipse, c’est la même chose – revoyez à ce sujet l’encadré « Ces satanées extensions de fichiers »). Sur un Mac, servez-vous de la fonction de recherche Spotlight et tapez Eclipse. Une fois le nom localisé, sélectionnez-le et appuyez sur Entrée. La première fois que vous essayez d’exécuter Eclipse sur un Mac, il se peut que vous ayez droit à un message qui vous prévient que l’application ne provient pas de l’Apple Store, et que son développeur est inconnu. D’accord, rien n’est jamais totalement sûr dans ce bas monde, mais j’ai téléchargé et installé Eclipse des milliards de fois et je n’ai jamais eu le moindre problème. Une manière de contourner cet avertissement consiste à localiser Eclipse dans votre dossier Applications, à faire un Ctrl+clic sur son icône, et à choisir la commande Ouvrir. Il ne vous reste plus qu’à confirmer tout en pestant contre ces types qui vous veulent un peu trop de bien.

Lorsque Eclipse se lance, vous voyez s’afficher une boîte de dialogue qui vous demande de définir un espace de travail, ou workspace (voir la Figure 2.13). Il s’agit de l’emplacement de votre disque dur dans lequel sera enregistré le code que vous allez créer en utilisant Eclipse.

FIGURE 2.13

Définir l’espace de travail dans Eclipse.

2. Cliquez sur OK pour accepter la proposition par défaut, ou définissez un autre nom de dossier. Aucun problème, c’est vous qui voyez ! Si vous préférez changer de nom, veillez à ce qu’il ne s’agisse pas d’un dossier déjà existant. Lors de son premier lancement, Eclipse affiche un écran d’accueil (voir la Figure 2.14). Cet écran

évolue au fil du temps, mais il conserve toujours une interface proposant quelques icônes offrant des outils et aides que vous pouvez consulter si vous le souhaitez.

FIGURE 2.14

L’écran d’accueil d’Eclipse (dans sa version par défaut).

3. L’icône qui nous intéresse ici est appelée Workbench (ou Plan de travail). Cliquez sur cette icône pour ouvrir l’écran principal d’Eclipse. Votre plan de travail, bien sûr encore vierge à ce stade, va s’afficher comme l’illustre la Figure 2.15.

FIGURE 2.15

Le plan de travail d’Eclipse.

Eclipse en français, vraiment ? En fait, la manipulation développée plus haut pour localiser l’interface d’Eclipse en français ne donne pas le résultat escompté  ? C’est possible. Tout dépend de la version que vous avez installée… Voyons une autre façon de procéder, cette fois en partant directement de la fenêtre par défaut d’Eclipse : 1. Depuis la fenêtre principale du logiciel, choisissez Help, puis Install new software.

Vous demandez ainsi à Eclipse d’installer un complément. 2. Dans la fenêtre qui s’affiche, saisissez le lien : https://download.eclipse.org/technology /babel/update-site/ R0.16.1/2018-12/ 3. Cliquez sur Add, puis donnez un nom au site Web choisi (Babel, c’est pas mal). 4. Faites défiler la liste qui va s’afficher jusqu’à ce que vous trouviez la ligne qui indique Babel Language Pack in French (Hungarian, c’est un autre choix possible). Cochez-la (voir la Figure 2.16).

FIGURE 2.16

Choisir un pack de langue dans le menu d’aide d’Eclipse.

5. Cliquez sur le bouton Next et patientez un peu. 6. Cliquez maintenant sur la ligne qui indique : https://download.eclipse.org/technology /babel/update-site/ R0.16.1/2018-12/ 7. Cliquez sur Next, validez, attendez… Rien que de l’ordinaire, quoi.

Quand vous avez dit oui à tout, Eclipse va redémarrer en vous ouvrant une jolie interface aussi bien francisée qu’il est possible (voir la Figure 2.17).

Configurer Java dans Eclipse Normalement, Eclipse recherche les installations de Java sur votre ordinateur, et il en sélectionne une version pour pouvoir exécuter vos programmes. Il est

possible

que

plusieurs

versions

de

Java

coexistent sur votre disque dur, et vous devez donc absolument vous assurer qu’Eclipse a fait le bon choix. Pour cela, suivez ces étapes :

FIGURE 2.17

Eclipse est maintenant francisé.

1. Ouvrez le menu Fenêtre (Window), ou Eclipse sur un Mac. Choisissez ensuite la commande Préférences. La boîte de dialogue des préférences d’Eclipse va apparaître (voir la Figure 2.18). 2. Dans l’arborescence proposée à gauche de la fenêtre, cliquez sur la ligne Java pour révéler les options correspondantes. 3. Cliquez ensuite sur la sous-branche JRE installés.

4. Consultez la liste des JRE installés dans la partie principale de la boîte de dialogue. Sur l’exemple de la Figure 2.18, une seule version est cochée, ce qui indique qu’elle est bien reconnue et active. Par contre, si plusieurs versions sont disponibles sur votre propre système : 5. Dans le cas où votre version préférée est bien présente dans la liste des JRE installés, cliquez sur la case qui se trouve à sa gauche pour l’activer. 6. Si vous ne voyez pas votre version préférée, cliquez sur le bouton Ajouter. Dans ce cas, la boîte de dialogue Type de JRE va apparaître (voir la Figure 2.19).

FIGURE 2.18

Définir les préférences dans Eclipse.

FIGURE 2.19

La boîte de dialogue Type de JRE.

7. Faites un double clic sur la ligne qui indique VM Standard. La boîte de dialogue de définition du JRE s’affiche (voir la Figure 2.20). La suite dépend de plusieurs éléments :

FIGURE 2.20

La boîte de dialogue Définition du JRE.

8. Remplissez le champ Répertoire source du JRE (JRE home). La manière de procéder varie selon le système d’exploitation : •

Sous Windows, naviguez vers le dossier dans lequel vous avez installé votre version préférée de Java, par exemple C : \Programmes\Java\jdk-

12.0.1, ou quelque chose du même style. •

Sur un Mac, utilisez le Finder pour naviguer vers le dossier dans lequel vous avez installé votre version préférée de Java. Tapez le nom de ce dossier dans le champ Répertoire source du JRE. Mon Mac a un dossier appelé /System/Library/Java/Java Virtual Machines/1.6.0.jdk/Contents/Home, et un autre intitulé /Library/ Java/JavaVirtualMachines/jdk9.jdk/Contents/Home. Le premier correspond à une ancienne version Apple, et le second à une version plus récente d’Oracle. Il est également possible que vous trouviez un vieux Java d’Apple sous /System/Library/Frameworks/JavaVM.fr amework/Versions et un plus récent Java d’Oracle sous /Library/Internet PlugIns/JavaAppletPlugin.plugin/Contents /Home. Des dossiers tels que /System et /Library n’apparaissent pas spontanément dans la

fenêtre du Finder. Vous devez spécifier le nom recherché en passant par le menu de celui-ci. Lorsque vous naviguez vers le répertoire contenant votre version Java préférée, vous pouvez rencontrer une icône signalant un élément d’extension .jdk. Pour voir le contenu de cet élément, control-cliquez sur son icône, puis sélectionnez l’affichage du contenu du package dans le menu qui apparaît. •

Sous Linux, naviguez vers le dossier dans lequel vous avez installé votre version préférée de Java. En cas de doute, recherchez un dossier dont le nom commence par jre ou jdk.

Vous n’avez pas encore fini de remplir la boîte de dialogue Définition du JRE. 9. Regardez le champ Nom du JRE. Si Eclipse n’a pas rempli automatiquement ce nom, saisissez un intitulé à votre convenance. 10.Cliquez sur le bouton Terminer (Finish). La boîte de dialogue JRE installés va afficher la version de Java que vous venez d’ajouter.

11.Cochez la ligne qui correspond à la version de Java qui vient d’être définie. Vous avez bientôt terminé. 12.Dans la liste des préférences, à gauche de la boîte de dialogue, cliquez sous la branche Java sur la ligne Compilateur. Vous pouvez voir à droite de la rubrique Conformité JDK (JDK Compliance) une liste déroulante (voir la Figure 2.21). 13.Ouvrez la liste Conformité JDK et choisissez un numéro correspondant à votre version préférée de Java. Si c’est Java 8, cliquez sur 1.8. Pour Java 9, choisissez évidemment 9. Pour ce livre, je vous propose de vous en tenir à ce choix qui ne devrait pas poser de problèmes avec nos exemples. 14.Cliquez sur le bouton Appliquer et fermer pour refermer les préférences et revenir au plan de travail d’Eclipse.

FIGURE 2.21

Définir le niveau de conformité du JDK.

Importer les exemples de ce livre Eclipse offre de multiples méthodes pour importer différents types d’objets. Vous devez donc faire preuve de précision pour ne pas vous tromper. Mais si vous suivez exactement la procédure décrite cidessous, tout devrait bien se passer. 1. Vérifiez que vous avez correctement téléchargé le fichier d’archive qui contient les

exemples du livre et que vous savez retrouver l’emplacement dans lequel vous l’avez enregistré. 2. Dans le menu principal d’Eclipse, choisissez Fichier->Importer (voir la Figure 2.22). Eclipse affiche la boîte de dialogue Importer. 3. Dans la liste des choix proposés, cliquez sur la ligne Généralités afin de la développer.

FIGURE 2.22

Lancer l’importation des exemples de ce livre.

4. Faites un double clic sur la ligne Projets existants dans l’espace de travail (Existing Projects into Workspace). C’est ce qu’illustre la Figure 2.23.

La boîte de dialogue Importation de projets apparaît. 5. Choisissez l’un des boutons radio Sélection du répertoire racine (Select Root Directory) ou Sélection d’un fichier archive (Select Archive File). Le choix dépend de la manière dont vous avez stocké les exemples du livre (reportez-vous à la Figure 2.24). •

Si votre navigateur Web n’a pas automatiquement décompressé le fichier des exemples de code que vous avez téléchargé, choisissez la seconde option (archive).



Sinon, vous devriez avoir sur votre disque dur un dossier appelé Java ou quelque chose d’équivalent selon les choix que vous avez faits. Sélectionnez alors la première option (racine).

FIGURE 2.23

Dans la boîte de dialogue Importer, choisissez l’option

Projets existants dans l’espace de travail.

En cas de doute, reportez-vous plus haut dans ce chapitre à l’encadré « Ces satanées extensions de fichiers ». Si nécessaire, revoyez également, toujours dans ce chapitre, l’encadré « Une affaire d’archives ». 6. Cliquez sur le bouton Parcourir pour localiser l’archive ou le dossier voulu sur votre disque dur.

Une fois que vous avez trouvé le dossier ou le fichier, la boîte de dialogue affiche le nom des projets détectés par Eclipse (voir la Figure 2.24). 7. Si nécessaire, cliquez sur le bouton Tout sélectionner. Évidemment, vous ne voulez rien manquer des exemples de ce livre ! 8. Cliquez sur le bouton Terminer. Vous revenez au plan de travail principal d’Eclipse. Vous constatez alors que le volet de gauche, l’Explorateur de packages (Package Explorer) affiche les noms des projets Java de ce livre (voir la Figure 2.25). Nous allons enfin pouvoir passer aux choses amusantes !

FIGURE 2.24

La boîte de dialogue Importation de projets.

Et maintenant ? Si vous lisez ce paragraphe, c’est que vous avez probablement suivi ce chapitre et appliqué les

instructions qu’il vous donne pour installer Java et Eclipse sur votre ordinateur. La question qui vous brûle maintenant les lèvres, c’est «  Est-ce que j’ai fait toute cette installation correctement  ?  » . Vous découvrirez la réponse dans le Chapitre 3 où vous allez vous servir de ces outils pour démarrer un tout nouveau programme Java.

FIGURE 2.25

Un tas de projets Java dans Eclipse.

Chapitre 3

Exécuter des programmes DANS CE CHAPITRE : » Compiler et exécuter un programme » Éditer votre propre code Java » Utiliser un espace de travail

S programme

i vous débutez en programmation, exécuter un signifie probablement pour vous

cliquer sur une icône ou quelque chose de ce genre. Si vous voulez par exemple « exécuter » Microsoft Word, vous faites un double clic sur son icône. Et c’est parti… Lorsque vous créez vos propres programmes, la situation est un peu différente. Avec un nouveau programme, c’est le développeur qui doit créer l’icône de l’application. D’ailleurs, un excellent programme peut fort bien ne pas avoir d’icône du tout (et, en fait, il n’a aucune icône tant que cet élément d’interface n’a pas été défini). Par voie de

conséquence, qu’allez-vous faire d’un tout nouveau programme Java  ? Comment allez-vous le lancer  ? Ce chapitre vous explique tout ce que vous avez besoin de savoir à ce sujet.

Exécuter un programme Java existant La meilleure manière d’apprendre Java, c’est de faire du Java. Autrement dit, d’écrire, tester et exécuter vos propres programmes Java. Cette section va vous préparer à vous lancer dans le grand bain en vous expliquant comment exécuter et tester un programme. Vous allez pour cela utiliser quelque chose que j’ai écrit pour vous (ne me remerciez pas ! ). Cette petite application calcule les remboursements mensuels d’un prêt immobilier (cela peut toujours servir à quelque chose). Ce programme n’ouvre aucune fenêtre. Il se contente d’afficher ses résultats dans la fenêtre Console d’Eclipse. Cette vue est accessible via l’un des onglets qui se trouvent vers le bas du plan de travail d’Eclipse (voir la Figure 3.1). Un programme qui s’exécute uniquement dans la console est dit programme en mode texte.

FIGURE 3.1

L’exemple de programme de remboursement d’emprunt

de ce chapitre.

Si vous ne voyez pas l’onglet Console en bas de la fenêtre d’Eclipse, ouvrez le menu Fenêtre, puis choisissez Afficher la vue (Show View) et Console. Pour plus d’informations sur la vue Console (et sur le plan ou espace de travail d’Eclipse en général), reportez-vous plus loin dans ce chapitre à la section « Vues, éditeurs et autres » . Lorsque

vous

remboursement

exécutez

le

d’emprunt,

programme vous

de

voyez

essentiellement deux choses dans la fenêtre de la console : » Les messages et les résultats que le programme vous envoie : Les messages disent par exemple Quel est le montant de l’emprunt ? Les résultats se traduisent ici par

une ligne comme Vos remboursements mensuels se montent à 1 035,62 €. » Les réponses que vous fournissez au programme à la suite de ses questions : Si vous entrez par exemple 200000 en réponse au premier message, les chiffres que vous tapez sur votre clavier sont renvoyés en écho à la console. Voyons

maintenant

comme

exécuter

ce

programme : 1. Commencez par vous assurer que vous avez bien suivi les instructions données dans le Chapitre 2 (installation de Java, installation et configuration d’Eclipse, importation dans Eclipse des exemples de ce livre). Tout va bien ? Parfait ! Vous n’aurez plus besoin de revenir sur ces instructions par la suite. 2. Lancez Eclipse. La première chose qui vous est demandée, c’est de choisir votre espace de travail (voir la Figure 3.2).

FIGURE 3.2

Le lanceur d’espace de travail d’Eclipse.

Un espace de travail (workspace) est un dossier de votre disque dur. Eclipse enregistre vos programmes Java dans un ou plusieurs dossiers formant autant d’espaces de travail. En plus de vos programmes Java, ces dossiers mémorisent aussi certains paramètres d’Eclipse, comme la version de Java que vous utilisez, les couleurs que vous préférez pour l’affichage des mots dans l’éditeur, la taille de celui-ci lorsque vous redimensionnez la fenêtre de l’application, et ainsi de suite. Vous pouvez donc créer plusieurs espaces de travail associés à différents programmes et différentes configurations d’Eclipse. Par défaut, c’est le dernier espace de travail utilisé qui vous est proposé lorsque vous lancez Eclipse. Comme vous voulez continuer ce qui a été

entrepris dans le Chapitre 2, vous ne devriez rien avoir à modifier à ce stade. 3. Cliquez sur le bouton Lancer dans la boîte de dialogue Lanceur Eclipse IDE. L’espace de travail choisi apparaît sur l’écran de votre ordinateur (voir la Figure 3.3).

FIGURE 3.3

L’espace de travail d’Eclipse.

Sur la Figure 3.3, la partie la plus à gauche de la fenêtre d’Eclipse montre une série de nombres sous l’intitulé Explorateur de packages (Package Explorer). Il s’agit des projets correspondant aux exemples de ce livre. Le projet 03-01 contient le

premier et seul exemple de ce chapitre. Le projet 06-02 contient le programme Java que vous retrouvez dans le Listing 6.2 (le second du Chapitre 6). Les noms des projets peuvent comprendre des lettres, des chiffres, certains signes de ponctuation ou encore des espaces. Dans ce livre, je m’en tiens uniquement à des chiffres et des tirets. Pourquoi faire compliqué ? Pour en apprendre plus sur l’Explorateur de packages, voyez plus loin la section « C’est quoi toutes ces choses dans la fenêtre d’Eclipse ? ». Lorsque vous lancez Eclipse, ce que vous voyez ne reproduit pas forcément l’illustration de la Figure 3.3. Vous allez peut-être voir l’écran d’accueil, ou bien un espace de travail avec un Explorateur de packages vide (ou rempli d’autres projets), et ainsi de suite. Cela signifie simplement que vous n’avez pas suivi exactement les instructions données au Chapitre 2. À moins que vous n’ayez choisi un espace de travail différent lors de l’Étape 2. Dans tous les cas, assurez-vous que vous voyez les numéros des exemples de ce livre, c’est-à-dire 0301, 04-01 et ainsi de suite. Cela vous indiquera

qu’Eclipse est bel et bien prêt à exécuter les exemples de code de ce livre. 4. Cliquez dans l’Explorateur de packages sur la branche 03-0-Mortgage. Le nom de ce projet est mis en surbrillance. Vous avez légitimement envie de voir à quoi peut bien ressembler le code de ce projet. Pour cela, développez la branche 03-0-Mortgage. Vous allez voir une sous-branche appelée src. À son tour, elle contient une autre sous-branche intitulée (default package). Développez-la pour révéler le niveau inférieur, Mortgage.java. Il s’agit de mon programme Java. Faites un double clic sur cette ligne, et son code va s’afficher dans l’éditeur d’Eclipse. 5. Choisissez Exécuter, puis Exécuter (Run), ou encore Exécuter en tant que, suivi de Application Java (voir la Figure 3.4). En règle générale, la première solution est évidemment la plus courte. Vous disposez également du raccourci clavier Ctrl+F11.

FIGURE 3.4

Il existe plusieurs manières d’exécuter un programme.

Vous devriez voir s’afficher le message Quel est le montant de l’emprunt ? dans la console. Notez en passant que, dans cette section de la fenêtre d’Eclipse, la console se partage l’espace avec les onglets Problèmes, Javadoc et Déclaration, voire avec d’autres vues encore. 6. Cliquez n’importe où dans la vue Console, puis saisissez une valeur numérique, par exemple 200000. Entrez uniquement un nombre. N’ajoutez rien d’autre (pas de virgule, pas de symbole monétaire et ainsi de suite). À défaut, vous verriez s’afficher un message signalant une erreur de type NumberFormatException. En particulier, comme dans tout langage de programmation, Java sépare partie entière et partie décimale par un point et non par une virgule ! 7. Appuyez sur Entrée. Le message suivant (Quel est le taux d’intérêt ? ) va s’afficher.

Tapez un nombre à votre convenance, par exemple 2.25, puis appuyez à nouveau sur Entrée. Le message devient Nombre d’années de remboursement ? 8. Saisissez le nombre d’années, par exemple 20. Le programme Java va afficher un paiement mensuel (reportez-vous à la Figure 3.1). Même si mon programme Java est correctement construit, ne vous fiez pas à lui pour savoir avec précision ce que vous devriez payer pour rembourser un tel emprunt. Je n’aimerais pas avoir à vous redonner la différence. Adressez-vous à votre banque ! Lorsque vous saisissez le nombre d’années, entrez uniquement une valeur entière, c’est-à-dire sans partie décimale. Sinon, vous aurez droit à un virulent message d’erreur. Il peut arriver que vous constatiez au milieu de l’exécution d’un programme que vous avez fait une erreur quelque part. Dans ce cas, il vous suffit de cliquer sur le bouton rouge dans la vue Console pour stopper l’exécution du programme (voir la Figure 3.5).

FIGURE 3.5

Comment terminer prématurément l’exécution d’un

programme.

Si vous avez suivi les instructions de cette section et que vous n’obtenez pas les résultats attendus, vous pouvez tenter deux choses : » Revérifier toutes les étapes pour vous assurer que vous avez suivi les instructions correctement. » Paniquer.

Taper et exécuter votre propre code Dans ce qui précède, nous avons vu comment exécuter le code écrit par quelqu’un d’autre (moi, en l’occurrence). Mais, bien entendu, le but du jeu est d’écrire votre propre code. Cette section vous explique comment le faire dans Eclipse.

Séparer vos programmes des miens

Dans le Chapitre  2, vous avez téléchargé les exemples de ce livre. Vous avez ensuite créé un espace de travail sous Eclipse et importé ces exemples dans ledit espace de travail. Vous pouvez évidemment ajouter vos propres projets à cet espace de travail. Mais, pour séparer vos projets des miens, il faut que vous définissiez un

second

espace.

Voici

deux

manières

d’y

parvenir : » Lorsque vous ouvrez Eclipse, saisissez un nouveau nom de fichier dans la boîte de dialogue Lanceur Eclipse IDE. Si ce dossier n’existe pas, Eclipse va le créer. Sinon, l’Explorateur de packages d’Eclipse va lister les projets contenus dans ce dossier. » Dans la fenêtre d’Eclipse, ouvrez le menu Fichier et choisissez la commande Commuter l’espace de travail (Switch Workspace). Eclipse vous propose les derniers espaces de travail utilisés. Si celui qui vous intéresse n’est pas proposé dans la liste, choisissez Autre (voir la Figure 3.6). Eclipse ouvre alors à nouveau la boîte de dialogue Lanceur Eclipse IDE.

FIGURE 3.6

Passer d’un espace de travail à un autre.

Écrire et exécuter votre programme Voici comment créer un nouveau projet Java : 1. Lancez Eclipse.

2. Ouvrez le menu Fichier, puis choisissez Nouveau et enfin Projet Java (votre anglais devrait être suffisant pour localiser si nécessaire cette commande). 3. Dans la boîte de dialogue Nouveau projet Java, saisissez un nom à votre convenance puis cliquez sur le bouton Terminer. Sur la Figure 3.7, j’ai donné comme nom à ce projet MonPremierProjet.

FIGURE 3.7

Créer un nouveau projet Java avec Eclipse.

Si vous cliquez sur Suivant au lieu de Terminer, vous allez voir d’autres options dont vous n’avez pas besoin à ce stade. Pour éviter toute confusion, cliquez simplement sur Terminer.

Dans la section JRE, vous pouvez noter que la version proposée par défaut (JavaSE 1.8) est plus ancienne que votre installation (jdk-12.0.1 ici). Pour éviter tout problème éventuel de compatibilité, il est préférable de conserver la valeur par défaut, tout à fait adaptée aux exemples développés dans ce livre. Vous revenez à l’espace de travail courant, et le nom de votre nouveau projet apparaît dans le volet Explorateur de packages (voir la Figure 3.8). La prochaine étape va consister à créer un nouveau fichier pour le code source de votre programme Java.

FIGURE 3.8 d’Eclipse.

Votre projet apparaît dans l’Explorateur de packages

4. Sélectionnez votre nouveau projet dans l’Explorateur de packages d’Eclipse. Sur l’illustration de la Figure 3.8, j’ai cliqué sur MonPremierProjet. 5. Choisissez maintenant dans le menu Fichier l’option Nouveau, puis Classe. Les programmeurs Java divisent normalement leur code en un ou plusieurs packages. Un package typique porte un nom comme java.util ou org. allyourcode.images. Sur la Figure 3.9, Eclipse m’avertit que je n’ai pas donné de nom au package destiné à contenir le code de mon projet. Dans ce cas, le code sera placé dans le package par défaut de Java. Ce package par défaut n’a pas de nom. C’est en quelque sorte un fourre-tout pour le code qui n’appartient à aucun package. Les packages sont très utiles pour gérer les projets de programmation importants. Mais ce livre ne contient rien d’une telle ampleur. Dans cet exemple (comme d’ailleurs dans le reste de ce livre), j’ai donc choisi d’ignorer cette question. Pour plus d’informations sur les packages Java, reportez-vous au Chapitre 18.

FIGURE 3.9

Créer une nouvelle classe Java dans Eclipse.

Comme tous les autres environnements basés sur un système de fenêtres, Eclipse fournit plusieurs méthodes pour accomplir la même tâche. Au lieu de passer par le menu Fichier, vous auriez pu faire un clic droit (ou un Ctrl+clic sur un Mac), et choisir Nouveau puis Classe dans le menu contextuel. Ce menu peut également être ouvert via le raccourci

clavier Alt+Maj+N (ou Option+touche Pomme+N sur un Mac). Le choix vous appartient. 6. Dans le champ Nom (Name) de la boîte de dialogue Nouvelle classe Java, saisissez le nom que voulez donner à votre classe. Pour cet exemple, j’ai choisi MaPremiereClasseJava, sans espaces entre les mots (reportez-vous à la Figure 3.9). Le nom que vous indiquez dans la boîte de dialogue Nouvelle classe Java ne doit comporter aucune espace. Et le seul signe de ponctuation autorisé est le trait de soulignement (_). MaPremiereClasseJava ou Ma_Premiere_Classe_ Java sont valides, mais pas Ma Premiere Classe Java. 7. Cochez la ligne qui indique public static void main(String[] args). De cette manière, vous indiquez à Eclipse que vous voulez créer un code Java passe-partout. 8. Acceptez les propositions par défaut pour toutes les autres options de la boîte de dialogue. Dit autrement, il vous suffit de cliquer sur Terminer.

Comme indiqué plus haut, vous pouvez parfaitement ignorer le message d’avertissement affiché en haut de la boîte de dialogue. Vous revenez à l’espace de travail d’Eclipse. Votre projet MonPremierProjet contient maintenant un fichier appelé MaPremiereClasseJava.java. Pour vous faciliter la tâche, ce fichier contient déjà quelques lignes de code, ce que vous montre l’éditeur d’Eclipse (voir la Figure 3.10).

FIGURE 3.10

Eclipse a placé quelques lignes de code dans l’éditeur.

9. Remplacez la ligne de code par défaut par votre propre code Java. À titre d’exemple, vous allez changer la ligne qui débute par TODO : // TODO Stub de la méthode généré automatiquement

Écrivez ceci à la place : System.out.println("Chocolat, argent, sommeil"); Copiez le code exactement comme vous le voyez sur le Listing 3.1. •

Écrivez chaque mot comme sur le Listing 3.1, sans rien y changer.



Tapez les majuscules et les minuscules exactement comme sur le Listing 3.1.



Incluez tous les symboles de ponctuation : les points, les guillemets, le point-virgule, tout.



Veillez à bien faire la différence entre la lettre l minuscule et le chiffre 1. Le mot println signifie imprimer une ligne entière (print line). Toutes les lettres sont en minuscules. Il n’y a aucun chiffre.

LISTING 3.1 Un

programme qui affiche des choses

que j’aime. public class MaPremiereClasseJava { public static void main(String[] args) {

System.out.println("Chocolat, argent, sommeil"); } } Java est sensible à la casse, autrement dit à la présence des majuscules et des minuscules. De ce fait, System.out.printLn et system.out.println sont différents. Si vOus taPez system.out.printLn, voTre pRoGramme nE fonCtioNneRa pAs. Veillez donc à bien saisir votre code exactement comme sur le Listing 3.1.

IL EST FORMATÉ OU PAS, MON PROGRAMME JAVA ? Lorsque vous utilisez l’éditeur d’Eclipse pour écrire un programme Java, vous voyez des mots s’afficher dans différentes couleurs. Certains sont en bleu. D’autres sont toujours noirs. Il y a même des phrases en gras ou en italique. Vous pourriez croire qu’il s’agit d’un formatage, mais pas du tout. Il s’agit d’une technique de coloration, ou de mise en surbrillance, de la syntaxe. Il faut bien faire la différence entre un éditeur de code et un traitement de texte : » Avec Microsoft Word, par exemple, les mots que vous mettez en caractères gras sont enregistrés dans le document avec cette mise en forme. » Avec un éditeur de programme Java, aucune mise en forme n’est enregistrée dans le fichier. C’est l’éditeur luimême qui décide d’afficher chaque mot d’une manière qui rend le programme Java plus facile à lire et à comprendre. En Java, certains mots (comme class, public ou void) ont une signification bien particulière. L’éditeur d’Eclipse les affiche donc également d’une manière spécifique, en l’occurrence dans un ton rouge et en gras. Mais lorsque je sauvegarde mon programme Java dans un fichier, rien n’est

enregistré en rouge ou en gras. C’est simplement l’éditeur qui en décide ainsi lorsque le fichier est ouvert. Certains autres éditeurs pourraient très bien afficher les mêmes termes en bleu. Et si vous utilisiez un outil tel que le Bloc-Notes de Windows pour écrire vos programmes, tout resterait désespérément noir. Ne confondez pas guillemets droits ("), et les guillemets dits français (« »). Dans un programme Java, les premiers sont bons. Les autres sont une source de problèmes. Si vous avez reproduit correctement le Listing 3.1, vous devriez obtenir le même résultat que sur la Figure 3.11.

FIGURE 3.11

Un programme Java dans l’éditeur d’Eclipse.

Si vous avez fait une erreur dans votre saisie, vous allez voir dans l’éditeur des mots soulignés d’un trait rouge ondulant, de petits rectangles marqués d’une croix, ou d’autres marques rouges (voir la Figure 3.12).

FIGURE 3.12

Ce programme Java contient une faute de frappe.

Les marques rouges dans l’éditeur d’Eclipse signalent des erreurs de compilation dans votre code. Il s’agit d’une erreur qui empêche l’ordinateur de traduire votre code (revoyez à ce sujet le Chapitre 1). L’erreur signalée sur la Figure 3.12 se trouve à la ligne 5 du programme Java. Les numéros des lignes apparaissent dans la marge gauche de l’éditeur. Pour les afficher, ouvrez la boîte de dialogue Préférences (depuis le menu Fenêtre ou Eclipse selon le système). Choisissez ensuite Généralités ->

Éditeurs -> Éditeurs de texte. Cochez l’option qui indique Afficher les numéros de ligne (Show Line Numbers). Pour corriger les erreurs de compilation, vous devez vous transformer en super détective. Vous ne trouvez que rarement le coupable du premier coup. La plupart du temps, vous devrez passer votre code au peigne fin en faisant attention à tous les indices. Comparez tout ce que vous voyez dans l’éditeur avec le Listing 3.1, caractère par caractère. N’omettez aucun détail, y compris l’orthographe et la ponctuation. Vérifiez tout particulièrement l’emploi des majuscules et des minuscules. Eclipse est bien entendu là pour vous aider à trouver l’origine d’une erreur de compilation. Par exemple, vous pouvez placer le pointeur de la souris au-dessus du mot souligné en rouge. Vous allez alors voir s’afficher une brève explication sur la cause de l’erreur, ainsi que des suggestions pour la réparer. C’est ce qu’Eclipse appelle des correctifs à chaud, ou quick fixes (voir la Figure 3.13).

FIGURE 3.13

Eclipse vous propose des suggestions utiles.

Sur la Figure 3.13, la fenêtre d’information vous indique que le mot system ne peut pas être résolu. Si vous faites défiler la liste des correctifs, vous allez trouver un lien qui vous propose de remplacer system par System. Cliquez sur ce lien, et le code incorrect de la Figure 3.12 redevient le code correct de la Figure 3.11. 10.Apportez les modifications ou les corrections voulues dans l’éditeur d’Eclipse.

Quand vous ne voyez plus de lignes rouges ondulantes et autres signaux inquiétants, vous êtes prêt à essayer d’exécuter le programme. 11.Cliquez dans l’éditeur ou sur la ligne MaPremiereClasseJava.java dans l’Explorateur de packages. 12.Cliquez sur l’option Exécuter dans le menu de même nom. Et c’est tout… Votre nouveau programme Java est exécuté dans la console d’Eclipse. Trois mots vont s’afficher dans cette fenêtre, comme l’illustre la Figure 3.14. Les portes du paradis vous sont ouvertes !

FIGURE 3.14

Le programme du Listing 3.1 est exécuté.

DES ERREURS À GOGO ? Corriger toutes les erreurs qui se manifestent par un trait rouge ondulé de soulignement peut donner l’impression que tout est pour le mieux dans le meilleur des mondes. Eclipse aime l’aspect de votre code, et vous pensez que tout va bien se passer. En fait, ce n’est pas si simple. En plus des erreurs de compilation déjà rencontrées, votre code peut poser d’autres problèmes moins évidents à détecter. Imaginez que quelqu’un vous dise  : «  Allez jusqu’à l’intersection puis dournez à troite  ». Vous remarquez immédiatement qu’il y a un souci et vous répondez poliment «  Pardon  ?  ». Ce «  Pardon  ?  », c’est comme la ligne rouge ondulée dans l’éditeur d’Eclipse. En tant qu’humain doué d’intelligence et de compréhension, vous êtes certainement capable de saisir le sens de la phrase prononcée par votre interlocuteur. Mais l’éditeur d’Eclipse, de son côté, ne se permet jamais de corriger vos erreurs sans vous demander de lui expliquer ce qu’il doit faire. En plus des erreurs de compilation, d’autres types de « gremlins » peuvent se cacher dans un programme Java : » Exceptions lors de l’exécution  : Vous n’avez aucune erreur de compilation, mais, lorsque vous exécutez votre programme, celui-ci se termine prématurément. À un certain moment, vos instructions demandent à Java

quelque chose qu’il ne peut pas faire. Supposons par exemple

que,

dans

notre

programme

de

remboursement d’emprunt, vous tapiez en réponse à la première question  200000,00. Java n’aime pas les virgules dans les nombres. Votre programme plante donc, et un message angoissant apparaît, comme sur la Figure 3.A (page suivante). C’est un peu comme si quelqu’un vous disait de tourner à droite à l’intersection, alors qu’il n’y a à cet endroit qu’un mur de briques. L’éditeur d’Eclipse ne vous prévient pas à l’avance, car il ne peut pas prédire si et quand cette exception va se produire. » Erreurs de logique  : Là encore, aucun marqueur n’apparaît dans l’éditeur d’Eclipse. De plus, votre programme peut parfaitement s’exécuter jusqu’au bout. Mais la réponse qu’il fournit est incorrecte. Sur la Figure  3.B, le programme vous indique que vous devriez payer chaque mois 1035  616,57  € pour rembourser votre maison. Il y a comme un problème  ! C’est un peu comme si on vous disait de tourner à droite et que vous bifurquiez sur la gauche. Vous pouvez alors conduire dans la mauvaise direction pendant très longtemps…

Les erreurs de logique sont les plus difficiles à trouver et à corriger. Et, pire que tout, elles peuvent parfaitement passer inaperçues. Il y a quelques années de cela, j’ai reçu une facture de chauffage de plusieurs centaines de milliers de dollars. Lorsque j’ai appelé la compagnie du gaz pour protester, le type que j’ai eu au bout du fil m’a répondu : « Calmez-vous. Payez la moitié ce mois-ci et demandez un échelonnement. » » Avertissements au moment de la compilation  : Ce n’est pas aussi violent qu’un message d’erreur. Lorsque Eclipse remarque quelque chose qui ne lui paraît pas normal dans votre programme, l’éditeur le souligne d’un trait ondulé, mais qui est cette fois jaune. Sur la Figure  3.C, par exemple, j’ai ajouté au Listing  3.1  quelque chose qui indique qu’un montant est égal à 10 (c’est sur la ligne 4). Le problème, c’est que le mot montant, pas plus que la valeur 10, n’est jamais utilisé ailleurs dans le code du programme. En soulignant ce mot en jaune, Eclipse m’indique à peu près ceci : « D’accord, votre montant = 10 ne mérite pas de tout arrêter. Je peux quand même exécuter votre programme. Mais êtes-vous vraiment certain que vous voulez garder montant = 10 ? Ce truc semble ne servir à rien. »

Imaginez qu’on vous dise  : «  Tournez quand vous arrivez à l’intersection  ». Il n’y a rien de faux dans cette phrase. Mais vous allez bien sûr répondre : « Et je dois tourner dans quelle direction ? À gauche ou à droite ? » Si vous êtes sûr de savoir ce que vous faites, vous pouvez ignorer ces avertissements et y revenir plus tard. Mais il peut aussi s’agir d’une alerte qui recouvre un problème plus sérieux dans votre code. C’est pourquoi je vous recommande de faire bien attention à ces avertissements. Pour autant, si vous n’arrivez pas à comprendre ce qui ne va pas, ne vous laissez pas bloquer et continuez à aller de l’avant.

FIGURE 3.A

FIGURE 3.B

FIGURE 3.C

C’est quoi toutes ces choses dans la fenêtre d’Eclipse ? Une

langue

évolue

et

de

nouveaux

mots

apparaissent sans cesse. Comme aurait pu le dire ce bon Monsieur de la Palisse : « On ne disait pas ces mots-là parce qu’ils n’existaient pas. » Je vais donc dans ce qui suit vous proposer des termes qui risquent fort de sonner comme des nouveautés à vos oreilles. Mais avant de nous attaquer à la terminologie d’Eclipse, il convient d’éclaircir certains points : » Lire cette section est un exercice facultatif. Vous pouvez y revenir plus tard si vous avez des difficultés à comprendre certaines instructions données dans ce livre. Mais si vous vous sentez à

l’aise avec l’interface d’Eclipse, ne vous compliquez pas l’existence inutilement. » Cette section donne des explications sur un certain nombre de termes, pas des définitions formelles de ceux-ci. Oui, mes explications sont plutôt précises, et non, elles ne sont ni exhaustives, ni hermétiques. Pratiquement chaque description de cette section a des exceptions cachées, des omissions, des exemptions et des exclusions (je viens d’atteindre les limites de mon vocabulaire). Prenez ce qui suit comme un guide touristique, pas comme un contrat légal. » Eclipse est un outil extrêmement utile. Mais ce n’est pas un composant officiel de l’écosystème Java. En fait, vous pouvez parfaitement écrire des programmes Java sans jamais utiliser Eclipse (mais, de mon point de vue, c’est moins pratique).

Eclipse, les généralités Votre visite panoramique d’Eclipse débute par un survol général (avec un œil d’aigle ou un drone équipé d’une caméra, au choix) :

» Espace de travail (ou workbench) : C’est le bureau d’Eclipse (revoyez la Figure 3.3), autrement dit l’environnement dans lequel vous développez votre code. » Aire : Une section de l’espace de travail. Pour illustrer cela, j’ai repris la Figure 3.3 en encadrant chacune des cinq aires visibles (voir la Figure 3.15).

FIGURE 3.15

L’espace de travail est divisé en plusieurs aires.

» Fenêtre : Une copie de l’espace de travail d’Eclipse. Vous pouvez ouvrir en même temps plusieurs copies de cet espace de travail. Chaque copie apparaît dans sa propre fenêtre.

» Action : C’est un choix qui s’offre à vous, typiquement quand vous cliquez sur quelque chose. Par exemple, si vous cliquez sur la commande Nouveau dans le menu Fichier, vous voyez toute une liste d’éléments que vous pouvez créer. Vous y trouvez des options plutôt classiques comme Projet, Fichier, Dossier voire Autre, et d’autres beaucoup plus spécifiques, comme Classe ou encore Interface. Chaque élément d’un tel menu est appelé une action.

Vues, éditeurs et autres La prochaine série de termes traite de choses que l’on appelle vues, éditeurs et onglets. Comprendre la différence entre vues et éditeurs n’est pas donné immédiatement. En gros, une vue est comme un éditeur, qui est comme une vue, ou quelque chose dans ce genre. Si vues et éditeurs vous semblent être équivalents, ne vous tracassez pas avec cette affaire. Vous comprendrez mieux la distinction entre les deux au fil du temps, en vous familiarisant avec l’espace de travail d’Eclipse. En fait, vous avez rarement à vous demander si la chose que vous utilisez est une vue ou un éditeur.

Et si vous avez besoin d’en savoir plus, par exemple pour briller dans une soirée geek, lisez ce qui suit : » Vue : Une partie de l’espace de travail d’Eclipse qui affiche des informations parmi lesquelles vous pouvez naviguer. Dans le cas le plus simple, une vue occupe une aire dans l’espace de travail. Par exemple, l’Explorateur de packages est une vue qui remplit la partie la plus à gauche de la fenêtre d’Eclipse. De nombreuses vues affichent des informations sous la forme de listes ou d’arborescences. Comme nous l’avons déjà noté, l’Explorateur de packages contient l’arborescence des projets définis dans l’espace de travail courant. Vous pouvez utiliser une vue pour modifier certaines choses. Regardez la Figure 3.10. Vous y voyez un projet appelé UnAutreProjet (pourquoi pas ?). Supposons que nous voulions le supprimer. Il suffit pour cela de faire un clic droit (ou un Ctrl+clic sur un Mac) sur cette ligne et de choisir l’action Supprimer (Delete) dans le menu contextuel qui apparaît. Lorsque vous utilisez une vue pour changer quelque chose, le changement est

immédiatement appliqué. Dans l’exemple cidessus, la suppression du projet serait ferme et définitive. Mais c’est un comportement classique sur les ordinateurs. » Éditeur : Une partie de l’espace de travail d’Eclipse qui affiche des informations que vous pouvez modifier. Un éditeur typique affiche ces informations sous forme de texte. Il peut s’agir du contenu d’un fichier. Ainsi, sur la Figure 3.10, un éditeur affiche le contenu du fichier MaPremiereClasseJava. java. Lorsque vous changez quelque chose dans un éditeur, la modification n’est pas appliquée immédiatement. Revenons une fois de plus à la Figure 3.10. Vous pouvez taper ce que vous voulez dans l’éditeur. Mais rien ne se produit de particulier tant que vous ne cliquez pas sur le bouton Enregistrer de la barre d’outils d’Eclipse, ou que vous choisissez Enregistrer (Save) dans le menu Fichier, ou encore tant que vous n’exécutez pas le programme (auquel cas Eclipse va enregistrer au préalable le fichier). Là encore, ce type de comportement est classique : vous le retrouvez dans Microsoft Word et dans des tas d’autres applications.

D’accord, je vous ennuie avec tout ce vocabulaire, et je sais par avance que, dans ce livre, il m’arrivera d’employer le mot vue alors qu’il aurait fallu dire éditeur. Mais, en règle générale, je m’efforce de respecter la terminologie officielle d’Eclipse. Donc les vues comme les éditeurs sont des parties de l’espace de travail d’Eclipse. Malheureusement, ce terme de « parties » n’est pas très évocateur pour la plupart des gens. Une aire de l’espace de travail d’Eclipse peut contenir plusieurs vues ou plusieurs éditeurs. Mais, dans ces vues et ces éditeurs, un autre type d’objet vient s’insérer : les onglets (tab)… » Onglet : Comment décrire un onglet, si ce n’est en disant que c’est un… onglet. Ce qu’il est important de retenir, c’est que les vues peuvent être empilées les unes sur les autres. Eclipse affiche ces vues empilées comme s’il s’agissait de pages dans un carnet à onglets. Sur la Figure 3.14, par exemple, on peut remarquer la présence de quatre vues : Problèmes, Javadoc, Déclaration et Console. Chaque vue possède son propre onglet. Une pile de vues est appelée un groupe d’onglets. Pour placer une vue au premier plan, vous cliquez

simplement sur son onglet. Évidemment, tout ce qui vient d’être du dit sur les vues et les onglets s’applique de la même manière aux éditeurs. Par exemple, l’aire illustrée sur la Figure 3.16 contient trois éditeurs empilés (et non trois onglets qui appartiendraient à un même éditeur).

FIGURE 3.16

L’aire de l’éditeur contient en fait trois éditeurs empilés.

» Vue active ou éditeur actif : Dans un groupe d’onglets, c’est la vue ou l’éditeur qui se trouve en haut de la pile. Sur la Figure 3.16, l’éditeur actif s’appelle MaPremiereClasseJava.java. Les deux autres sont inactifs.

Que trouve-t-on dans une vue ou un éditeur ?

Voyons maintenant de plus près ce que l’on trouve dans les vues individuelles, les éditeurs individuels et dans les aires individuelles. » Barre d’outils : C’est la barre de boutons (et autres petites choses) qui apparaît en haut d’une vue (voir la Figure 3.17). » Bouton Menu : Un bouton d’une barre d’outils qui affiche une flèche pointant vers le bas. Lorsque vous cliquez sur ce genre de bouton, une liste d’actions apparaît (voir la Figure 3.18). Bien entendu, les actions proposées varient d’une vue à une autre. » Bouton Fermer : Un bouton qui, comme son nom l’indique, referme une vue ou un éditeur particulier (voir la Figure 3.19).

FIGURE 3.17

La barre d’outils dans la vue Explorateur de packages.

FIGURE 3.18

Le bouton Menu de la vue Explorateur de packages.

FIGURE 3.19

Le bouton Fermer d’un éditeur.

» Chevron : Il s’agit d’une double flèche qui indique qu’un autre onglet devrait apparaître dans une certaine aire, mais que celle-ci n’est pas assez large pour tout afficher. Sur la Figure 3.20, vous remarquez que le chevron situé à droite des onglets de l’éditeur affiche le chiffre 2. Cela vous

indique qu’il y a deux onglets masqués faute de place. En cliquant sur ce chevron, vous pouvez révéler la liste des noms des onglets disponibles.

FIGURE 3.20

Le chevron indique que deux éditeurs sont masqués.

» Barre des marqueurs : La règle verticale qui est affichée à gauche de l’aire d’un éditeur. Eclipse y affiche de petites icônes, ou marqueurs. Vous en voyez un exemple sur la Figure 3.12.

Retour au survol général Les deux termes décrits ici concernent l’aspect général d’Eclipse. » Disposition : Un arrangement de certaines vues. Sur la Figure 3.3, par exemple, Eclipse contient sept vues, dont quatre sont facilement visibles :



À gauche, vous trouvez la vue Explorateur de packages.



Tout à fait à droite se trouvent les vues Liste des tâches (Task List) et Structure (Outline).



En bas, vous disposez des vues Problèmes, Javadoc, Déclaration et Console.

En plus de ces vues, vous trouvez une unique aire pour le ou les éditeurs. Tous les éditeurs s’ouvrent dans cette aire. » Perspective : C’est une disposition très pratique à laquelle un nom a été donné. Par exemple, la disposition illustrée sur la Figure 3.3 s’appelle tout simplement Java. Mais il en existe bien d’autres. Par défaut, la perspective Java contient six vues disposées à peu près comme sur la Figure 3.3. La vue Console n’apparaît pas toujours dans la perspective Java. Normalement, elle s’ouvre automatiquement lorsque vous exécutez un programme Java en mode texte. Si vous voulez forcer l’activation de cette vue, ouvrez le menu Fenêtre (ou Eclipse selon le système), puis cliquez sur Afficher la vue (Show View) suivi de Console. Si vous avez l’esprit d’aventure, vous pouvez également choisir Autre (Other). Dans la boîte de

dialogue qui apparaît, développez la branche Généralités (General). Faites ensuite un double clic sur la ligne Console. En même temps que toutes ces vues, la perspective Java contient une aire pour l’éditeur. Certes, cette aire affiche le plus souvent plusieurs onglets, mais le nombre de ces onglets n’a rien à voir avec la perspective elle-même. Vous pouvez passer d’une perspective à une autre en choisissant dans le menu Fenêtre l’option Perspective, puis Ouvrir la perspective (Open Perspective). Dans ce livre, seule la perspective Java nous intéresse. Mais n’hésitez pas à visiter les autres perspectives pour mieux vous rendre compte de la puissance et de la souplesse d’Eclipse. Voici

pour

terminer

quelques

éléments

complémentaires pour vous aider à comprendre le contenu de ce chapitre. Si le fait d’essayer ces choses renforce votre confiance en vous, c’est parfait. Si essayer ces choses vous amène à vous poser des questions sur ce que vous avez lu, c’est bien aussi. Si essayer ces choses vous rend nerveux, ne vous découragez pas. Vous pourrez trouver des

réponses et d’autres aides sur le site Web de ce livre (www.allmycode.com/BeginProg).

Eclipse à la base Suivez d’abord les instructions données dans la section « Exécuter un programme Java existant » , au début de ce chapitre, puis essayez les tâches suivantes : » Assurez-vous que vous pouvez voir le code du programme de calcul de remboursement d’emprunt dans l’éditeur d’Eclipse. Si vous ne le voyez pas, recherchez 03-0-Mortgage dans la vue Explorateur de packages, sur le côté gauche de l’espace de travail d’Eclipse. Développez la branche 03-0-Mortgage jusqu’à ce que vous voyiez une ligne qui indique Mortgage.java. Faites un double clic sur ce nom. » Dans l’éditeur d’Eclipse, apportez des modifications au texte dans le programme de calcul de remboursement d’emprunt. Annulez ensuite ces modifications en sélectionnant Éditer > Annuler dans le menu principal d’Eclipse. » Recherchez l’onglet Console dans la partie inférieure de l’espace de travail d’Eclipse. Si vous

ne voyez pas cet onglet, faites-le apparaître en sélectionnant Fenêtre -> Afficher la vue -> Console depuis le menu principal d’Eclipse. Si cela ne fonctionne pas, essayez Fenêtre -> Afficher la vue > Autre. Dans la boîte de dialogue qui apparaît, double-cliquez sur l’élément Généralités -> Console. » L’espace de travail d’Eclipse comporte plusieurs zones. Utilisez la souris pour faire glisser les limites entre ces zones (et donc les redimensionner). Pour rétablir les zones telles qu’elles étaient avant ce redimensionnement, sélectionnez Fenêtre -> Perspective -> Réinitialiser la perspective dans le menu principal d’Eclipse. » L’espace de travail d’Eclipse a plusieurs perspectives différentes. Dans ce livre, vous utilisez la perspective Java. Passez temporairement à la perspective de débogage en sélectionnant Fenêtre -> Perspective -> Ouvrir la perspective -> Déboguer dans le menu principal d’Eclipse. Remarquez comment les zones et les vues de l’espace de travail changent. Revenez à la perspective Java en sélectionnant Fenêtre -> Perspective -> Ouvrir la perspective -> Perspective -> Java dans le menu principal

d’Eclipse. (Si, pour une raison quelconque, Java ne figure pas parmi les choix proposés, sélectionnez Autre et recherchez Java dans la boîte de dialogue qui apparaît.)

Expérimenter avec les messages d’erreur Suivez d’abord les instructions données dans la section « Exécuter un programme Java existant » . Recherchez la branche 03-01 dans l’Explorateur de packages d’Eclipse. Développez cette branche pour localiser la ligne MaPremiereClasseJava. java. Faites un

double

clic

sur

MaPremiereClasseJava

ce

nom.

apparaît

Le

code

dans

pour

l’éditeur

d’Eclipse. » Dans l’éditeur d’Eclipse, changez la lettre c minuscule dans le mot class en une majuscule C. Remarquez que des marques rouges apparaissent sous ce mot. Ces marques colorées indiquent que votre programme comporte une erreur de compilation. Java est sensible à la casse. Ainsi, dans un programme Java, le mot Class (avec une lettre C majuscule) ne signifie pas la même chose que le mot class (avec une lettre c minuscule).

Il y a quelques endroits dans le projet 03-01 où une telle modification ne causera pas d’erreurs. Mais, pour la plus grande partie du texte, un changement de minuscule en majuscule (ou l’inverse) entraîne l’apparition d’avertissements d’erreur en rouge dans l’éditeur d’Eclipse. » Toujours dans l’éditeur d’Eclipse, changez System.out.println("Chocolat, argent, sommeil") ; en System.out.println(6/0) ; Aucun marqueur d’erreur n'apparaît dans l’éditeur. Mais, lorsque vous essayez d’exécuter le programme, vous voyez du texte rouge dans la vue Console. Le message indique qu’une exception d’exécution est survenue. Cette exception se produit parce que Java ne peut pas diviser un nombre par 0 (pas plus que vous ou moi).

PARTIE 2 Écrire vos propres programmes Java DANS CETTE PARTIE… Disséquer les programmes et en examiner les morceaux Travailler avec les nombres Travailler avec des choses qui ne sont pas des nombres

Chapitre 4

Explorer les parties d’un programme DANS CE CHAPITRE : » Identifier les mots dans un programme Java » Utiliser la ponctuation et l’indentation » Comprendre les instructions et les méthodes Java

travaille dans une université à dominante J escientifique. Chaque fois que je passe devant le laboratoire de biologie, je murmure un mot de remerciement.

Heureusement,

je

n’ai

pas

à

disséquer de petits animaux. À la place, je dissèque des programmes informatiques. Pas de formol, pas d’instruments tranchants. Un ordinateur, ça ne se dissèque pas, ça se recycle… Dans ce chapitre, je vous invite à disséquer un programme avec moi. C’est en fait un petit programme que j’ai appelé ThingsILike (des choses

que j’aime, si vous préférez). Préparez votre scalpel et partons ensemble à la découverte des entrailles de l’animal !

Code Java, première découverte J’ai une confession à vous faire. La première fois que j’ai regardé un programme écrit par quelqu’un d’autre, j’ai trouvé cela indigeste. Réaliser que je ne comprends pas quelque chose (ou beaucoup de choses) dans le code me rend nerveux. J’ai écrit des centaines,

peut-être

même

des

milliers

de

programmes, mais je ne me sens jamais en sécurité lorsque je commence à lire le code d’un autre programmeur. Étudier un programme informatique est pour moi une expérience presque existentielle. Je commence par y jeter un coup d’œil craintif. Ensuite, je le lance pour voir ce qu’il fait. Puis je regarde le code pendant un certain temps ou je lis les explications laissées par l’auteur de ce code. Après quoi je commence à me dire qu’il faut bien se jeter à l’eau, et je lance à nouveau le programme. Eh oui, c’est ainsi. Ne croyez pas ceux qui vous disent qu’ils n’ont pas besoin de passer par toutes ces étapes.

Même les programmeurs chevronnés approchent un nouveau projet lentement et avec précaution.

Regardez ! C’est un programme ! Sur le Listing 4.1, vous pouvez voir un morceau de code Java. Comme tous les programmeurs novices, vous êtes censé rester bouche bée et prendre une posture humble. Mais ne soyez pas intimidé. Une fois que

vous

en

aurez

compris

le

sens,

vous

commencerez à trouver que programmer n’est pas si difficile que cela. Et c’est aussi amusant, croyezmoi. LISTING

4.1 Un programme Java très simple.

/* * Un programme pour lister les bonnes choses de la vie * Auteur: Barry Burd, [email protected] * 13 février 2017 */ class ThingsILike { public static void main(String args[])

{ System.out.println("Chocolat, argent, sommeil"); } } Si je lance ce programme dans Eclipse, j’obtiens le résultat montré sur la Figure  4.1. L’ordinateur affiche les mots Chocolat,

argent,

sommeil.

Maintenant, je dois bien admettre qu’écrire et exécuter un programme Java juste pour afficher ces mots, c’est quand même pas mal de travail pour si peu. Mais il faut bien commencer par quelque chose. Les exemples proposés dans ce livre sont des programmes en mode texte. Toutes leurs entrées et leurs sorties s’effectuent donc via la vue Console d’Eclipse. Le développement de programmes avec une interface graphique, avec des fenêtres, des boutons et autres extras c’est le sujet d’un autre livre  ! Il faut bien commencer par apprendre les bases de la peinture avant de songer à exposer ses toiles dans une galerie, n’est-ce pas ? Pour autant, je n’oublie pas ce sujet si important, et vous pourrez voir une version avec interface utilisateur graphique du Listing  4.1, comme d’ailleurs d’une

douzaine d’autres exemples de ce livre sur mon site Web. Voyez pour cela l’adresse :

FIGURE 4.1

Exécution du programme présenté sur le Listing 4.1.

https://users.drew.edu/bburd/BeginProg/in dex.html Cliquez sur le lien GUI Versions pour télécharger l’archive

correspondante,

qu’il

vous

suffira

d’installer directement dans un espace de travail adapté d’Eclipse (reportez-vous au Chapitre  2  si vous avez oublié comment procéder). Pour exécuter le code du Listing  4.1, suivez ces étapes : 1. Reportez-vous si nécessaire au Chapitre 2 pour installer Eclipse. 2. Suivez ensuite les instructions données dans la première partie du Chapitre 3. Ces

instructions

vous

ont

expliqué

comment

exécuter un projet appelé  03-01. Cette fois, vous

devez

suivre

la

même

procédure,

mais

pour

exécuter le projet appelé 04-01.

Ce que disent les lignes du programme Si le programme du Listing 4.1 devient célèbre, il se trouvera peut-être un historien du futur pour en écrire l’histoire. Mais, en réalité, le résumé de ce livre pourrait être très court, car toute l’affaire peut se définir en une phrase : Afficher Chocolat, argent, sommeil sur l’écran de l’ordinateur. Comparez cette phrase avec le Listing  4.1. Ce dernier comporte bien plus de lignes. Vous pouvez donc penser que ce surcroît de texte n’a pas grand intérêt. Et vous n’avez pas tort. Vous pouvez parfaitement

écrire

un

programme

Java

sans

aucune fioriture. En fait, le même listing pourrait être réécrit d’une manière un peu plus romanesque, par exemple comme ceci : Un programme pour lister les bonnes choses de la vie. Il a été écrit le 13 février 2017 par

Barry Burd. Barry comprend que vous pouvez avoir des questions à lui poser sur ce code. Vous pouvez donc le contacter à l’adresse [email protected], ou bien sur Twitter à l’adresse @allmycode, ou encore sur Facebook (/allmycode). Ce code définit une classe Java appelée ThingsILike. La partie principale (main) des instructions indique : Afficher Chocolat, argent, sommeil sur l’écran. Le reste de ce chapitre explique le code du Listing 4.1 plus en détail.

Les éléments d’un programme Java Le fait que l’anglais (ou le français) et Java soient appelés des langues (ou des langages) n’est pas un hasard. Votre langue maternelle vous permet de communiquer avec des gens. Et Java vous permet de communiquer avec des ordinateurs. Dans tous

les cas, ce langage est basé sur des mots, des noms ou encore des signes de ponctuation. En réalité, la grande différence, c’est que Java est plus facile à apprendre que l’anglais ou le français (si ces langues étaient simples, cela ferait longtemps que les ordinateurs seraient parfaitement capables de les comprendre). Prenons une phrase simple en langage courant et comparons-la avec le Listing 4.1 : Suzanne dit "eh" parce que, comme vous le savez, elle vit au Canada. Au cours de vos études, vous avez appris des mots comme

verbe,

adjectif

et

d’autres

trucs

de

grammaire pas très amusants. Mais, dans ce livre, vous allez devoir penser en termes de mots-clés et d’identificateurs. C’est ce que vous explique la Figure 4.2. La phrase qui décrit Suzanne contient, comme vous pouvez le constater, un nombre assez incroyable de composants. Et voici le plan d’action que je vous propose 

;

comparez

les

éléments

de

la

Figure  4.1  avec les éléments semblables sur le Listing  4.1. Si vous maîtrisez un tant soit peu l’anglais, le parallèle ne devrait pas être trop

difficile

à

établir,

et

cela

va

vous

aider

à

comprendre quelques notions essentielles sur Java.

FIGURE 4.2

Décomposer une phrase simple.

Mais commencez par retenir ceci  : je vous ai plus haut proposé une comparaison entre l’anglais (et le français bien sûr, mais il ne va pas vous servir beaucoup, hormis à rédiger vos commentaires) et Java.

Par

exemple,

votre

dictionnaire

sait

certainement bien des choses sur le chocolat, l’argent et le sommeil. Mais là n’est pas le problème. Que sait-il par contre sur les mots main, public ou void ? C’est une autre affaire. Alors, poursuivons. On reste bons amis, n’est-ce pas ?

Mots-clés

Un mot-clé est un mot qui appartient à un dictionnaire, autrement dit qui est un élément constitutif d’une langue. Sur la Figure  4.2, un mot tel que «  dit  » est un mot-clé, car il joue le même rôle chaque fois qu’il est employé dans une phrase en français. Les autres mots-clés de cet exemple sont «  parce que  » , «  comme  » , «  vous  » , «  le  » , «  savez  » , « elle », « vit » et « au ». Les programmes informatiques ont eux aussi des mots-clés.

En

fait,

le

programme

du

Listing 4.1 contient quatre mots-clés Java, ceux qui sont mis ici en caractères gras : class ThingsILike { public static void main(String args[]) { Chaque

mot-clé

Java

a

une

signification

particulière, signification qui reste inchangée d’un programme à un autre. Par exemple, le mot-clé public

signale

toujours

une

partie

d’un

programme qui est accessible à n’importe quel autre morceau de code.

N’oubliez pas, n’oubliez jamais, que Java est un programme sensible à la casse. Autrement dit, il différencie les majuscules et les minuscules. Si, dans le Listing 4.1, vous écrivez Public à la place de public, le programme cessera immédiatement de fonctionner. Ce chapitre ne vous explique pas particulièrement ce que signifient les mots-clés class, public, static et void. Vous pouvez vous référer aux explications fournies dans d’autres chapitres, ou faire un peu de recherche dans la documentation de Java, ou encore tricher un peu. Lorsque vous écrivez un programme, commencez simplement par : class CeciOuCela { Puis collez le texte suivant dans votre code : public static void main(String args[]) { Pour vos premiers programmes, cette stratégie sera parfaite. Le Tableau  4.1  vous livre une liste complète des mots-clés Java. En Java, les mots true (vrai), false (faux) et null (nul) ont une signification particulière. Comme les

mots-clés du Tableau  4.1, vous ne pouvez pas les utiliser pour autre chose que ce pour quoi ils sont conçus. Mais, pour des raisons qui ne regardent que les experts en Java les plus pointilleux, ils ne sont pas appelés des mots-clés. D’une manière ou d’une autre, si vous ajoutez ces mots à la liste du Tableau 4.1, personne, et surtout pas moi, ne vous en tiendra rigueur. Voici une notion que vous devez retenir à propos des mots-clés Java  : chaque mot-clé a une signification officielle, prédéfinie. Les types de chez Oracle, qui ont le dernier mot sur tout ce qui concerne le langage Java, ont créé tous ces motsclés. Le dictionnaire grammatical de Java, c’est eux, et vous ne pouvez pas réécrire ce dictionnaire à votre convenance. Par exemple, il est interdit d’employer le mot-clé public dans un calcul : TABLEAU

4.1

Mots-clés Java.

abstract continue for

new

switch

assert

goto

package

synchronized

boolean do

if

private

this

break

implements protected throw

default

double

byte

else

import

public

throws

case

enum

instanceof

return

transient

catch

extends

int

short

try

char

final

interface

static

void

class

finally

long

strictfp

volatile

const

float

native

super

while

//Ceci est du TRÈS, TRÈS MAUVAIS CODE : public = 6; Si vous tentez d’utiliser un mot-clé de cette manière, le compilateur va afficher un message d’erreur et refuser de traduire votre code source. Imaginez ceci : M. et Mme Gérard ont un fils qu’ils appellent Lamentable. «  Et maintenant, applaudissez très fort notre maître de cérémonie, Lamentable Gérard ! » Le pauvre enfant n’aura jamais une vie normale… En fait, il y a deux mots-clés Java qui n’ont aucun sens dans un programme. Ce sont const et goto. Ils sont là uniquement pour vous empêcher de les utiliser. Si vous tentez par exemple de créer une variable appelée goto, Eclipse va afficher un

message d’erreur du genre VariableDeclaratorId n’est pas valide. Les créateurs de Java indiquent poliment de cette manière que, si vous vous servez de l’un de ces mots-clés dans votre code, vous feriez mieux d’aller vous asseoir à la table des programmeurs en C++.

Identificateurs que vous ou moi pouvons définir Suzanne est un joli prénom, mais personne ne vous interdit d’en fabriquer de nouveaux si le calendrier de la Poste ne vous suffit pas. Personnellement, si j’avais une fille, je l’appellerais «  Deneen  » ou «  Chrisanta  » . Et si c’était un garçon, je l’appellerais «  Belton  » ou «  Merk  » . Mais à chacun ses goûts. Un nom est un mot qui identifie quelque chose. Donc j’arrête tout de suite d’appeler ces choses des noms, et je commence à les désigner par le terme identificateurs. Un identificateur peut faire référence à une valeur, à une partie d’un programme, à un certain type de structure et à des tas d’autres choses.

Le Listing  4.1  contient deux identificateurs que vous

ou

moi

pouvons

définir

comme

nous

l’entendons. Il s’agit en l’occurrence des mots ThingsILike et args. class ThingsILike { public static void main(String args []) { De même que les noms Suzanne et Chrisanta n’ont aucune

signification

particulière

en

français,

ThingsILike et args n’ont eux non plus aucune signification particulière en Java. Sur le Listing 4.1, le premier est le nom que j’ai donné à mon programme, mais j’aurais tout aussi bien pu choisir Enzyme, Kalamazoo placer

quelque

ou IdiotStupide. Je dois chose

comme

(String

unCertainNom []) dans mon programme, mais je pourrais utiliser (String

args

[]), (String

ArgumentsLigneCommande

[]),

ou

(String

fromage []). Faites ce que je dis, pas ce que je fais… Donnez des noms explicites aux choses que vous définissez dans vos programmes Java. Par exemple, fromage fera peut-être rire dans la cour de récréation, mais

n’aidera

en

rien

à

comprendre

la

stratégie

développée dans votre programme. Des termes comme public, class ou void sont des mots-clés Java. Il est donc interdit de les employer pour nommer quelque chose. Le mot args

dans (String

args

[])

peut

contenir des informations supplémentaires que vous

fournissez

lorsque

vous

exécutez

un

programme Java. Par exemple, si vous lancez le programme en tapant une ligne de commande qui indique java ThingsILike un deux 3, alors args va contenir les valeurs un, deux et  3. En tant que débutant, vous n’avez pas à vous préoccuper particulièrement

de

cette

fonctionnalité.

Contentez-vous de coller (String args []) dans tous vos programmes sans vous poser de questions.

Identificateurs ayant un sens particulier De nombreuses personnes peuvent avoir pour prénom Suzanne, mais un seul pays s’appelle le Canada. Si on vous dit «  Canada  » , vous pensez immédiatement au pays dont le drapeau est frappé d’une feuille d’érable rouge. Si vous créez un jour

votre propre pays, vous ne l’appellerez pas Canada, car plus personne ne s’y retrouverait (il est vrai qu’il existe aux États-Unis un lieu appelé Canada dans l’État du Kentucky, mais cela ne compte pas). La plupart des langages de programmation ont des identificateurs

ayant

prédéterminée.

En

identificateurs

sont

Java,

une la

définis

signification plupart

dans

de

ces

l’API.

Le

Listing  4.1  en contient cinq, qui sont mis ici en caractères gras : public static void main ( String args[]) { System.out.println ("Chocolat, argent, sommeil"); } Voyons rapidement la signification de chacun de ces noms (qui seront décrits avec plus de précision dans d’autres chapitres de ce livre) : » main : Le point de départ principal de tout programme Java. » String : C’est du texte, c’est-à-dire une série de caractères rangés les uns à la suite des autres. » System : Un programme déjà mis en boîte dans l’API Java. Ce programme accède à certaines

fonctionnalités de votre ordinateur qui échappent au contrôle direct de la machine virtuelle Java (JVM). » out : C’est là où un programme en mode texte affiche ses sorties. Avec Eclipse, le mot out va désigner la vue Console. Reportez-vous si nécessaire au début du Chapitre 3 pour plus d’informations sur les programmes en mode texte. » println : Affiche du texte sur l’écran de votre ordinateur. Le nom println est l’abréviation de «  print a line  » (imprimer une ligne). L’avant-dernière lettre est donc bien un l minuscule. Lorsque cette instruction est exécutée, un certain texte est affiché dans la console d’Eclipse, et le curseur passe immédiatement au début de la ligne suivante, prêt pour la suite des événements. Strictement

parlant,

la

signification

des

identificateurs de l’API Java n’est pas gravée dans le marbre. Bien que vous puissiez redéfinir des mots comme System ou println, ce n’est pas une bonne

idée.

Cela

introduirait

beaucoup

de

confusion, tous les programmeurs étant habitués à

utiliser

ces

noms

familiers

en

respectant

la

définition qui en est donnée dans l’API Java.

Littéraux Un littéral est un morceau de texte qui ressemble à la valeur qu’il représente. Dans l’exemple de la Figure  4.2, «  eh  » est un littéral, car il fait référence au mot eh. Tout simplement. Les langages de programmation ont aussi des littéraux. Par exemple, dans le Listing 4.1, ce qui se trouve entre les guillemets est un littéral : System.out.println( "Chocolat, argent, sommeil" ); Lorsque cette ligne est exécutée, vous voyez s’afficher les mots Chocolat, argent et sommeil sur votre écran, mais sans les guillemets. La plupart des nombres que vous utilisez dans vos programmes sont des littéraux. Si vous écrivez l’instruction : monSalaire = 1000000.00; dans un programme, alors  1000000.00 littéral qui désigne la valeur d’un million.

est un

Si vous avez du mal à décomposer les grands nombres, vous pouvez aussi placer l’instruction suivante dans votre programme : monSalaire = 1_000_000.00; Cette syntaxe n’est autorisée que depuis Java  7. Autrement dit, elle n’était pas possible avant. Même si l’emploi de virgules n’est pas autorisé dans les littéraux numériques, vous pouvez vous servir du trait de soulignement pour séparer les groupes de chiffres. Par exemple, en Inde, les chiffres sont groupés par deux à partir des milliers. Si votre programme est destiné à être exporté vers ce pays, vous pourriez donc écrire l’affectation cidessus sous la forme monSalaire = 10_00_000.00. Vous pouvez aussi personnaliser l’affichage des nombres à l’aide des classes Java Locale

et

NumberFormat (voyez à ce sujet le Chapitre 18).

Ponctuation Un programme typique a des tas de ponctuations. Reprenons par exemple le Listing 4.1 : class ThingsILike {

public static void main ( String args []) { System.out.println ("Chocolat, argent, sommeil"); } } Chaque

crochet,

chaque

accolade,

chaque

parenthèse, chaque gribouillis quelconque jouent un rôle dans la structure et le fonctionnement du programme. En français, vous écrivez vos phrases d’un seul tenant, et vous passez à la ligne uniquement lorsque vous voulez changer de paragraphe. En programmation, vous travaillez rarement de cette manière. Au lieu de cela, la ponctuation du code guide

l’indentation

de

certaines

lignes.

Cette

indentation montre quelles parties du programme sont

subordonnées

à

quelles

autres

parties.

Revenons à Suzanne et voyons comment la phrase se structure : Suzanne dit "eh" parce que , comme vous le savez , elle vit au Canada.

Les diagrammes des Figures  4.3  et  4.4  vous montrent comment les parties du programme ThingsILike s’emboîtent les unes dans les autres. Notez la manière dont les accolades fonctionnent comme une boîte. Pour rendre la structure du programme visible d’un coup d’œil, vous devez indenter le contenu de chaque boîte.

FIGURE 4.3

Une paire d’accolades fonctionne comme une boîte.

FIGURE 4.4 Dans un programme informatique, les idées sont imbriquées les unes dans les autres.

Je n’insisterai jamais assez sur ce point. Si vous n’indentez pas votre code, ou si vous ne le faites pas correctement, votre programme se compilera et s’exécutera correctement. Mais cela ne fera que vous donner une fausse sensation de confiance. Dans l’instant même où vous essaierez d’éditer une ligne de code pas ou mal indentée, la confusion va s’installer. Suivez donc systématiquement mon conseil  : veillez à une bonne indentation de votre code à chaque étape du processus. Faites très attention à la précision de cette indentation, que vous écriviez un court programme de test ou que vous développiez une application de haut vol pour une entreprise multinationale. Eclipse peut indenter automatiquement votre code à votre place. Sélectionnez le fichier .java que vous voulez traiter, puis choisissez Code Source-> Formater (Source->Format). Eclipse va ajuster la présentation indentant

ce

des qui

lignes

dans

doit

l’être,

votre ce

code, qui

en

rend

généralement ce code plus lisible.

Commentaires Un commentaire est un texte qui n’est pas pris en compte

dans

le

flux

de

l’exécution.

Sur

la

Figure  4.2, par exemple, les mots Un commentaire ne font pas partie de la phrase qui parle de Suzanne. Ils disent simplement quelque chose à propos de cette phrase. C’est

pareil

pour

les

commentaires

dans

les

programmes informatiques. Les cinq premières lignes du Listing 4.1 forment un seul et même long commentaire. L’ordinateur ne s’en préoccupe pas, car il n’y a aucune instruction à exécuter dans ces lignes. Par contre, ce commentaire représente une description de votre travail à destination des autres programmeurs. Mais les commentaires sont aussi utiles pour vous. Imaginez que vous laissiez de côté votre code pendant un certain temps pour travailler à autre chose. Lorsque vous le retrouvez plus tard, ces commentaires vous aident à vous souvenir de ce que vous aviez fait. Le langage de programmation Java possède trois types de commentaires : » Commentaires traditionnels : C’est ce que montre le Listing 4.1. Ce type de commentaire débute par les caractères /* et se termine par */. Tout ce qui se trouve entre les deux n’intéresse

que les yeux humains, et donc n’est pas traduit par le compilateur. Trois de ces lignes contiennent des astérisques supplémentaires. Elles servent uniquement à renforcer le contenu du commentaire, et à rien d’autre. Mais la plupart des programmeurs Java aiment ajouter des astérisques (je ne suis pas sûr de toujours comprendre pourquoi). » Commentaires de fin de ligne : Voici du code avec des commentaires de fin de ligne : class ThingsILike { //Il manque deux choses public static void main(String args[]) { System.out.println("sommeil"); // Incomplet } } Un commentaire de fin de ligne débute par une double barre oblique (//) et se termine comme il se doit à la fin de la ligne courante. Il est courant que les programmeurs commentent certaines parties de leur code, c’est-à-dire transforment celles-ci en commentaires.

Supposons que vous écriviez un programme et que quelque chose ne fonctionne pas correctement. Dans ce cas, il est souvent utile de supprimer certaines lignes. Cela peut permettre d’isoler le coupable. Mais, comme vous ne savez pas à l’avance ce qui va se passer, vous ne voulez pas réellement supprimer tout ce code. Dans ce cas, il vous suffit de l’isoler provisoirement en le transformant en commentaire. Si vous changez par exemple System.out.println("sommeil") ; en /* System.out.println("sommeil") ; */, le compilateur Java ignorera cette ligne de code, vous laissant ainsi le temps de rechercher ce qui ne va pas dans votre programme. » Commentaires Javadoc : C’est un commentaire traditionnel qui débute par un astérisque supplémentaire. /** * Affiche une ligne et passe à la ligne suivante */ C’est une intéressante fonctionnalité de Java. Le logiciel Java SE que vous avez téléchargé sur le site d’Oracle contient un petit programme appelé

javadoc. Celui-ci a pour mission de rechercher dans votre code ces commentaires spéciaux. Il les utilise pour créer une page Web servant à documenter votre programme. Pour en apprendre plus à ce sujet, vous pouvez visiter la section correspondante de mon site Web, à l’adresse : https://users.drew.edu/bburd/BeginProg /CreatingJavadocs.pdf

Comprendre un programme Java simple Les sections qui suivent présentent, expliquent, dissèquent et démystifient le programme Java du Listing 4.1.

Qu’est-ce qu’une méthode ? Vous travaillez comme mécanicien dans un garage automobile.

Votre

patron

grincheux,

qui

est

toujours pressé et qui a l’habitude de manger ses mots, vous dit  : «  RépareLAlternateur de cette VieillePeugeot  » . Mentalement, vous réfléchissez aux tâches à effectuer. «  Amener la voiture à

l’atelier, lever le capot, prendre une clé, desserrer la courroie de l’alternateur  » et ainsi de suite. Partant de là, trois phénomènes se dégagent : » Vous avez un nom pour ce que vous êtes supposé faire. Le nom est RépareLAlternateur. » Vous avez une liste mentale des tâches associées au nom RépareLAlternateur. Cette liste, c’est « Amener la voiture à l’atelier, lever le capot, prendre une clé, desserrer la courroie de l’alternateur » et ainsi de suite. » Vous avez un patron grincheux qui vous dit de faire tout ce travail. Il vous dit « RépareLAlternateur ». En d’autres termes, il énonce le nom de la chose que vous êtes supposé faire, ce qui déclenche votre action. Ce scénario illustre la notion de méthode. Vous avez une méthode pour exécuter une certaine tâche concernant un alternateur. Votre patron invoque cette méthode, et vous y répondez en suivant la liste des instructions que vous avez associées à ladite méthode.

Méthodes Java

Si vous avez suivi la démonstration ci-dessus, vous êtes prêt à vous plonger dans les méthodes Java. En Java, une méthode est une liste de choses à faire. Chaque méthode a un nom, et vous dites à l’ordinateur d’exécuter ces tâches en utilisant dans votre programme le nom de la méthode. Je n’ai jamais écrit de programme qui serait capable de réparer automatiquement un alternateur. Mais si je devais le faire, mon programme contiendrait une méthode appelée RepareLAlternateur. La liste des tâches de cette méthode pourrait alors se présenter comme sur le Listing 4.2. LISTING

4.2 Une déclaration de méthode.

void RepareLAlternateur() { Conduire(voiture, atelier); Lever(capot); Prendre(cle); Desserrer(courroieAlternateur); … } Quelque part ailleurs dans mon programme Java (donc à l’extérieur du Listing 4.2), j’ai besoin d’une instruction

qui

RepareLAlternateur

appelle

ma

méthode

pour la mettre en action.

Cette instruction pourrait ressembler à celle qui est proposée dans le Listing 4.3. LISTING

4.3 Appeler une méthode.

RepareLAlternateur(VieillePeugeot); Bien entendu, vous ne devez pas prendre les Listings  4.2  et  4.3  au pied de la lettre. Il s’agit simplement d’une illustration de la transcription d’une

situation

programmeur.

réelle Et

du

c’est

point encore

de

vue

moins

du une

illustration de toutes les règles de Java. C’est juste un exercice à vocation pédagogique. Pratiquement

tous

les

langages

informatiques

possèdent plus ou moins l’équivalent des méthodes Java. Si vous avez déjà programmé dans d’autres langages,

des

expressions

comme

sous-

programmes, procédures, fonctions, ou encore des mots-clés tels que Sub ou PERFORM, devraient vous rappeler des souvenirs. Quelle que soit la manière de la désigner, une méthode est un regroupement d’instructions auquel on donne un nom.

Déclaration, en-tête et appel

Si vous avez compris l’essence des méthodes, telle que je l’explique plus haut, vous pouvez aller un peu plus loin en explicitant le vocabulaire qui leur est associé. » Comme je suis un peu fainéant, j’ai parlé de méthode à propos du Listing 4.2. Mais si je reprends mon courage à deux mains, je vous dirais qu’il s’agit plus exactement d’une déclaration de méthode. » La déclaration de méthode du Listing 4.2 comporte deux parties. La première ligne (celle qui contient le nom de la méthode jusqu’à, mais non comprise, l’accolade ouvrante) est appelée l’en-tête de la méthode. Le reste (ce qui est délimité par les accolades) est le corps de la méthode. » Le terme déclaration de méthode distingue la liste des instructions du Listing 4.2 de l’instruction du Listing 4.3, connue sous le nom d’appel de méthode. La Figure 4.5 illustre cette terminologie. Un en-tête et un corps de méthode sont un peu comme les entrées d’un dictionnaire. Celles-ci

n’utilisent pas le mot qu’elles définissent, mais ce qui se produit si et quand vous utilisez ces mots. Chocolat (choc-o-lat) n.m. 1. La meilleure substance nutritive du monde. 2. Quelque chose que vous achetez avec de l’argent. 3. L’élément nutritionnel le plus important pour bien dormir. RepareLAlternateur(). Amener la voiture à l’atelier, lever le capot, prendre une clé, desserrer la courroie de l’alternateur puis manger un peu de chocolat.

FIGURE 4.5

Les méthodes et leur terminologie.

Par contraste, un appel de méthode est comme utiliser un mot dans une phrase. Il met une certaine partie de code en mouvement. « Je veux du chocolat, sinon je pique une crise. » « RepareLAlternateur de cette VieillePeugeot. » Une déclaration de méthode explique à l’ordinateur ce qu’il doit faire si vous appelez cette méthode. Un appel de méthode (qui se trouve ailleurs dans le code) met ladite méthode en action. Déclaration et appel sont placés à différents endroits dans le programme Java.

Les programmes et la méthode main Sur le Listing  4.1, l’essentiel du code est la déclaration d’une méthode appelée main. C’est donc la méthode dite principale (main en anglais). À ce stade, laissez de côté les autres mots présents dans l’en-tête de cette méthode (public, static, void, String

et args). Nous les retrouverons dans

d’autres chapitres. Comme toute autre méthode Java, la méthode main est une recette :

Comment faire des biscuits; Préchauffer le four. Rouler la pâte. Faire cuire la pâte roulée. Ou bien : Comment suivre les instructions main dans le code ThingsILike : Afficher Chocolat, argent, sommeil à l’écran. Le mot main joue un rôle particulier en Java. En particulier, vous ne pouvez jamais écrire du code qui appelle explicitement une méthode main. Ce nom est réservé à la méthode qui est appelée automatiquement lorsque le programme commence son exécution. Lorsque

le

programme

ThingsILike

se

lance,

l’ordinateur localise automatiquement la méthode main et il exécute les instructions contenues dans le corps de celle-ci. Dans mon exemple, il n’y a qu’une seule instruction qui affiche les mots Chocolat, argent et sommeil à l’écran. Aucune des instructions d’une méthode n’est exécutée tant que cette méthode n’est pas appelée. Par contre, la méthode main fait exception à cette

règle, puisqu’elle est automatiquement exécutée au démarrage du programme.

Comment dire à l’ordinateur de faire quelque chose Au cœur du Listing 4.1, vous trouvez la seule ligne qui envoie une instruction à l’ordinateur : System.out.println("Chocolat, argent, sommeil"); C’est elle qui affiche mes trois mots préférés à l’écran (et plus précisément dans la vue Console sous Eclipse). Il y a deux manières de décrire cette ligne de code : » C’est une instruction. En Java, une instruction demande directement à l’ordinateur de faire quelque chose, en l’occurrence d’afficher un certain texte. D’autres instructions pourraient par exemple demander d’enregistrer le chiffre 7 dans un certain emplacement en mémoire, ou encore de faire apparaître une fenêtre sur l’écran. Dans les programmes informatiques, les instructions sont capables de faire de multiples choses.

» C’est un appel de méthode. Nous avons vu un peu plus haut ce qu’était un appel de méthode. Ainsi, RepareLAlternateur(VieillePeugeot); est un exemple d’appel de méthode. Et c’est pareil pour System.out.println("Chocolat, argent, sommeil"); Java a de nombreux types d’instructions. Un appel de méthode est simplement l’un d’entre eux.

Terminer une instruction avec un point-virgule En Java, chaque instruction se termine avec un point-virgule.

Il

n’y

en

a

qu’un

dans

le

Listing  4.1  puisque celui-ci ne comporte qu’une seule instruction. Regardez

maintenant

les

autres

lignes

du

Listing  4.1, par exemple l’en-tête de la méthode. Celle-ci

(la

ligne

main)

ne

demande

pas

directement à l’ordinateur de faire quelque chose.

Elle décrit uniquement une certaine action à laquelle il faudra faire référence le moment voulu. En langage clair, elle signifie «  Dans le cas où quelqu’un appellerait la méthode main, les lignes qui suivent expliquent ce qu’il faut faire en réponse à cet appel » . Chaque instruction Java entière se termine par un point-virgule.

Un

appel

de

méthode

est

une

instruction, ce qui n’est pas le cas d’un en-tête ou d’une déclaration de méthode.

La méthode System.out.println L’instruction du Listing  4.1  appelle une méthode nommée System.out.println. Cette méthode est définie dans l’API Java. Lorsque vous l’appelez, elle affiche le texte spécifié à l’écran. Les noms sont importants. Très importants, même. Deux personnes peuvent avoir le même prénom et le même nom de famille, et peut-être aussi le même métier. Mais il y a toujours quelque chose qui les différencie, par exemple leur adresse ou un signe

particulier.

programmation. existent

en

Il

Les

Java  :

en deux

va

de

écritures

même

suivantes

System.out.println

DriverManager.println.

Leur

point

en et

commun,

c’est bien sûr println. Mais la première (que vous allez souvent utiliser) affiche quelque chose à l’écran, tandis que la seconde (dont vous ne vous servirez pas dans ce livre) écrit dans un fichier appelé un journal. Dans les deux cas, println est défini dans l’API Java. Mais vous ne pouvez pas écrire son nom seul, car le système ne saurait pas ce que vous voulez faire. Vous devez donc écrire System.out.println, ou toute combinaison valide de noms de l’API. N’oubliez jamais, jamais que Java est sensible à la casse des caractères. Il fait la différence entre minuscules et minuscules, et toute erreur de saisie est

aussi

une

erreur

irrémédiable

dans

vos

programmes.

Partout des méthodes, partout Dans le programme ThingsILike, deux méthodes jouent leur partition. La Figure  4.6 illustre cette situation. Cette section apporte des précisions supplémentaires.

FIGURE 4.6

Appeler la méthode System.out. println.

» Il y a une déclaration pour une méthode main. J’ai écrit la méthode main moi-même. Mais retenez qu’elle est automatiquement appelée lorsque le programme se lance. » Il y a un appel à la méthode System.out.println. Dans cet exemple, c’est la seule instruction présente dans le corps de la méthode main. En d’autres termes, appeler System.out.println est l’unique tâche dévolue à cette méthode main.

Vous n’avez pas à vous soucier de ce que peut bien contenir la méthode System.out.println. Elle est définie dans l’API Java, et le savoir devrait suffire à votre bonheur. L’API Java n’est en aucun cas une sorte de Deus Ex Machina,

ou

de

révélation

magique.

C’est

simplement un autre (énorme) tas de code Java qui a été écrit par des types géniaux et qui vous évite d’avoir à réinventer la roue chaque fois que vous voulez faire quelque chose. Un grand merci à eux.

La classe Java Vous

avez

peut-être

déjà

entendu

parler

de

Programmation Orientée Objet (ou POO)  ? C’est une façon

de

réfléchir

programmation

sur

nos

aux

problèmes

ordinateurs

qui

de est

implémentée dans divers langages informatiques. Le point de départ de la POO se situe dans les années 1960 avec un langage qui s’appelait Simula. Celui-ci a été étendu dans les années  1970  par un autre langage appelé Smalltalk, puis plus tard par le C++. La page consacrée à Smalltalk dans Wikipédia est très intéressante à consulter. Vous y découvrirez

par exemple que Java est l’un des nombreux enfants légitimes (?) de Smalltalk : https://fr.wikipedia.org/wiki/Smalltalk Certaines

personnes

voudraient

changer

l’acronyme POO en POC, ou COP en anglais (pour Class-Oriented

Programming,

programmation

orientée par les classes, voire Concept-Oriented Programming,

programmation

orientée

par

le

concept). L’idée est que la programmation orientée objet commence par quelque chose qui est appelé une classe. En Java, tout part de classes, tout est contenu dans des classes et tout est basé sur des classes. Vous ne pouvez rien faire en Java sans avoir créé au moins une certaine classe. Il est donc essentiel que vous compreniez ce qu’est une classe. C’est pourquoi je ne vais pas aller plus loin sur ce sujet dans ces quelques lignes. J’y reviendrais plus longuement dans le Chapitre  17. Dans tous les cas, votre méthode main

doit

appartenir à une classe. Pour le petit programme proposé dans le Listing 4.1, j’ai donné comme nom ThingsILike à ma nouvelle classe. C’est pourquoi ce listing débute par les mots class ThingsILike.

Remarquez maintenant ce qu’il se passe après cette ligne. Le reste du code est encadré par des accolades. Celles-ci marquent tout ce qui se trouve à l’intérieur de la classe. Sans ces accolades, vous sauriez où se trouve le point départ de la classe ThingsILike, mais vous ne pourriez pas savoir où elle se termine. C’est un peu comme ranger des objets dans une boîte, comme l’illustre la Figure  4.3. Au lieu d’ouvrir et de fermer un couvercle, vous procédez de la manière suivante : » Vous utilisez des accolades. Ces accolades indiquent à l’ordinateur où commence et où finit le code de la classe. » Vous indentez votre code. Cette indentation montre à vos yeux (et à votre cerveau) où commence et où finit le code de la classe, mais aussi comment celle-ci est structurée. Ne l’oubliez pas. Les deux sont indispensables.

Des mots dans un programme Le Listing  4.1  contient plusieurs types de mots. Découvrez ce qui se passe lorsque vous changez certains de ces mots.

» Changer un des mots-clés. Par exemple, remplacez le mot class par le mot bologne. Recherchez un message d’erreur dans l’éditeur d’Eclipse. » Modifier l’un des identificateurs que vous ou moi pouvons définir. Par exemple, remplacez le mot args par le mot malarkey (pourquoi pas ?). Après cela, votre programme peut-il toujours fonctionner ? Le mot ThingsILike est aussi un mot que vous ou moi pouvons inventer. Vous pouvez donc essayer de changer ThingsILike pour autre chose. Si vous avez copié le code exactement comme dans le Listing 4.1, votre programme fonctionne toujours. Mais si votre programme commence par le mot « public », comme dans : public class AutreMot { vous pourriez avoir des ennuis. Si c’est le cas, supprimez simplement le mot « public » . » Modifier un identificateur qui a une signification convenue. Par exemple, changez println pour afficher. Recherchez un message d’erreur dans l’éditeur d’Eclipse.

» Modifier la ponctuation du programme. Par exemple, enlevez une paire d’accolades. Recherchez un message d’erreur dans l’éditeur d’Eclipse. » Commenter toute la ligne System.out.println("Chocolat, argent, sommeil") ; (utilisez le style de commentaire de fin de ligne). Que se passe-t-il lorsque vous exécutez le programme ? » Commenter toute la ligne System.out.println("Chocolat, argent, sommeil") ; (utilisez le style de commentaire traditionnel). Que se passe-t-il lorsque vous exécutez le programme ?

Identifiants valides Il y a des limites aux genres de noms que vous pouvez inventer. Par exemple, le nom d’une personne peut inclure un tiret, mais il ne peut pas contenir un point d’interrogation. Le nom d'une célébrité peut être un symbole imprononçable. Mais, pour la plupart d’entre nous, les lettres classiques, les tirets et les traits d’union sont tout ce que nous pouvons utiliser.

Quels genres de noms pouvez-vous inventer dans le cadre d’un programme Java  ? Découvrez-le en changeant le mot «  args

»

pour ces autres

appellations dans l’éditeur d’Eclipse. Lesquels des changements sont acceptables et lesquels ne le sont pas ? » helloThere » hello_there » args7 » ar7gs » 75 » 7args » hello there » hello-there » public » royalties » @args » #args » /args

Vos choses favorites

Changez le code du Listing 4.1 pour qu’il affiche les choses que vous aimez. Exécutez-le pour vous assurer qu’il affiche correctement ces choses dans la vue Console d’Eclipse.

Chapitre 5

Composer un programme DANS CE CHAPITRE : » Lire les saisies au clavier » Éditer un programme » Rechercher les erreurs

H nommé

ier, je discutais avec mon robot serviteur, le bien RJ-3000  (un modèle perfectionné de

dernière génération). Voici un extrait de notre conversation : Moi : RJ-3000, dis-moi la vitesse d’un objet après trois secondes de chute dans le vide. RJ-3000  : Oui, maître. «  La vitesse d’un objet après trois secondes de chute dans le vide. » Voilà, je vous ai répondu. Moi : RJ-3000, ne répète pas ce que je viens de dire. Je veux un nombre. Je veux la vitesse réelle.

RJ-3000 : D’accord ! « Un nombre ; la vitesse réelle ». Moi  : RJ-3000, ces plaisanteries sont indignes de toi. Est-ce que tu peux répondre à ma question ? RJ-3000 : Oui. Moi : « Oui », quoi ? RJ-3000  : Oui, je peux ou ne peux pas répondre à votre question. Moi : Eh bien, tu peux ? RJ-3000 : Oui, je peux. Moi : Alors, fais-le. Donnez-moi la réponse. RJ-3000 : La vitesse est de 153 984 792 kilomètres par heure. Moi : (après quelques instants de réflexion) RJ-3000, je sais que tu ne fais jamais d’erreur, mais ce nombre, 153 984 792, il est beaucoup trop grand. RJ-3000  : Trop grand  ? C’est impossible. Les choses tombent

très

vite

sur

la

planète

géante

Mangorrrkthongo. Maintenant, si vous vouliez savoir ce qui se passe quand des objets chutent sur la Terre, il fallait le préciser tout de suite. La vérité, c’est que RJ-3000 fait exactement ce que je lui demande de faire, ni plus ni moins. Si je lui

dis  : «  Nourris le chat  » , il me répondra « Nourris ? Chat ? Lequel de vos invités va avoir du chat pour le dîner ? »

Les ordinateurs sont stupides Aussi pratiques soient-ils, les ordinateurs sont comme mon robot RJ-3000. Ils font exactement ce que vous leur dites de faire, et le résultat peut parfois être désespérant. Par exemple, en  1962, un vaisseau spatial Mariner devant se diriger vers Vénus fut détruit quatre minutes seulement après son décollage. Pourquoi  ? À cause d’une faute de frappe dans un programme FORTRAN. À peu près à la même période, les scientifiques de la NASA trouvèrent une erreur qui aurait pu provoquer le même accident dans les vols spatiaux Mercury (avec des astronautes à bord ! ). Cette erreur, c’était tout bêtement la présence dans une ligne d’un point à la place d’une virgule (un programmeur avait écrit DO

10

I=1.10

au lieu de DO

10

I=1,10). Avec tout le respect que je dois à mon cher RJ3000, lui et tous ses cousins ordinateurs sont incroyablement stupides. On pourrait parfois croire qu’ils pensent avant nous, humains, mais en fait ils

font exactement ce que d’autres humains leur ont dit de faire. Ils peuvent lancer des pièces virtuelles et utiliser des schémas élaborés pour prédire le côté où elles vont tomber, mais ils sont en réalité incapables de «  penser  » tout seuls. Si vous dites «  Saute  » , ils feront ce pour quoi ils sont programmés pour répondre aux lettres S-a-u-t-e. Lorsque vous écrivez un programme informatique, vous devez imaginer qu’un génie vous a accordé trois vœux. Ne demandez pas l’amour éternel, car le

génie

vous

donnera

instantanément

un

compagnon bavant d’admiration devant vous. Vous n’allez pas aimer du tout. Et ne demandez pas non plus un million d’euros à moins que vous ne vouliez être transformé en pilleur de banques par le génie. Tout ce que vous écrivez dans un programme d’ordinateur doit être très précis. Prenons un exemple…

Un programme pour faire écho à une saisie au clavier Le Listing 5.1 contient un petit programme Java. Ce programme vous permet de saisir une ligne de

caractères sur le clavier. Dès que vous appuyez sur la touche Entrée, le programme affiche une seconde ligne qui recopie ce que vous avez entré. LISTING

5.1 Un programme Java.

import java.util.Scanner; class EchoLine { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in);

System.out.println(keyboard.nextLine()); keyboard.close(); } } Les programmes de ce livre sont en mode texte. Leurs entrées et leurs sorties s’effectuent donc presque exclusivement dans la console d’Eclipse. Vous pouvez voir une version du programme du Listing 5.1  avec une interface utilisateur graphique en

visitant

mon

site

Web

(https://users.drew.edu/bburd/BeginProg/index.ht ml) et en cliquant sur le lien GUI versions. La Figure  5.1  illustre l’exécution de la classe EchoLine (le code du Listing 5.1). La première ligne est celle que j’ai saisie, et la seconde l’écho renvoyé par le programme.

FIGURE 5.1

Écho, es-tu là ?

Sur la Figure 5.1, j’ai tapé la première ligne (le Ne répétez

ceci

à

personne

du

haut),

et

l’ordinateur a affiché la seconde ligne. Voici ce qui se

passe

lorsque

vous

exécutez

le

code

du

Listing 5.1 : 1. Au début, l’ordinateur ne fait rien. Il attend que vous tapiez quelque chose. 2. Vous cliquez dans la console d’Eclipse. Le résultat est que vous voyez un curseur clignoter sur le bord gauche de la vue Console (voir la Figure 5.2).

FIGURE 5.2

L’ordinateur attend que vous tapiez quelque chose.

3. Vous saisissez votre ligne de texte (voir la Figure 5.3).

FIGURE 5.3

Votre phrase.

4. Vous appuyez sur la touche Entrée, et l’ordinateur affiche une copie de votre texte (voir la Figure 5.4).

FIGURE 5.4

L’ordinateur fait écho à votre saisie.

5. Le programme a fait son travail, et il se termine maintenant.

Taper et exécuter un programme Tous les programmes de ce livre peuvent être téléchargés sur le site de l’éditeur (ou de l’auteur). Reportez-vous si nécessaire au Chapitre 2 pour les instructions d’installation de ces exemples. Pour tester le code du Listing 5.1, il vous suffit d’ouvrir dans Eclipse le projet appelé 05-01. Au lieu de vous contenter d’un code tout fait, je vous encourage vivement à faire l’expérience vousmême, c’est-à-dire à taper le code proposé dans le Listing 5.1, puis à tester votre propre saisie. Suivez simplement ces étapes : 1. Lancez Eclipse. 2. Dans la barre des menus d’Eclipse, choisissez Fichier ->Nouveau ->Projet Java (File -> New -> Java Project). La boîte de dialogue Nouveau projet Java s’affiche. 3. Dans le champ Nom du projet, tapez par exemple MonNouveauProjet. 4. Cliquez sur Terminer (Finish).

Vous revenez à l’espace de travail d’Eclipse, et MonNouveauProjet apparaît dans l’Explorateur de packages. La prochaine étape va consister à créer un nouveau fichier de code source Java. 5. Dans l’Explorateur de packages, sélectionnez MonNouveauProjet. Dans le menu Fichier, choisissez maintenant Nouveau, puis Classe. La boîte de dialogue Nouvelle classe Java apparaît. 6. Tapez le nom de votre nouvelle classe dans le champ Nom. Dans cet exemple, j’ai utilisé comme nom EchoLine. Faites de même en respectant la même syntaxe, avec un E et un L en majuscules, et sans espace. En Java, respecter une syntaxe et une capitalisation précises est très important. Si vous n’êtes pas cohérent dans un programme particulier, il est très probable que vous serez confronté à des erreurs de compilation. Le cas échéant, cochez la case qui indique public static void main(String[] args}. Cela vous évitera un peu de saisie lors de l’Étape 8. 7. Cliquez sur Terminer.

Vous revenez à l’espace de travail d’Eclipse. Un éditeur dont l’onglet indique EchoLine.java attend votre code. 8. Tapez le programme du Listing 5.1 dans l’éditeur EchoLine.java. Copiez ce code exactement comme vous le voyez sur le Listing 5.1. •

Orthographiez chaque mot exactement comme je l’ai fait sur le listing.



Respectez scrupuleusement les majuscules et les minuscules du listing.



N’omettez aucun signe de ponctuation (les points, les points-virgules, tout).



Vérifiez deux fois l’écriture du mot println. Tout doit être en minuscules, et l’avantdernière lettre est un l, pas un i.

Rappelez-vous que println est l’abréviation de « print a line » (imprimer une ligne). Si vous avez tout saisi correctement, vous ne devriez voir aucun marqueur dans la colonne de gauche de l’éditeur. Sinon, remettez votre ouvrage sur le métier, et comparez chaque mot, chaque

lettre, chaque signe de ponctuation, chaque gribouillis avec le Listing 5.1. 9. Apportez tous les changements ou toutes les corrections indispensables dans le code de l’éditeur. Quand vous ne voyez plus aucun marqueur d’erreur, vous êtes prêt à exécuter le programme. 10.Sélectionnez la classe EchoLine en cliquant dans l’éditeur ou en sélectionnant la branche MonNouveauProjet dans l’Explorateur de packages. 11.Ouvrez le menu Exécuter d’Eclipse et choisissez la commande Exécuter (Run). Une autre option est Exécuter en tant que (Run As) -> Application Java. 12.Cliquez dans la vue Console d’Eclipse. Un curseur apparaît sur le bord gauche de la vue (reportez-vous à la Figure 5.2). Si vous oubliez de cliquer dans la console, Eclipse ne peut pas envoyer votre saisie au programme Java en cours d’exécution. Les caractères que vous tapez seront transmis à l’éditeur, ou bien, ce qui est assez étrange, à l’Explorateur de packages.

13.Tapez une ligne de texte et appuyez sur Entrée. En réponse, l’ordinateur affiche une copie de votre ligne de texte, à la suite de quoi le programme se termine (revoyez la Figure 5.4). Si cette liste d’étapes vous semble un peu vague, revoyez

le

Chapitre  3  pour

des

détails

plus

approfondis. En fait, cette liste constitue un résumé rapide de tout ce qui a été abordé dans le Chapitre 3, la grande différence étant que, dans ce chapitre, je ne vous ai pas demandé de saisir vousmême le programme. Quel est l’enjeu quand vous tapez le programme vous-même  ?

En

fait,

des

tas

de

choses

intéressantes peuvent se produire quand vous posez vos doigts sur le clavier. C’est pourquoi la seconde moitié de ce chapitre est consacré aux délicats problèmes de dépannage.

Comment fonctionne le programme EchoLine Lorsque vous étiez un bébé confortablement blotti dans les bras de votre mère, celle-ci vous a expliqué comment envoyer des caractères sur l’écran de l’ordinateur :

System.out.println(le texte que vous voulez afficher); Mais ce qu’elle ne vous a pas dit, c’est comment récupérer ces caractères à partir du clavier de cet ordinateur. Il y a de multiples manières de s’y prendre, mais celle que je vous recommande dans ce chapitre est celle-ci : keyboard.nextLine() Et maintenant, voici le meilleur de l’affaire. Appeler la méthode keyboard.nextLine ne fait pas que lire les caractères saisis au clavier. Lorsque l’ordinateur exécute votre programme, il remplace le texte keyboard.nextLine() par ce que vous tapez sur le clavier. Pour comprendre ce qui se passe, regardez cette instruction provenant du Listing 5.1 : System.out.println(keyboard.nextLine()); Lorsque vous exécutez le programme, l’ordinateur voit votre appel à nextLine, et il coupe net son élan (reportez-vous à la Figure 5.2). Il attend alors que vous tapiez une ligne de texte, par exemple ceci (voyez la Figure 5.3) :

Tiens, il y a de l’écho ici. L’ordinateur substitue la ligne Tiens… tout entière à l’appel keyboard.nextLine(). Ce processus est illustré sur la Figure 5.5.

FIGURE 5.5

L’ordinateur remplace l’appel à nextLine par le texte

que vous tapez.

L’appel à keyboard.nextLine() est imbriqué dans l’appel

à

l’ordinateur

System.out.println.

Au

se

comme

comporte

donc

l’instruction du Listing 5.1 était rédigée ainsi :

final, si

System.out.println("Tiens, il y a de l’écho ici."); Quand vous appuyez sur la touche Entrée, il affiche une autre copie du texte (reportez-vous à la Figure 5.4).

Récupérer des nombres, des mots et d’autres choses Sur le Listing  5.1, l’appel à keyboard.nextLine() récupère une ligne de texte tapée sur le clavier de l’ordinateur dans sa totalité. Si vous entrez par exemple : Test 1 2 3 Vous verrez s’afficher en écho Test 1 2 3. Mais ce n’est pas toujours ce que vous voulez obtenir. Vous pourriez avoir uniquement besoin d’un certain élément dans une ligne. Par exemple, si vous tapez 1 2 3, vous voudriez juste récupérer le nombre 1 (il peut signifier un certain client, ou tout ce que vous pouvez imaginer d’autre). Dans ce cas, keyboard.nextLine() ne fait pas l’affaire. Vous devez utiliser à la place keyboard.nextInt().

Le Tableau 5.1 vous montre quelques variations sur le thème keyboard.next. Malheureusement, les entrées de ce tableau ne sont pas très prévisibles. Pour lire une ligne de texte entière, vous appelez nextLine. Mais pour lire un mot dans une saisie, vous n’appelez pas nextWord. D’ailleurs, l’API de Java ne possède pas de méthode nextWord. L’appel se fait dans ce cas par next. TABLEAU

5.1

Quelques méthodes d’analyse de saisie.

Pour lire

Appelez cette méthode

ceci… Un nombre

nextInt()

sans point décimal Un nombre

nextDouble()

avec un point décimal Un mot (se

next()

terminant par exemple par une espace Une ligne (ou ce qui en reste

nextLine()

après avoir lu certaines données de cette ligne) Un caractère

findWithinHorizon(".",0).charAt(0)

unique (une lettre, un chiffre ou un signe de ponctuation) La fin du tableau est assez surprenante. Pour lire un unique caractère, vous devez appeler l’étrange combinaison

de

méthodes

findWithinHorizon(".",0).charAt(0). Mais vous devez excuser les types qui ont créé la classe Scanner.

Ils

l’ont

fait

pour

des

motifs

très

spécialisés. Pour voir certaines des méthodes du Tableau 5.1  en action,

reportez-vous

à

d’autres

programmes

proposés dans ce livre, en particulier dans les Chapitres 6, 7 et 8.

Obtenir des mots seuls et des lignes entières de texte

Suivez les instructions de la section «  Taper et exécuter un programme  » de ce chapitre, mais effectuez ces deux modifications : » À l’Étape 6, tapez GetInput dans le champ Nom de la boîte de dialogue Nouvelle classe Java. » Au lieu de taper le code du Listing 5.1, tapez le programme suivant : import java.util.Scanner; public class GetInput { public static void main(String[] args) { Scanner keyboard = new Scanner(System.in);

System.out.println(keyboard.next()); System.out.println(keyboard.next()); System.out.println(keyboard.nextLine() ); keyboard.close(); } }

Lorsque le programme s’exécute, tapez le texte suivant (sur une seule ligne) dans la vue Console d’Eclipse, puis appuyez sur Entrée. Comment l’ordinateur réagit-il ? Pourquoi ? J’aime apprendre Java.

Trois lignes de code à saisir (sans se retourner) Trois lignes de code particulières se dissimulent innocemment dans le Listing  5.1. Elles aident l’ordinateur à lire ce que vous saisissez au clavier. Les voici : import java.util.Scanner; Scanner keyboard = new Scanner(System.in); keyboard.close(); J’ai de bonnes et de mauvaises nouvelles à vous communiquer concernant ces trois lignes. » La mauvaise nouvelle, c’est que le raisonnement qui se cache derrière ces lignes est difficile à comprendre. Et c’est tout

particulièrement vrai à ce stade du livre, où je présente les concepts les plus fondamentaux de Java.

JAVA ET SON SCANNER Dans ce chapitre, je vous conseille d’ignorer la logique sousjacente aux lignes import

java.util.

Scanner

et

Scanner keyboard, etc. Collez-les sans réfléchir dans votre fichier et passez à autre chose. Bien entendu, vous n’êtes pas obligé de suivre mon conseil. Si vous êtes du genre têtu et qui veut toujours savoir ce qu’il fait, vous pouvez lire ce qui suit. » Le mot Scanner est défini dans l’API Java. Un Scanner est quelque chose que vous pouvez utiliser pour récupérer une saisie. Cette classe Scanner existe depuis la version 5 de Java. Avec une version plus ancienne, vous ne feriez qu’obtenir un message d’erreur. » Les mots System et in sont aussi définis dans l’API Java. Additionnés pour former System.in, ils représentent le clavier de l’ordinateur. Dans d’autres chapitres, vous pourrez voir des choses comme new Scanner(new File( « myData.txt » )). Cela signifie que l’entrée n’est pas lue depuis le

clavier, comme dans System.in, mais à partir d’un fichier présent sur le disque dur. » Le mot keyboard ne provient pas de l’API Java. C’est une création très personnelle. Au lieu de keyboard, vous pourriez parfaitement écrire clavier, ou bien choseLecture, ou tout ce que voulez à condition de rester cohérent dans l’utilisation de votre nom. Par exemple : Scanner clavier = new Scan ner(System.in); System.out.println(clavier.next Line()); Ainsi réécrit, le programme fonctionnera parfaitement. » La ligne import

java.util.Scanner

est un

exemple de déclaration d’importation. Une déclaration d’importation facultative vous permet d’abréger les noms dans le reste de votre programme. Vous pourriez parfaitement supprimer cette ligne dans le Listing  5.1. Mais vous devriez alors utiliser le nom pleinement qualifié de la classe Scanner dans tout votre code :

class EchoLine { public static void main(String args[]) { java.util.Scanner keyboard = new java.util.Scan ner(System.in); System.out.println (key board.nextLine()); keyboard.close(); } } C’est quand même beaucoup de travail pour rien. » La bonne nouvelle, c’est que vous n’avez pas besoin de comprendre le raisonnement qui se cache derrière ces lignes. Vous pouvez vous contenter de les copier et de les coller dans tout programme qui lit les entrées faites au clavier. Vous n’avez rien à y changer. Elles fonctionnent sans aucune modification dans toutes sortes de programmes Java. Assurez-vous que ces lignes sont placées aux bons endroits :

» Faites de la ligne import java.util.Scanner ; la première de votre programme. » Placez la ligne Scanner keyboard = new Scanner(System.in) ; à l’intérieur de votre méthode main immédiatement après la ligne public static void main(String args[]) {. » Placez la ligne keyboard.close() ; à la fin de votre programme. Il arrivera un moment où vous devrez faire encore plus attention à la position de ces trois lignes. Mais, pour l’instant, ces règles sont claires et suffisantes.

S’attendre à l’inattendu Il n’y a pas longtemps, j’ai discuté avec un professeur spécialisé dans la programmation. Il m’a dit à peu près ceci : « Parfois, quand je fais un cours, il m’arrive de composer un programme directement sur l’ordinateur. Je le fais face à mes étudiants.

Si

le

programme

se

compile

et

fonctionne correctement du premier coup, je leur demande de m’applaudir. »

Vous pourriez croire que ce type a un ego énorme, mais il faut mettre les choses en perspective. Il est rare qu’un programme «  tourne  » du premier coup. Il y a pratiquement toujours au moins une faute de frappe ou des erreurs d’un autre genre. Cette section s’intéresse aux erreurs normales, attendues, que vous pouvez rencontrer lorsque vous compilez et exécutez un programme pour la première fois. L’essentiel, c’est de bien garder la tête froide. Voici donc quelques remarques d’ordre général à ce sujet : » Ne vous attendez pas à ce qu’un programme que vous saisissez soit compilé dès la première fois. Soyez préparé à revenir à votre éditeur et à corriger certaines erreurs. » Ne vous attendez pas à ce qu’un programme parfaitement compilé s’exécute correctement. Même si l’éditeur d’Eclipse n’affiche aucun marqueur, votre programme peut comporter des imperfections. Une fois la compilation réussie, encore faut-il qu’il en aille de même pour l’exécution. Autrement dit, votre programme

devrait se terminer sans grincements après avoir affiché correctement la sortie. Compiler, puis exécuter… Et la première partie est la plus facile des deux. » Lisez ce qu’il y a d’affiché dans l’éditeur d’Eclipse, pas ce que vous croyez qu’il y a. Ne supposez pas que vous avez tapé tous les mots correctement, que vous avez mis les bonnes lettres en majuscules, ou que vous avez parfaitement couplé les parenthèses ou les accolades. Comparez le code que vous avez tapé avec d’autres exemples. Vérifiez chaque détail avec soin. » Soyez patient. Tout bon effort de programmation demande du temps pour que tout aille bien. Si vous ne comprenez pas quelque chose tout de suite, prenez votre temps. Persévérez (ou laissez reposer quelque temps le problème pour y revenir ensuite). Il n’y a rien que vous ne puissiez comprendre si vous faites preuve de patience. » Ne devenez pas frustré.

Inutile de vous mettre à piétiner frénétiquement. La frustration est votre ennemi. Si vous êtes frustré, vous ne pourrez rien faire de bien. » Ne croyez pas que vous êtes le seul à comprendre lentement. Je suis lent, et j’en suis fier. » Ne jouez pas le timide. Si votre code ne fonctionne pas et que vous ne comprenez pas pourquoi, demandez à quelqu’un d’autre. Postez un message sur un forum en ligne. Et ne vous effrayez pas si vous recevez une réponse ironique ou sarcastique. Dites-vous que la personne qui se moque de vous a vécu la même chose, et qu’elle la vivra encore.

Diagnostiquer un problème La section «  Taper et exécuter un programme  » , plus haut dans ce chapitre, vous a expliqué comment lancer le programme EchoLine. Si tout s’est bien déroulé, l’écran que vous avez obtenu devait ressembler à celui de la Figure 5.1. Mais les choses ne se passent pas toujours aussi bien. Il peut arriver que vos doigts dérapent sur les touches du

clavier, et la faute de frappe est là sans même que vous vous en rendiez compte. Ou bien vous avez oublié un certain détail, et vous obtenez un méchant message d’erreur. Bien entendu, il y a des choses qui peuvent être changées dans le Listing  5.1. Les mots utilisés ne sont pas tous gravés dans la pierre. Mais je ne peux pas vous donner des règles générales à ce sujet. Certaines modifications sont correctes, et d’autres pas. Voyons cela de plus près.

Java et la capitalisation Je ne le dirai jamais assez  : Java est sensible à la capitalisation, c’est-à-dire aux majuscules et aux minuscules. Dans un programme Java, les lettres P et p sont différentes. Si vous m’écrivez en disant «  Cher barry  » au lieu de «  Cher Barry  » , je saurai quand même que vous vous adressez à moi. Mais Java ne fonctionne pas de cette façon. Changez

simplement

une

lettre

dans

un

programme Java, et vous risquez de transformer une compilation réussie en un pénible parcours du combattant. Essayons par exemple de changer un p en P :

// La ligne suivante est incorrecte : System.out.Println(keyboard.nextLine()); Aussitôt, Eclipse se fâche (voir la Figure 5.6).

FIGURE 5.6

Le compilateur Java comprend println, mais pas

Println.

Lorsque vous voyez des marqueurs et des correctifs à chaud comme ceux de la Figure  5.6, le mieux à faire est de rester calme et de lire attentivement le message. Parfois, celui-ci donne des conseils utiles (évidemment, parfois aussi ils ne le sont pas). Ici, Eclipse

nous

avertit

que

La

méthode

Println(String) est indéfinie pour le type PrintStream. En bon français, cela signifie que le compilateur Java ne sait pas interpréter le mot Println. Et, comme il est poli, il ne vous dit pas  :

«  Ne tape pas le mot Println, espèce de nul  !  » Bien entendu, quand un ordinateur traite l’un d’entre nous de nul, il faut le prendre comme un compliment. En fait, il y a des tas de raisons pour lesquelles

le

compilateur

est

incapable

de

comprendre le mot Println. Mais, à ce stade, il faut se poser deux questions : » Avez-vous orthographié le mot correctement ? Vous avez peut-être accidentellement tapé print1n (avec le chiffre 1) au lieu de println ? » Avez-vous mis correctement toutes les lettres en minuscules ou en majuscules ? Vous avez peut-être, toujours accidentellement tapé Println ou PrintLn au lieu de println ? Toutes

ces

erreurs

peuvent

faire

tourner

le

compilateur Java en bourrique. Comparez mot par mot (et même lettre par lettre) ce que vous avez saisi avec la syntaxe officielle. Quand vous avez trouvé une contradiction, revenez à l’éditeur et corrigez le problème. Essayez ensuite de recompiler le programme. Lorsque vous tapez un programme dans l’éditeur d’Eclipse, celui-ci essaie de le compiler. S’il trouve une erreur à ce stade, il affiche en règle générale au

moins

trois

marqueurs

rouges

(revoyez

la

Figure  5.6). Celui qui se trouve dans la marge gauche contient une sorte de croix, et parfois une petite ampoule. Le marqueur affiché dans la marge droite est un mince rectangle. Et celui du milieu est une ligne ondulée. Si vous placez le pointeur de la souris sur l’un de ces marqueurs, Eclipse va afficher un message qui tente de décrire la nature de l’erreur. Si le pointeur se trouve au-dessus de la ligne ondulée, il va en plus (si c’est possible) proposer une liste de solutions appelées correctifs à chaud. Si vous cliquez droit (Ctrl+clic sur un Mac) sur le marqueur qui se trouve

dans

la

marge

gauche,

et

que

vous

choisissez dans le menu contextuel qui apparaît l’option Correctif rapide (Quick Fix), Eclipse va afficher les solutions suggérées. Pour appliquer automatiquement une correction, cliquez simple ou double sur la réponse qui vous paraît adaptée dans la liste des corrections rapides (si quelque chose ressemble à un lien, un clic suffit).

Ponctuation manquante En français, en anglais, comme en Java, utiliser la bonne ponctuation est important.

Regardons par exemple ce qui se passe si vous oubliez un point-virgule, comme ci-dessous : // Le code suivant est incorrect :

System.out.println(keyboard.nextLine()) keyboard.close(); } Vous allez obtenir le message illustré sur la Figure 5.7.

FIGURE 5.7

Un message d’erreur très explicite.

Un message comme celui qui est montré sur la Figure  5.7  vous simplifie l’existence. Je n’ai pas

besoin de vous l’expliquer, et vous n’avez pas à vous

creuser

la

tête

pour

comprendre

sa

signification. Prenez ce qu’il vous dit (insérez " ; " pour effectuer Statement) au pied de la lettre. Ajoutez sans discuter un point-virgule au bout de la ligne System.out.println(keyboard.nextLine()).

Quand il y a trop de ponctuation Lorsque j’étais au lycée, mon professeur de langue m’expliquait qu’il fallait utiliser une virgule à chaque respiration dans une phrase. Mais ce conseil ne fonctionnait pas bien pendant la saison des allergies, car mes phrases finissaient par contenir plus de virgules que de mots. Et même maintenant, j’ai du mal à savoir où les placer, et j’ai tendance à en ajouter pour faire bonne mesure. Bien sûr, cela complique la tâche de mon correcteur, qui a une corbeille pleine de virgules sous son bureau.

POURQUOI L’ORDINATEUR NE PEUT-IL PAS CORRIGER MES ERREURS ? Combien de fois finissez-vous la phrase de quelqu’un d’autre ? « S’il te plaît », dit votre supérieur, « va là-bas et relie les... ». « fils ! », dites-vous. « Je vais aller relier les fils. » Si vous savez ce que quelqu’un veut dire, pourquoi attendre qu’il le dise ? C’est la même chose pour la connexion avec les messages d’erreur de l’ordinateur. Revenons sur le message affiché sur la Figure  5.7. L’ordinateur attend un point-virgule après l’instruction de la ligne 8. Bien. M. Ordinateur, pourquoi estce que vous m’ennuyez pour si peu de choses  ? Après tout, puisque vous savez qu’il manque un point-virgule, vous n’avez qu’à l’ajouter vous-même, non ? Eh bien non. La raison est d’ailleurs simple. L’ordinateur n’a pas à faire des suppositions sur vos intentions. Voulez-vous réellement ajouter un point-virgule à la fin de la ligne 8 ? Et si ce fameux point-virgule était le signe d’un problème plus profond ? Si l’ordinateur décidait tout seul d’ajouter ce signe de ponctuation, il pourrait potentiellement faire beaucoup plus de mal que de bien. Revenons à vous et à votre chef…

Boum ! Une grande explosion. « Pas les fils, triple idiot ! Les points ! Je voulais que tu relies les points ! ». « Désolé », dites-vous. C’est la même chose dans un programme Java. Vous pouvez oublier des signes de ponctuation, mais vous pouvez aussi en mettre de trop par erreur. Par exemple, l’en-tête de la méthode main du Listing peut être un véritable piège pour les débutants. Pour réviser les termes en-tête de méthode et corps de méthode, reportez-vous au Chapitre 4. Normalement, vous ne devriez pas terminer un entête

de

méthode

par

un

point-virgule.

Mais

certaines personnes ont tendance à le faire quand même (d’une certaine manière, un en-tête de méthode

donne

l’impression

qu’il

devrait

se

terminer par un point-virgule, vous ne trouvez pas  ?).

Voici

donc

comment

se

présente

problème : // La ligne suivante est incorrecte : public static void main(String args[]) ; {

le

Dans ce cas, vous allez obtenir le message illustré sur la Figure 5.8.

FIGURE 5.8

Un point-virgule en trop, et les ennuis commencent.

Ce message est un peu troublant. Il vous dit en effet que cette méthode requiert un corps. Mais elle a un corps, n’est-ce pas ? En fait, cette syntaxe remplit le compilateur de confusion. Cette confusion est illustrée sur la Figure  5.9. Vos yeux voient simplement un pointvirgule, mais le compilateur l’interprète comme la fin d’une instruction, et donc comme une méthode sans corps. D’où son cri d’effroi. Si vous sélectionnez le correctif à chaud Ajouter un corps (Add Body), Eclipse va créer le code (horrible) ci-dessous :

import java.util.Scanner; class EchoLine { public static void main(String args[]) { } { Scanner keyboard = new Scanner(System.in); System.out.println(keyboard.nextLine()); keyboard.close(); } }

FIGURE 5.9

La confusion règne dans le cerveau de l’ordinateur.

Ce «  correctif  » ne provoque pas d’erreur de compilation. Mais quand vous l’exécutez, rien ne se produit. Le programme se lance, puis il se termine sans que rien n’apparaisse dans la vue Console d’Eclipse. Nous

savons

tous

qu’un

ordinateur

est

une

machine très patiente et très bienveillante. C’est pourquoi il regarde votre code et décide de vous donner une seconde chance. Il se rappelle que Java possède

une

fonctionnalité

avancée

qui

vous

permet d’écrire un en-tête de méthode sans compléter le code de celle-ci. Dans ce cas, vous obtenez ce que l’on appelle une méthode abstraite (une notion qui dépasse le cadre de ce livre). Quoi qu’il en soit, sur la Figure 5.9, l’ordinateur voit un en-tête sans corps. Il se dit donc : « J’ai compris ! Le programmeur essaie peut-être d’écrire une méthode abstraite. Le problème, c’est qu’un entête de méthode abstraite doit contenir le mot abstract.

Je

devrais

le

rappeler

au

programmeur.  » Et c’est pourquoi il propose de changer 'EchoLine.main' en 'abstract' dans le correctif à chaud de la Figure 5.8. D’une

manière

ou

d’une

autre,

vous

devez

décrypter certains messages un peu ésotériques. Si un correctif à chaud ajoute par exemple le mot abstract, vous savez désormais que ce n’est pas ce que vous vouliez obtenir. Supprimez-le et tournezvous vers l’hypothèse la plus crédible  : le pointvirgule fautif. Si vous regardez attentivement la ligne public static

de

la

Figure  5.8,

vous

remarquerez

éventuellement qu’elle est différente de la ligne correspondante du Listing 5.1. En effet, celle-ci ne contient pas de point-virgule. Bien sûr, vous ne

commencerez pas toujours avec du code préécrit comme celui du Listing 5.1. C’est dans ce genre de situation que la pratique révèle toute sa valeur. Plus vous écrivez de code, plus vos yeux seront sensibles aux points-virgules étrangers et aux autres gaffes de programmation.

Trop d’accolades Vous cherchez la station d’essence la plus proche, et vous demandez à un autochtone où la trouver. Il vous répond  : «  Allez jusqu’au prochain feu et tournez à gauche » . Vous avancez et vous voyez un signal clignotant orange. Vous tournez alors à gauche, et vous continuez pendant environ un kilomètre. Quoi  ? Pas de station  ? Vous avez peutêtre pris un banal signal clignotant pour un feu de circulation. Vous arrivez à une intersection, et vous vous dites : « La personne ne m’a pas parlé d’une intersection. Quelle route vais-je prendre  ?  » Vous virez à droite, mais, une minute plus tard, vous vous retrouvez sur une autoroute. Et, là, vous voyez un panneau

qui

indique

« 

Prochaine

sortie

à 24 kilomètres » . Cette fois, vous êtes réellement

perdu, et la jauge d’essence pointe maintenant dangereusement vers zéro… Que s’est-il passé  ? Vous avez fait une erreur a priori bénigne. Vous n’auriez pas dû tourner à gauche quand vous avez vu le signal clignotant. En soi, ce n’était pas bien grave. Mais cette première erreur en a engendré une seconde, et, au bout d’un certain temps, vos décisions ont éventuellement perdu tout sens. Se retrouver sur l’autoroute était une pure catastrophe. Est-ce que cette histoire a une morale  ? Bien entendu. Un ordinateur peut lui-même se trouver dans le même genre de panade. Il remarque une erreur

dans

votre

métaphoriquement

programme.

parlant,

il

bifurque

Puis, à

la

prochaine intersection (une bifurcation basée sur l’erreur d’origine, mais à partir de laquelle aucune alternative

ne

fournit

la

bonne

solution

au

problème). Supposons, toujours en partant du Listing 5.1, que vous tapiez par inadvertance une accolade de trop : // Le code suivant est incorrect : import java.util.Scanner;

class EchoLine { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); } System.out.println(keyboard.nextLine()); keyboard.close(); } } La

marge

gauche

d’Eclipse

affiche

plusieurs

marqueurs. En survolant le second, vous voyez s’afficher les messages illustrés sur la Figure 5.10.

FIGURE 5.10

Trois messages d’erreur.

Eclipse

est

perdu,

parce

que

l’appel

à

System.out.println est complètement décalé. Il demande alors d’insérer des choses auxquelles vous ne comprenez rien (rassurez-vous, c’est normal). Aucun de ces messages ne repère la source du problème. Eclipse essaie de se débrouiller au mieux dans cette situation, mais, à ce stade, vous ne devriez pas croire un seul mot de ce qu’il vous raconte. Les

ordinateurs

ne

sont

pas

des

animaux

intelligents, et si quelqu’un a programmé Eclipse pour

dire

insérez

"Identifier

("

pour

effectuer MethodHeaderName, c’est exactement ce qu’il fait). Certaines personnes disent qu’elles se sentent stupides

devant

un

ordinateur.

Moi,

c’est

exactement l’inverse. Un ordinateur me rappelle combien une machine peut être stupide, et combien un

être

humain

peut

être

intelligent.

J’aime

beaucoup cette idée. Lorsque

vous

voyez

une

horde

de

messages

d’erreur, lisez-les tous attentivement. Demandezvous ce qu’ils peuvent vous apprendre. Mais n’en prenez aucun comme s’il s’agissait d’une vérité révélée. Lorsque vous avez fini de vous triturer les

méninges avec les messages d’Eclipse, retournez à vos propres efforts pour écrire soigneusement votre propre code. Lorsque vous obtenez plusieurs messages d’erreur, lisez soigneusement ce qu’ils disent. Parfois, un avertissement très utile se cache au milieu d’une forêt de messages beaucoup moins utiles.

Des fautes dans des mots Vous avez trouvé une vieille recette de cuisine pour faire des œufs mimosas (mes préférés). Vous suivez soigneusement toutes les étapes, mais vous laissez le sel de côté parce que votre grand-mère fait de la tension. Vous tendez un œuf mimosa (superbement décoré) à votre grand-mère. «  Pas assez de poivre » , dit-elle. Et elle s’en va. Votre

prochaine

recette

est

celle

du

bœuf

bourguignon. Vous en apportez une assiette à votre grand-mère adorée. « Pas assez doux » , grondet-elle. Et elle quitte la pièce. Vous pensez alors  : «  Mais ce n’est pas possible. Il n’y a pas de sucre dans le bœuf bourguignon. J’ai juste supprimé le sel  !  » . Comme vous n’êtes pas du genre à renoncer, vous retournez à la cuisine pour préparer de la purée. Bien entendu, vous utilisez du beurre

sans sel. « Elle va l’aimer, cette fois » , vous ditesvous. «  Elles sont aigres, tes pommes de terre  ! Beurk  !  » s’écrie-t-elle, et elle se précipite vers le lavabo pour tout vomir. C’est votre grand-mère, après tout, et vous lui pardonnez. Mais vous êtes tout de même très surpris. Comment peut-elle dire trois choses aussi différentes à propos de trois plats non

salés  ?

Peut-être

y

a-t-il

de

subtiles

différences dont vous ne savez rien. Le même genre de chose se produit lorsque vous écrivez

des

programmes

informatiques.

Vous

pouvez faire deux fois la même erreur (ou plutôt vous pensez avoir fait deux fois le même type d’erreur), et pourtant vous obtenez à chaque fois des messages d’erreur différents. Par

exemple,

si

vous

mettez

une

lettre

en

majuscule dans println, Eclipse vous dit que la méthode n’est pas définie pour le type PrintStream. Mais si vous faites la même chose en écrivant system au lieu de System, Eclipse va vous répondre system ne peut pas être résolu. Toujours dans le Listing  5.1, si vous changez l’orthographe de args, rien de mal ne va se passer.

Le programme est compilé normalement, et il s’exécute

comme

modification

de

prévu.

main

se

Par

contre,

traduirait

par

une des

complications plus inhabituelles (si vous ne me croyez pas, lisez la section «  Messages d’erreur à l’exécution » , un peu plus loin dans ce chapitre). Toujours dans le Listing 5.1, changez le nombre de signes d’égalité dans la ligne Scanner keyboard = new Scanner(System.in). Avec un seul signe égal, tout le monde est content. Si vous en ajoutez par mégarde un second (Scanner keyboard == new Scanner(System.in) ; ), Eclipse vous alerte bien entendu, et il indique Erreur de syntaxe sur le sème "==", = attendu (voir la Figure  5.11). Bon. Mais si vous êtes pris de tremblements et que vous tapez quatre signes d’égalité (ou aucun), Eclipse ne comprend plus rien, et il accuse keyboard d’être le coupable en suggérant insérez effectuer

"

;

"

pour

BlockStatements. Malheureusement,

insérer un point-virgule n’arrange rien du tout (voir la Figure 5.12).

FIGURE 5.11

Le second signe égal doit être supprimé.

Java répond aux erreurs de nombreuses manières différentes. Deux changements dans votre code peuvent avoir l’air de se ressembler, mais ils ne conduisent pas toujours aux mêmes résultats. Chaque problème de votre code nécessite une attention individuelle.

FIGURE 5.12

Il y a beaucoup trop de signes d’égalité, mais Eclipse ne

le remarque pas.

Voici un exercice utile. Commencez à travailler sur un programme Java. Une fois que vous avez exécuté correctement le code, faites une modification qui introduit intentionnellement une erreur. Regardez avec soin le message qu’affiche Eclipse. Demandezvous si ce message vous aide à diagnostiquer le problème. Cet exercice est tout à fait important, car il vous aidera à penser aux erreurs comme à quelque chose de normal. Il vous donnera aussi une certaine expérience dans l’analyse des messages lorsque votre problème à vous n’est pas de savoir si le programme fonctionne ou non correctement.

Messages d’erreur à l’exécution

Jusqu’ici, j’ai décrit des erreurs qui sont affichées lorsque

vous

compilez

un

programme.

Mais

d’autres peuvent survenir au moment où vous exécutez votre programme. Une situation typique de ce type d’erreur se produit si une syntaxe est incorrecte, ou si vous orthographiez mal le mot main. Supposons donc que, dans un moment de total abandon, vous écriviez main avec une majuscule : // La ligne suivante est incorrecte : public static void Main(String args[]) { Si vous tapez ce code, aucun marqueur d’erreur ne va apparaître dans l’éditeur. Mais quand vous lancez le programme, la catastrophe prévisible se produit. C’est ce qu’illustre la Figure 5.13.

FIGURE 5.13

La méthode principale est introuvable dans la classe

EchoLine, ça veut dire quoi au fait ?

D’accord, votre programme contient quelque chose appelé Main. Mais où se trouve la méthode main ? L’ordinateur ne comprend pas que votre mot Main a le même sens que main (j’ai entendu parler d’un célèbre poète nommé victor hugo, mais qui diable est donc Victor Hugo  ?). Corrigez cette erreur, et tout rentrera dans l’ordre. Mais, si on y réfléchit un peu, comment cette utilisation incorrecte d’une majuscule peut-elle passer entre les mailles du filet du compilateur  ? Pourquoi d’erreur ?

celui-ci

n’émet-il

aucun

message

La réponse renvoie aux différents types de mots dans le langage de programmation Java. Comme je l’ai expliqué, dans le Chapitre 4, Java contient des mots-clés et des identificateurs. Les mots-clés de Java (je me répète) ne sont pas gravés dans le marbre. Si vous changez class en Class, ou public en Public, vous obtenez quelque chose de totalement nouveau  –  quelque chose que l’ordinateur ne peut probablement pas comprendre. C’est pourquoi le compilateur bute sur les motsclés qui sont mal orthographiés. Après tout, c’est son travail de vérifier que les mots-clés sont utilisés correctement. D’un

autre

existence

côté,

les

autonome.

identificateurs Bien

sûr,

il

ont

une

existe

un

identificateur appelé main, mais personne ne vous interdit d’en créer un autre appelé Main. Bien entendu, vous ne devriez jamais introduire quelque confusion que ce soit avec ce genre d’identificateur. Lorsque le compilateur rencontre une ligne mal orthographiée, comme public static void Main, il suppose que vous voulez définir un nouveau nom. Il laisse donc passer cette ligne et n’affiche aucun message d’erreur.

Par contre, dès que vous essayez de lancer le programme,

l’ordinateur

entre

en

transe.

La

machine virtuelle Java (JVM) essaie d’exécuter le code (voyez à ce sujet le Chapitre  1). La machine virtuelle a impérativement besoin de localiser un point

de

départ

appelé

main

(avec

un

m

minuscule). Comme elle ne le trouve pas, elle affiche un message pour le signaler. C’est donc la machine virtuelle, et non le compilateur, qui vous avertit du problème.

Un problème ? Quel problème ? Pour terminer ce chapitre, je vais vous montrer quelques-unes

des

choses

que

vous

pouvez

modifier dans le Listing  5.1  sans vous attirer les foudres du ciel.

Les identificateurs que vous créez Si vous créez un identificateur, donnez-lui un nom explicite. Par exemple, sur le Listing  5.1, vous pourriez changer mon EchoLine en RepeteApresMoi (sans accents).

class RepeteApresMoi { public static void main ... etc . Ceci ne pose aucun problème, dès lors que vous restez

cohérent

dans

votre

démarche.

Suivez

simplement les étapes décrites vers le début de ce chapitre, à la section «  Taper et exécuter un programme 

»

,

en

saisissant

votre

nom

personnalisé lors des Étapes 6 et 8. Plutôt que de commencer votre programme avec seulement le mot class, vous pouvez le lancer avec les mots public class. Si c’est le cas, changer le mot EchoLine en RepeteApresMoi pourrait vous attirer

des

débutant,

ennuis.

la

Pour

solution

la

vous, plus

programmeur simple

est

de

supprimer le mot public.

Espaces et indentations Java ne vous impose rien de particulier quant à l’utilisation

des

Simplement,

espaces

vous

devez

et

des

veiller

indentations. à

la

bonne

organisation et à la lisibilité de vos programmes. Voici par exemple une alternative à la présentation du Listing 5.1 :

import java.util.Scanner; class EchoLine { public static void main( String args[] ) { Scanner keyboard = new Scanner( System.in ); System.out.println ( keyboard.nextLine() ); keyboard.close(); } }

Faire vos choix Les programmes sont comme des empreintes digitales. Il n’y en a pas deux qui se ressemblent. Si deux personnes créent, chacune de leur côté, un programme censé répondre au même problème, vous pouvez être certain que le résultat sera différent. Chacun possède son propre style, et le style de chacun est unique. À titre d’exemple, j’ai demandé à un de mes amis d’écrire son programme EchoLine sans lui montrer le code du Listing 5.1. Voici ce qu’il a écrit :

import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class EchoLine { public static void main(String[] args) throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String input = br.readLine(); System.out.println(input); } } Ne vous souciez pas des mots que vous ne connaissez pas. Constatons simplement que les deux programmes font la même chose. C’était le but. La morale de l’histoire, c’est que votre code ne ressemblera pas à celui de quelqu’un d’autre et qu’il n’en sera pas pour autant moins bon. C’est encourageant.

Erreurs de compilation Le

vaccin

ROR

vous

aide

à

développer

une

immunité contre la rougeole en provoquant un léger cas de rougeole. De la même manière, vous

pouvez améliorer votre immunité contre les erreurs de programmation en provoquant des erreurs intentionnelles dans de petits programmes Java jetables. Peu importe le nombre d’années que vous aurez passées à écrire du code, vous aurez toujours des erreurs de programmation dans tout nouveau code que

vous

écrirez.

Même

les

programmeurs

professionnels les plus expérimentés font des erreurs. Mais en vous entraînant avec quelques cas simples, vous pourrez découvrir certaines erreurs que les débutants font le plus souvent, et vous habituer au cycle incontournable «  coder, tester, corriger, coder à nouveau » . Essayez les méthodes suivantes pour introduire des erreurs

(volontaires  !

)

dans

le

listing

du

programme 04-01 : » Dans le mot println, changez la lettre minuscule l en un chiffre 1. » Déplacez toute la ligne System.out.println de sorte qu’elle se trouve au-dessus de la ligne public static void main. » Supprimez les parenthèses autour de ("Chocolat, argent, sommeil").

» Supprimer les guillemets autour de "Chocolat, argent, sommeil". » Partagez le texte entre guillemets sur plusieurs lignes, comme suit : System.out.println("Chocolat, argent, sommeil"); » Ouvrez votre programme de traitement de texte préféré (Microsoft Word, Apple Pages, ou autre) et créez un document contenant uniquement le texte "Chocolat, argent, sommeil". Très probablement, votre traitement de texte utilisera automatiquement des guillemets comme ceux-ci : « ». Ces guillemets ne sont pas bons pour un programme Java. Copiez donc ce texte à partir de votre traitement de texte. Dans l’éditeur d’Eclipse, collez le texte ainsi copié à la place de celui qui se trouve dans le code, guillemets compris. Voyez le type de « messages » d’erreur qu’Eclipse affiche.

Changements acceptables dans l’espacement et l’indentation

Vous

ne

pouvez

pas

répartir

une

chaîne

de

caractères entre guillemets (comme "Chocolat, argent, sommeil") sur deux ou trois lignes. Mais, dans d’autres parties d’un programme Java, les sauts

de

Expérimenter

ligne en

n’ont

pas

modifiant

d’importance.

l’espacement

et

l’indentation dans le code de la classe ThingsILike. Essayez d'exécuter ce code : import java.util.Scanner; class ThingsILike { public static void main (String[] args) { Scanner keyboard = new Scanner (System.in); System.out.println ("Chocolat, argent, sommeil"); keyboard.close (); } }

Chapitre 6

Utiliser les blocs de construction : variables, valeurs et types DANS CE CHAPITRE : » Déclarer des variables » Affecter des valeurs à des variables » Travailler avec les nombres » Utiliser les types Java

1946, John von Neumann écrivit un article E n révolutionnaire sur la nouvelle technologie émergente des ordinateurs et l’informatique. Parmi bien d’autres idées, il établit un fait fondamental  : au-delà de leur complexité, le principal travail des ordinateurs consiste à déplacer des données d’un endroit à un autre. Prenons un nombre, disons le montant du compte en banque d’une personne. Déplacez ce nombre de la mémoire de l’ordinateur

vers son unité centrale de traitement. Ajoutez quelques euros à cette valeur, remettez-la ensuite dans la mémoire de l’ordinateur, et le tour est joué. Le mouvement des données… Tout est là, et il n’y a rien d’autre. Ce

chapitre

va

donc

vous

montrer

comment

déplacer vos données.

Utiliser des variables Partons d’une situation simple. Vous achetez un machin quelconque sur un site Internet appelé SnitSoft. Vous cliquez sur un bouton pour valider votre panier d’achats. Vous vérifiez bien sûr votre commande, qui se monte par exemple à 5,95  € pour le zizigougou qui plaît tant à votre fille, plus  25  € de frais de port (ça, c’est le prix de la tranquillité). Vous cliquez en râlant sur le bouton qui finalise la commande, et voilà votre carte bancaire bientôt rançonnée par la famille. En toile de fond, c’est un programme d’ordinateur qui calcule le montant de l’arnaque. Ce programme pourrait ressembler au code du Listing 6.1. LISTING

6.1 Arnaque et compagnie.

class SnitSoft { public static void main(String args[]) { double amount; amount = 5.95; amount = amount + 25.00; System.out.print("Nous allons prélever "); System.out.print(amount); System.out.println(" € sur votre carte bancaire."); } } Si j’exécute ce code sur mon ordinateur (fort heureusement, tout cela n’est que virtuel), j’obtiens la sortie illustrée sur la Figure 6.1.

FIGURE

6.1

Exécuter le code du Listing 6.1.

Utiliser une variable

Le Listing  6.1  utilise ce que l’on appelle une variable : amount (le montant à payer). Une variable est comme un conteneur. Vous pouvez placer un nombre comme  5.95 dans une variable. Mais vous pouvez ensuite changer d’avis, et enregistrer une autre valeur, par exemple  30.95, dans cette même variable. Donc une variable varie. C’est sa nature. Bien entendu, si vous changez le contenu d’une variable, l’ancien nombre est perdu (à moins que vous ne l’ayez sauvegardé ailleurs). Souvenez-vous que Java n’aime pas les virgules dans les nombres décimaux. Il lui faut un point. Point. La Figure  6.2  illustre la situation avant et après l’exécution

du

code

du

Listing  6.1.

Lorsque

l’ordinateur traite l’instruction amount = 5.95, la variable amount

se voir affecter la valeur  5.95.

Ensuite, une fois l’instruction amount = amount + 25.00

exécutée,

brusquement

cette

également

variable

à  30.95.

devient

Quand

vous

employez le mot variable, vous ne faites en réalité que parler de choses électroniques dont l’état est modifié pour mémoriser 5.95, 30.95 ou tout ce que vous voulez d’autre. Sur la Figure 6.2, imaginez que

chaque boîte est entourée de millions d’autres boîtes semblables.

FIGURE 6.2 Il

faut

Une variable (avant et après).

bien

maintenant

parler

un

peu

de

terminologie. Vous pouvez vous reporter pour cela à la Figure 6.3. La chose qui est enregistrée dans une variable est appelée une valeur. La valeur d’une variable peut changer au cours de l’exécution d’un programme

(par

exemple

lorsque

le

prix

du

zizigougou et du port sont ajoutés). Cette valeur n’est pas nécessairement un nombre. Il peut tout aussi bien s’agir d’une lettre, d’un mot, d’un texte entier, etc. Le genre de la valeur enregistrée dans une

variable

est

appelé

son

type.

Vous

en

apprendrez plus sur les types dans la suite de ce

chapitre ainsi que dans les deux chapitres qui suivent.

FIGURE 6.3

Une variable, sa valeur et son type.

Il y a une différence subtile, presque indécelable, entre une variable et un nom de variable. Dans ce livre, j’utilise souvent le mot variable à la place de nom de variable. Strictement parlant, amount est le nom de la variable, et toute la mémoire mobilisée par ce montant (y compris sa valeur et son type) est la variable proprement dite. Si vous trouvez cette distinction trop subtile pour mériter de vous y attarder, bienvenue au club.

Chaque variable a un identificateur, c’est-à-dire un nom que vous pouvez définir et utiliser dans votre propre code (revoyez à ce sujet le Chapitre 4). Dans l’exemple du Listing 6.1, j’ai défini l’identificateur appelé amount.

Comprendre les instructions d’affectation Les instructions qui contiennent un signe égal, comme dans le Listing  6.1  sont appelées des instructions

d’affectation.

Dans

une

instruction

d’affectation, vous assignez une valeur à quelque chose. Le plus souvent, ce quelque chose est une variable. Vous

devriez

prendre

l’habitude

de

lire

les

instructions d’affectation de droite à gauche. Par exemple, la première affectation du Listing  6.1  dit en réalité : « Affecter 5.95 à la variable amount » . La seconde affectation est un tout petit peu plus compliquée.

Elle

pourrait

s’écrire

ainsi 

:

« Ajouter 25.00 à la valeur qui se trouve déjà dans la variable amount, et faire de ce résultat (30.95) la nouvelle valeur de la variable amount » . Cette

séquence

est

illustrée

graphiquement

sur

la

Figure 6.4.

FIGURE 6.4

Une affectation doit se lire de la droite vers la gauche.

Dans une instruction d’affectation, la chose à laquelle est assignée une valeur se trouve toujours à gauche du signe égal.

Envelopper ou développer ? Les

trois

dernières

instructions

du

Listing 6.1  utilisent une astuce. Vous voulez que le programme affiche une seule ligne sur l’écran, mais en fait cette ligne est formée de trois éléments différents :

» La ligne commence par Nous allons prélever. » Elle se poursuit avec la valeur de la variable amount. » Elle se termine par € sur votre carte bancaire. Comme ces éléments sont distincts, vous les placez sur trois lignes différentes. Les deux premières instructions sont des appels à System.out.print. La dernière appelle System.out.println. La différence entre les deux, c’est que print affiche le texte voulu, et laisse le curseur en place. Les deux premières parties de la phrase se suivent donc poliment. Par contre, println, déjà rencontré, passe à la ligne suivante une fois le texte affiché. Elle termine donc le travail. Ce fonctionnement est illustré sur la Figure 6.5.

FIGURE 6.5

Les rôles joués par System.out.print et

Systemp.out. println.

Un appel à System.out.print écrit quelque chose et laisse le curseur en place. System.out.println écrit quelque chose, puis renvoie le curseur au début de la ligne suivante.

OUBLIEZ CE QUE VOUS VENEZ DE VOIR Dans le Listing  6.1, et dans d’autres exemples de ce livre, je fais quelque chose que les programmeurs expérimentés évitent

de

faire.

J’ai

mis

des

nombres

réels,

tels

que  5.95  et  25.00  dans mon code Java. C’est ce que l’on appelle le codage en dur des valeurs. J’ai codé les valeurs en dur

pour

que

ces

exemples

d’introduction

à

la

programmation restent aussi simples que possible. Mais, dans la plupart des applications de la vie réelle, le codage en dur est une mauvaise chose. Imaginez qu’un jour SnitSoft augmente ses frais d’expédition et de manutention de  25,00  € à 35,00  €. Le programme du Listing  6.1  ne fonctionnera plus correctement. Quelqu’un doit lancer Eclipse, vérifier le code, changer le code, tester le nouveau code, et distribuer ce nouveau code aux personnes qui l’exécutent. Quel pensum ! Pour le programme de dix lignes du Listing  6.1, ce processus va prendre quelques minutes. Pour un programme de 10000 lignes dans un contexte réel, ce processus peut prendre des jours, des semaines ou des mois. Au lieu de coder les valeurs en dur, vous devriez les taper sur le clavier pendant l’exécution du programme. Si ce n’est pas une solution pratique, votre programme peut lire les valeurs voulues sur le disque dur d’un ordinateur. D’une façon ou

d’une autre, vous devriez concevoir votre programme pour qu’il fonctionne avec toutes les valeurs possibles, et pas seulement

avec

des

valeurs

spécifiques

telles

que 5.95 et 25.00. Continuez à lire les exemples de ce livre. Quand vous y voyez des valeurs codées en dur, rappelez-vous que je le fais uniquement pour vous éviter d’être distrait par des problèmes d’entrée et de sortie. Je veux que vous restiez concentré sur les nouvelles idées que chaque exemple propose. Je ne fais pas de codage en dur pour vous convaincre

qu’il

s’agit

d’une

bonne

pratique

de

programmation. En fait, ça ne l’est pas du tout.

Ils veulent dire quoi, tous ces zéros et ces un ? Voici un mot anglais : gift En français, on traduit ce mot par cadeau. Mais là n’est pas la question. En fait, le sens de ce mot dépend de qui le regarde. Par exemple pour un Anglo-saxon, il évoque une boîte entourée d’un papier brillant et d’un nœud coloré. Mais, pour un Allemand,

ce

même

mot

a

une

tout

autre

signification  : poison  ! Et en suédois, gift peut vouloir dire marié ou poison ( «  dès qu’ils furent mariés, elle glissa du poison dans le verre de son mari  » pourrait peut-être être le pitch d’un futur Millenium  ?). La question est donc  : que signifient en réalité les lettres g-i-f-t  ? Réponse  : rien jusqu’à ce que vous décidiez de la manière de les interpréter. Et c’est pareil pour les zéros et les un enregistrés dans les circuits électroniques d’un ordinateur. Prenons par exemple la séquence  01001010. Elle peut

représenter

la

lettre

J,

mais

aussi

le

nombre  74, ou même  1.0369608636003646×10-43. Et si on l’interprète comme représentant une succession de pixels d’écran allumés (1) ou éteints (0), elle peut tout aussi bien se traduire par l’illustration de la Figure  6.6. La signification de  01001010  dépend

donc

entièrement

de

manière dont le logiciel interprète cette séquence.

la

FIGURE 6.6

Noir ou blanc ? Zéro ou un ?

Types et déclarations Comment expliquer à l’ordinateur la signification de la suite 01001010 ? La réponse se trouve dans le concept appelé type. Le type d’une variable décrit la nature des valeurs qu’elle peut enregistrer. Regardez par exemple la première ligne du corps de la méthode main : double amount ; Cette ligne est appelée une déclaration de variable. Placer cette ligne dans votre programme est comme dire  : «  Je déclare mon intention d’avoir une variable appelée amount dans mon programme » . Elle réserve donc ce nom pour la suite des événements.

Dans cette déclaration, double est un mot-clé de Java. Il indique à l’ordinateur quel est le type de valeur que vous avez l’intention d’y enregistrer. En particulier, le double signifie que cette valeur est comprise

entre  –1.8×10-308  et  1.8×10308.

C’est

évidemment énorme. Sans sa notation sous forme de puissance, ce second nombre est :

Quand vous achetez quelque chose sur Internet, ou ailleurs, le montant de votre facture est stocké dans une variable de type double (sans les puissances, je l’espère pour vous).

Faisons le point Plus important que le faramineux intervalle de valeurs

qu’un

nombre

de

type

double

peut

représenter est le fait qu’il peut s’agir de valeurs décimales, autrement dit avec des chiffres situés après la virgule. Ou plus exactement ici du point. Une fois que vous avez déclaré la variable amount comme étant de type double, vous pouvez lui

affecter des valeurs comme  5.95, 0.02398479  ou  – 3.0. Si, dans le Listing 6.1, je n’avais pas précisé que amount était de type double, je n’aurais pas pu y stocker la valeur 5.95, mais uniquement 5, ou peutêtre 6. Mais en tout cas rien qui peut venir après le point décimal. Pour plus d’informations sur les valeurs décimales, voyez le Chapitre 7. Ce paragraphe traite d’un point très délicat, vous pouvez donc le sauter si vous n’êtes pas d’humeur. Les gens utilisent souvent l’expression nombre décimal pour décrire un nombre avec des chiffres à la droite de la virgule ou du point décimal. Le problème est que la syllabe «  dec  » représente le chiffre  10, donc le mot décimal implique une représentation ordinateurs

en

base  10.

utilisent

une

Du

fait

que

les

représentation

en

base  2  (et non en base  10), le mot décimal pour décrire un tel nombre est un terme erroné. Mais, dans ce livre, je les appelle des nombres décimaux, que cela fasse ou non plaisir aux puristes. Voici quelques petites choses à essayer :

Changer les chiffres Modifiez

les

valeurs

numériques

dans

le

Listing  6.1  et exécutez le programme avec les nouveaux nombres.

Faire varier une variable Dans le Listing  6.1, changez le nom de la variable amount. Modifiez ce nom de façon uniforme dans l’ensemble du code du Listing 6.1. Exécutez ensuite le programme avec ce nouveau nom de variable.

Utiliser des traits de soulignement Modifiez le code du Listing 6.1 de façon à ce que les frais d’expédition et de manutention s’élèvent à 



million

d’euros.

Utilisez  1_000_000_000.00  (avec de traits de soulignement) pour représenter le montant en millions d’euros.

Plus d’informations, SVP ! Modifiez le code du Listing  6.1  pour qu’il affiche trois valeurs  : le prix original du zizigougou, les frais d’expédition et de manutention, et le coût combiné.

Lire des nombres décimaux à partir du clavier Incroyable  ! Je n’en crois pas mes yeux  ! Pendant seulement

une

semaine,

SnitSoft

fait

une

promotion spéciale sur les zizigougous au prix extraordinaire de  5,75  €  ! Il faut se dépêcher pour passer commande. Attendez  ! Dans le Listing  6.1, le prix est fixé à 5,95 €. Il faut donc que je modifie le programme. Je sais. J’aurais dû rendre le code plus souple afin de permettre de saisir le prix directement sur le clavier. Bien. Le Listing 6.2  montre le code corrigé et la Figure 6.7 illustre l’exécution de ce code. LISTING

6.2 L’arnaque continue.

import java.util.Scanner; class VersatileSnitSoft { public static void main(String args[]) { double amount; Scanner keyboard = new Scanner(System.in);

System.out.print("Quel est le prix d'un zizigougou ? "); amount = keyboard.nextDouble(); amount = amount + 25.00; System.out.print("Nous allons prélever "); System.out.print(amount); System.out.println(" € sur votre carte bancaire."); keyboard.close(); } }

FIGURE 6.7

Obtenir la valeur d’une variable double.

Le traitement des valeurs décimales dans Java reconnaît uniquement le point décimal. Par contre, Java sait dans quel pays vous vous trouvez, et comment les nombres s’écrivent dans votre langue. Il se charge tout seul de faire la conversion. Vous devez donc saisir 5,75, et non 5.75. Utiliser le point au lieu de la virgule dans votre saisie se traduirait

par une très sévère erreur d’exécution, comme l’illustre la Figure 6.8.

FIGURE 6.8

Pour les valeurs décimales, c’est virgule en entrée, point

en sortie. Sinon, malheur à vous !

Des méthodes, mais spéciales Remarquez l’appel à la méthode nextDouble dans le

Listing  6.2.

Souvenez-vous

que

pour

le

Listing 5.1, j’avais fait appel à nextLine. Voilà donc une autre manière de lire l’entrée au clavier. En Java, chaque type de saisie réclame sa propre méthode spéciale. Si vous voulez récupérer une ligne de texte, nextLine est parfait. Mais si vous voulez que la saisie soit interprétée comme étant un nombre, vous avez besoin d’une méthode comme nextDouble. Pour passer du Listing 6.1 au Listing 6.2, j’ai ajouté une déclaration import quelque chose concernant

new Scanner(System.in). Si vous avez besoin de faire quelques révisions à ce sujet, reportez-vous au Chapitre  5  (le Chapitre  13  vous en dira encore plus

sur

les

entrées

et

les

sorties).

Les

Chapitres 7 et 8 proposent également des exemples supplémentaires

d’utilisation

des

méthodes

keyboard.Quelquechose.

Méthodes et affectations Notez

la

manière

d’employer

keyboard.nextDouble dans le Listing 6.2. L’appel à

cette

méthode

faite

partie

de

l’instruction

d’affectation. Si vous regardez dans le Chapitre 5 la section

qui

explique

comment

fonctionne

le

programme EchoLine, vous verrez que l’ordinateur peut substituer quelque chose à la place d’un appel de méthode. C’est aussi ce qui se passe pour le Listing  6.2. Lorsque vous tapez  5,75 au clavier, l’ordinateur transforme amount = keyboard.nextDouble(); en amount = 5.75;

Au passage, il convertit votre virgule en un point. Bien entendu, le code du Listing  6.2  n’est pas réellement réécrit. La ligne ci-dessus est juste une illustration

de

l’action

de

l’ordinateur.

Dans

l’instruction suivante du Listing  6.2, l’ordinateur calcule la somme de  5.75  et de  25.00, et il stocke cette nouvelle valeur dans amount. Certains appels de méthode provoquent cet effet de substitution,

et

(System.out.println)

d’autres non.

comme Pour

d’informations à ce sujet, voyez le Chapitre 19.

plus

QUI FAIT QUOI, ET COMMENT ? Lorsque vous écrivez un programme, vous êtes appelé programmeur. Et lorsque vous exécutez un programme, on vous appelle un utilisateur. Lorsque vous testez le code que vous avez écrit, vous êtes donc à la fois programmeur et utilisateur. Supposons que votre programme contienne un appel du style keyboard.nextQuelquechose(), comme dans les Listings  5.1  et  6.2. Votre programme demande donc une saisie de l’utilisateur. Mais comment l’utilisateur sait-il qu’il doit taper quelque chose sur son clavier  ? Et quel genre de chose  ? Si l’utilisateur et le programmeur sont une seule et même personne, c’est plutôt évident. Par exemple, vous avez ce livre devant les yeux, vous suivez les exemples et vous savez ce que je vous demande de faire  : taper une phrase, taper un nombre, et ainsi de suite. Mais très peu de programmes sont fournis avec leur propre livre. Dans la plupart des cas, lorsqu’un programme se lance, l’utilisateur doit regarder son écran pour savoir ce qu’il doit faire ensuite. Le code du Listing  6.2  fonctionne selon ce scénario. Le premier appel à print affiche en effet sur l’écran de l’utilisateur un message plutôt explicite (Quel est le prix d’un zizigougou  ?). Les Anglo-saxons appellent ce genre

de message une invite (prompt). Presque un prompteur, quoi. Lorsque vous commencez à écrire des programmes, vous pouvez facilement confondre le rôle de l’invite et de la saisie de l’utilisateur. Mais il n’existe aucun lien préréglé à l’avance entre les deux. Pour créer une invite, vous appelez print ou println. Pour lire la saisie de l’utilisateur, vous appelez nextLine,

nextDouble

ou

l’une

des

autres

méthodes

nextQuelquechose de la classe Scanner. Ces print et ces next se trouvent sur deux lignes d’instructions différentes. Java ne contient rien en soi qui vous permettrait de regrouper les deux dans une seule instruction. Combiner les deux, c’est votre travail de programmeur. Cela peut se faire de multiples manières, certaines qui vont aider l’utilisateur, et d’autres pas. » Si vous n’appelez pas print ou println, alors l’utilisateur ne voit aucun message. En fait, il ne voit qu’un

curseur

clignotant,

qui

attend

une

saisie

quelconque de la part de l’utilisateur. C’est lui qui doit deviner ce qu’il doit faire. Parfois, cela marche, mais le plus souvent ce n’est pas le cas. » Si vous appelez print ou println, mais pas la méthode

keyboard.

nextQuelquechose,

l’ordinateur ne va rien attendre de la part de

l’utilisateur. Le programme continue tout bêtement son exécution sans s’occuper du reste du monde. » Si votre invite affiche un message inadapté, vous induisez l’utilisateur en erreur. Java n’a aucune fonction qui pourrait servir à vérifier que vous ne racontez pas n’importe quoi. Ce n’est pas surprenant. Ce n’est pas son affaire, mais la vôtre. Faites donc très attention à vos invites. Soyez gentil avec vos utilisateurs. Et ne l’oubliez pas  : vous aussi, vous êtes un utilisateur d’ordinateur.

Variations sur un thème Dans le Listing 6.1, deux lignes servent à donner à la variable amount sa première valeur : double amount; amount = 5.95; Vous pourriez résumer tout cela en une seule ligne : double amount = 5.95; Cette

syntaxe

n’est

plus

une

instruction

d’affectation. On l’appelle une déclaration avec

initialisation. Vous initialisez la variable amount que vous déclarez comme étant de type double. Vous pouvez faire tout un tas de choses avec les initialisations, y compris des calculs : double factureGaz = 174.59; double factureElec = 84.21; double factureH2O = 22.88; double total = factureGaz + factureElec + factureH2O;

Déplacer les variables Il est utile de se rappeler la différence entre initialisations et affectations. Par exemple, vous pouvez

faire

sortir

une

déclaration

initialisation en dehors d’une méthode. // Ce code est bon : class SnitSoft { static double amount = 5.95; public static void main(String args[]) { amount = amount + 25.00; System.out.print("Nous allons prélever ");

avec

System.out.print(amount); System.out.println("€ sur votre carte bancaire."); } } Mais vous ne pouvez pas faire la même chose avec les instructions d’affectation, comme le montrent le code qui suit et la Figure 6.9. // Ce code ne se compilera pas : class BadSnitSoftCode { static double amount; amount = 5.95; // Instruction mal placée public static void main(String args[]) { amount = amount + 25.00; System.out.print("Nous allons prélever "); System.out.print(amount); System.out.println("€ sur votre carte bancaire."); } }

FIGURE 6.9

Ce code ne sera pas compilé.

Vous ne pouvez pas déplacer des instructions en dehors des méthodes. Et même si une déclaration de variable se termine par un point-virgule, elle n’est

pas

considérée

comme

une

instruction.

Sachez-le. L’avantage de placer une déclaration en dehors d’une méthode est illustré dans le Chapitre 17. Tout en

attendant

impatiemment

d’atteindre

ce

chapitre, notez que j’ai ajouté le mot static au début

de

chacune

des

déclarations

que

j’ai

déportées. J’ai dû le faire, car l’en-tête de la méthode main contient aussi le mot static. Toutes les méthodes ne sont pas statiques, et la plupart ne le sont d’ailleurs pas. Mais chaque fois que vous effectuez une déclaration en dehors d’une méthode

statique, vous devez la faire précéder du mot static. Tous les mystères autour de ce mot seront révélés dans le Chapitre 18.

Combiner les déclarations de variables Le code du Listing  6.1  ne contient qu’une seule variable (comme si les stocks étaient presque épuisés). Mais vous pouvez parfaitement obtenir le même effet avec plusieurs variables. class SnitSoftNew { public static void main(String args[]) { double cdPrice; double shippingAndHandling; double total; cdPrice = 5.95; shippingAndHandling = 25.00; total = cdPrice + shippingAndHandling; System.out.print("Nous allons prélever "); System.out.print(total); System.out.println("€ sur votre

carte bancaire."); } } Ce nouveau code donne exactement le même résultat que celui du Listing 6.1. Il contient trois déclarations, une pour chaque variable utilisée dans le programme. Comme elles possèdent toutes le même type (double), il est possible de modifier ce programme pour frapper un grand coup : double cdPrice, shippingAndHandling, total; Lequel est le meilleur ? Une ou trois déclarations  ? Ni l’une ni l’autre. C’est une question de style personnel. Vous

pouvez

même

combiner

déclarations

et

initialisations. Dans ce cas, chaque initialisation ne concerne qu’une seule variable. Par exemple, la ligne : double cdPrice, shippingAndHandling = 25.00, total;

affecte

la

valeur 

25.00 

à

la

variable

shippingAndHandling, mais les deux autres n’ont aucune valeur particulière (on dit aussi qu’elles sont indéfinies). Aimeriez-vous vous exercer avec les concepts de cette section ? C’est parti !

Donner un pourboire au préposé du parking Un blog en ligne vous avise qu’il faut payer un pourboire

de 



$

lorsqu’un

préposé

au

stationnement va chercher votre voiture dans un parking de la ville de New York. Rédigez un programme comme celui du Listing 6.2. Lorsque le programme est exécuté, vous tapez le prix affiché par le parking pour le stationnement de votre voiture. Le programme vous indique alors combien vous paierez après avoir ajouté le pourboire de 2 $.

Double tarif Modifiez le code du Listing  6.2  de sorte que, quel que soit le coût normal d’un zizigougou, le programme facture le double de ce montant. En d’autres termes, le prix d’un zizigougou de 5 € finit

par être de 10 €, et le prix d’un disque dur de 100 € devient 200 €.

Expériences avec JShell Les programmes de ce livre commencent tous par le même refrain répétitif et lassant : class SomethingOrOther { public static void main(String args[]) { Retaper ce code standard dans l’éditeur d’Eclipse peut être ennuyeux, surtout lorsque votre but est simplement de tester l’exécution de quelques instructions simples. Pour résoudre ce problème, les stewards de Java ont mis au point un nouvel outil disponible depuis Java  9, et qu’ils appellent JShell. Lorsque vous utilisez JShell, vous tapez rarement un programme entier. Au lieu de cela, vous saisissez une instruction Java, puis JShell répond à votre

demande.

Vous

tapez

une

deuxième

instruction, et JShell répond à nouveau à cette deuxième demande, et ainsi de suite. Une seule

instruction suffit pour obtenir une réponse de JShell. JShell n’est qu’un exemple de la boucle dite REPL, c’est-à-dire lecture  –  évaluation  –  impression d’impression.

De

nombreux

langages

de

programmation ont des REPL et c’est le cas pour Java depuis sa version 9 (donc, pas avant).

Lancer JShell Pour exécuter JShell, assurez-vous d’avoir installé Java 9 ou une version supérieure (si vous avez suivi les instructions données au début de ce livre, vous devriez en être à Java  12, et pourquoi pas plus encore ?).

Pour lancer JShell sur un ordinateur Windows 1. Ouvrez une fenêtre d’Invite de commandes. Sous Windows 7 : Appuyez sur Win+R, puis tapez cmd, puis appuyez sur Entrée. Sous Windows 8 : Sur l’écran Démarrer, appuyez sur Win+Q. Dans le champ de recherche résultant,

tapez l’invite de commande, puis appuyez sur Entrée. Sous Windows 10 : Choisissez Démarrer -> Système Windows -> Invite de commandes. 2. Dans la fenêtre Invite de commandes, tapez les commandes suivantes : cd "\Program Files\Java" dir jdk* Sur certains ordinateurs, vous aurez peut-être plus de chance en tapant cd "\Program Files (x86)\Java" pour la première des deux commandes. La fenêtre Invite de commandes répond en listant certains noms de répertoires. 3. Dans la réponse de la fenêtre Invite de commandes, recherchez un dossier dont le nom commence par jdk-12, ou quelque chose comme cela (disons au moins jdk-9). Les répertoires dont le nom commence par jdk1.8 ou moins ne fonctionneront pas. Vous devez avoir Java 9 ou plus d’installé pour exécuter JShell.

Dans l’étape suivante, je suppose que vous avez trouvé un dossier nommé jdk-12. Si le vôtre a un nom différent, ajustez votre saisie pour qu’elle corresponde à ce nom. 4. Dans la fenêtre Invite de commandes, tapez les commandes suivantes : cd jdk-12\bin jshell

Si tout se passe bien, la fenêtre de l’Invite de commandes affiche l’invite JShell>. C’est ainsi que vous savez que vous avez lancé JShell avec succès.

Pour lancer JShell sur un Mac 1. Appuyez sur Command+barre d’espace, puis tapez Terminal, et appuyez sur Entrée. L’application Terminal de votre ordinateur démarre. 2. Dans la fenêtre de l’application Terminal, tapez les commandes suivantes : cd /Library/Java/JavaVirtualMachines dir jdk*

L’application Terminal répond en listant des noms de répertoires. 3. Dans la réponse de l’application Terminal, cherchez un répertoire nommé jdk-12.jdk, ou quelque chose comme ça. Les répertoires dont le nom commence par jdk1.8 ou moins ne fonctionneront pas. Vous devez avoir Java 9 ou une version supérieure installée pour pouvoir exécuter JShell. Dans l’étape suivante, je suppose que vous avez trouvé un répertoire nommé jdk-12.jdk. Si votre répertoire a un nom différent, ajustez votre saisie pour qu’elle corresponde à ce nom. 4. Dans la fenêtre de l’application Terminal, tapez les commandes suivantes : cd jdk-12.jdk/Contents/Home/bin ./jshell Si tout se passe bien, l’application Terminal affiche l’invite JShell>. C’est ainsi que vous savez que vous avez lancé JShell avec succès.

Utiliser JShell

Sur la Figure 6.10, j’utilise JShell pour expérimenter les concepts Java de ce chapitre. Lorsque vous ouvrez JShell, le dialogue ressemble à quelque chose comme ceci : jshell> Vous tapez une instruction JShell répond jshell> Vous tapez une autre instruction JShell répond Par exemple, sur la Figure  6.10, j’ai tapé double amount et j’ai appuyé sur Entrée. JShell répond en affichant :

FIGURE 6.10

Une conversation intime entre moi et JShell.

amount ==> 0.0 Ensuite, j’ai tapé amount répondu par : amount ==> 5.95

=

5.95, et JShell a

Quand je tape alors amount = amount + 25.00, JShell revient avec un amical : amount ==> 30.95 Voici quelques éléments à noter à propos de JShell : » Vous n'avez pas besoin de taper un programme Java complet. Saisir quelques déclarations telles que : double amount amount = 5.95 amount = amount + 25.00 suffit à faire le travail. C’est un peu comme exécuter le code du Listing 4.1 dans la fenêtre d’Eclipse. » Dans JShell, les points-virgules sont (dans une certaine mesure) facultatifs. Sur la Figure 6.10, je ne me donne pas la peine de terminer les lignes par des points-virgules. » JShell répond immédiatement après chaque ligne. Après avoir déclaré amount comme étant double, JShell me répond que la variable amount

a pour valeur 0.0. Après avoir saisi amount = amount + 25,00, JShell m’informe que la nouvelle valeur de amount est 30.95. La Figure 6.11 illustre quelques autres sympathiques fonctionnalités de JShell.

FIGURE 6.11

Utiliser JShell pour évaluer des expressions.

» Vous pouvez demander à JShell la valeur d’une expression. Vous n'avez pas besoin d’assigner la valeur de l’expression à une variable. Par exemple, sur la Figure 6.11, je tape :

factureGaz + factureElec JShell répond en me disant que la valeur de factureGaz + factureElec est de 258.8. JShell crée un nom temporaire pour cette valeur. Sur la Figure 6.11, ce nom est $3. » Vous pouvez même obtenir des réponses de JShell sans utiliser de variables. Sur la Figure 6.10, je demande la valeur 42 + 7, et JShell répond généreusement avec la valeur 49. JShell compose le nom temporaire $4 pour cette valeur. Donc, à la ligne suivante de la Figure 6.11, je demande la valeur de $4 + 1, et JShell me donne la réponse voulue, 50. Lorsque vous exécutez JShell, vous n’avez pas besoin de retaper les commandes que vous avez déjà saisies. Si vous appuyez une fois sur la touche fléchée vers le haut, JShell réaffiche la commande précédente. Si vous appuyez deux fois sur la touche fléchée vers le haut, JShell vous montre l’avantdernière commande que vous aviez tapée. Et ainsi de suite. Lorsque JShell affiche une commande, vous pouvez utiliser les touches fléchées gauche et droite pour vous déplacer vers n’importe quel

caractère à l’intérieur de celle-ci. Vous pouvez alors modifier les caractères de la commande. Une fois l’édition

terminée,

demander

à

JShell

appuyez

sur

d’exécuter

Entrée

votre

pour

nouvelle

commande. Pour terminer l’exécution de JShell, tapez /exit (en commençant par une barre oblique). Mais /exit n’est qu’une des nombreuses commandes que vous pouvez demander à JShell d’exécuter. Pour savoir quels autres types de commandes vous pouvez utiliser, tapez /help. Avec JShell, vous pouvez tester vos instructions avant de les mettre dans un programme Java complet. Cela fait de JShell un outil vraiment utile.

S’amuser avec JShell Lancez l’application JShell sur votre ordinateur. Tapez

les

instructions

suivantes,

l’une

l’autre, et regardez comment JShell répond : jshell> double bananeCalories = 100.0 jshell> double pommeCalories = 95.0 jshell> double sodalightCalories = 0.0

après

jshell> double cheeseburgerCalories = 500.0 jshell> bananeCalories + pommeCalories + ...> sodalightCalories + cheeseburgerCalories Notez que, dans JShell, une instruction peut s’étendre sur deux lignes ou plus. Après avoir tapé la première partie d’une instruction ? vous appuyez sur Entrée, comme dans : bananeCalories + pommeCalories + Ensuite, sur la ligne suivante, JShell n’affiche pas son invite jshell> habituelle. Au lieu de cela, il affiche ...>, ce qui indique que vous devriez continuer à taper la suite de la même instruction. Laissez JShell actif pour la prochaine expérience.

Se déplacer dans JShell Dans l’expérience précédente, vous avez entré un nombre de calories pour quatre aliments. Mais, parce que vous avez fait cette expérience, vous avez révisé à la hausse votre estimation du nombre de calories dans un cheeseburger.

JShell étant toujours en cours d’exécution, appuyez sur la touche fléchée vers le haut de votre clavier jusqu’à ce que vous voyiez l’instruction : double cheeseburgerCalories = 500.0 Appuyez ensuite sur la touche fléchée gauche jusqu’à ce que le curseur se trouve au début du nombre. Appuyez sur la touche de retour arrière ou de suppression de votre clavier pour effacer le chiffre 5, puis tapez 7 à la place. L’instruction se lit maintenant comme suit : double cheeseburgerCalories = 700.0 Appuyez sur Entrée pour confirmer que vous voulez que JShell exécute cette instruction révisée. Avec

la

valeur

de

cheeseburgerCalories

ainsi

réévaluée, utilisez les flèches vers le haut et vers le bas de votre clavier pour que JShell additionne les calories une seconde fois : jshell> bananeCalories + pommeCalories + ...> sodalightCalories + cheeseburgerCalories

Ne retapez pas les noms des variables. Laissez vos touches fléchées faire le travail !

Chapitre 7

Nombres et types DANS CE CHAPITRE : » Travailler avec des nombres entiers » Obtenir de nouvelles valeurs à partir d’anciennes » Comprendre les types Java plus exotiques

I pensaient

l n’y a pas si longtemps que cela, les gens que les ordinateurs ne savaient faire

que de grandes quantités de calculs. Ils résolvaient des problèmes d’arithmétique, et c’était la fin de l’histoire. Dans

les

années  1980,

avec

l’explosion

de

l’utilisation de traitements de texte, le mythe du gros cerveau calculateur métallique s’est estompé. Mais, en réalité, cela n’enlève rien au fait que les ordinateurs sont effectivement de puissants outils de calcul, extrêmement rapides et extrêmement précis. Ils n’ont jamais besoin de compter sur leurs doigts. De surcroît, les ordinateurs ne se sentent

jamais surchargés de travail lorsqu’ils font des calculs. Personnellement, j’aime bien jouer une heure au tennis après une bonne journée de travail. Les ordinateurs, eux, n’ont jamais besoin de se défouler (d’ailleurs, ils ne jouent pas au tennis).

Utiliser les nombres entiers Laissez-moi vous dire quelque chose. Ce n’est pas toujours facile d’être un adulte. Je suis dans le salon avec quatre enfants, et ils me regardent tous avec gourmandise, car je tiens un sachet plein de boules de gomme. Comme il y a trente friandises dans le sachet, les gamins sont tous là à se dire  : «  Qui va en avoir plus que les autres  ? Qui va être désavantagé  ?  » Ils veulent que la répartition se fasse équitablement, chacun recevant exactement le même nombre de boules de gomme. Je dois faire très attention. Sinon, je sens que je vais me faire de redoutables ennemis. Avec trente boules de gomme et quatre enfants, il n’est pas possible de répartir équitablement les friandises. Bien sûr, je pourrais tenter d’envoyer un enfant jouer ailleurs, et donner exactement dix boules de gomme aux trois autres. Mauvaise idée. Ma seule alternative est donc de diviser au mieux

les trente bonbons et de conserver le reste. La question posée est donc de calculer le nombre de boules de gomme que je vais distribuer à chaque enfant. Du coup, je me précipite sur mon ordinateur pour créer un programme qui va me donner la bonne réponse. Quand j’ai terminé, j’obtiens le code du Listing 7.1. LISTING

7.1 Comment empêcher une révolte

d’enfants. class KeepingKidsQuiet { public static void main(String args[]) { int gumballs; int kids; int gumballsPerKid; gumballs = 30; kids = 4; gumballsPerKid = gumballs / kids; System.out.print("Chaque enfant reçoit "); System.out.print(gumballsPerKid); System.out.println(" boules de

gomme."); } } La Figure 7.1 illustre l’exécution de ce programme. Si chaque enfant reçoit sept boules de gomme, ils ne pourront pas se plaindre que j’en ai favorisé un. Il faudra qu’ils trouvent autre chose pour se chamailler.

FIGURE

7.1

Juste et carré.

Au cœur de ce problème, il y a des nombres entiers, c’est-à-dire qu’aucun chiffre ne se trouve au-delà de

la

virgule

(ou

du

point

décimal).

Si

je

divise 30 par 4, j’obtiens 7,5. Rien à faire, je ne sais pas découper des boules de gomme exactement en deux.

Sinon,

un

des

gamins

va

forcément

s’exclamer : « Eh ! Sa moitié est plus grosse que la mienne ! C’est pas juste ! » Mais Java me permet d’arriver à la bonne solution. Sur le Listing  7.1, les trois variables (gumballs,

kids et gumballsPerKid) sont de type int. Une valeur

int

est

un

nombre

entier

(int

est

l’abréviation de integer, qui veut dire entier). Lorsque vous divisez une valeur entière par une autre valeur entière, vous obtenez un résultat entier. Ici, la vision de  30  par  4  donne donc  7, et non 7,5. C’est ce que vous voyez sur la Figure 7.1. Les deux instructions System.out.print(gumballsPerKid); System.out.println(" boules de gomme."); affichent le nombre 7 sur l’écran de l’ordinateur.

Lire des nombres entiers au clavier Quelle vie ! Hier, il y avait quatre enfants dans mon salon, et j’avais un sachet contenant trente boules de

gomme.

Aujourd’hui,

ils

sont

six

et

j’ai 80 boules de gomme. Comment gérer tout cela ? Je sais  ! Il faut que j’écrive un programme qui lise le nombre d’enfants et de boules de gomme au clavier.

Ce

programme

est

proposé

sur

le

Listing  7.2, et son exécution est illustrée sur la Figure 7.2.

LISTING

7.2 Un programme plus général pour les

enfants et les boules de gomme. import java.util.Scanner; class KeepingMoreKidsQuiet { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); int gumballs; int kids; int gumballsPerKid; System.out.print ("Combien de boules de gomme ? Combien d'enfants ? "); gumballs = keyboard.nextInt(); kids = keyboard.nextInt(); gumballsPerKid = gumballs / kids; System.out.print("Chaque enfant reçoit "); System.out.print(gumballsPerKid); System.out.println(" boules de gomme."); keyboard.close();

} }

FIGURE 7.2

Demain, 7 enfants et 1 000 boules de gomme…

Il y a plusieurs choses à remarquer sur le Listing  7.2. Tout d’abord, vous pouvez lire une valeur

entière

avec

la

méthode

nextInt

(reportez-vous au tableau dans le Chapitre 5). Ensuite, vous pouvez effectuer des appels successifs

aux

méthodes

Scanner.

Sur

le

Listing  7.2, j’ai appelé deux fois nextInt. Tout ce que j’ai à faire, c’est de saisir les deux nombres en les séparant par un espace. C’est ce que vous pouvez constater sur la Figure 7.2. Mais j’aurais pu tout aussi bien taper plusieurs espaces. Cette règle de séparation par un espace s’applique à la plupart des méthodes Scanner. Le code qui suit lit trois valeurs numériques : gumballs = keyboard.nextInt(); costOfGumballs = keyboard.nextDouble(); kids = keyboard.nextInt();

La Figure 7.3 montre une saisie valide pour ces trois appels de méthode.

FIGURE 7.3

Trois nombres pour trois appels à la méthode Scanner.

Ce que vous lisez est ce que vous obtenez Lorsque vous écrivez votre propre code, vous ne devriez jamais prendre quoi que ce soit pour argent comptant.

Supposons

accidentellement

que

l’ordre

vous des

inversiez instructions

d’affectation dans le Listing 7.2 : // Ce code est trompeur System.out.print("Combien de boules de gomme ? Combien d'enfants ? "); kids = keyboard.nextInt(); gumballs = keyboard.nextInt(); La question telle qu’elle est affichée devient extrêmement trompeuse. Du fait que l’affectation du nombre d’enfants (kids) précède celle du

nombre de boules de gomme (gumballs),

la

question est maintenant posée à l’envers. Ce n’est pas la question en elle-même qui crée le problème, mais l’ordre des affectations dans le programme. Évidemment, à question stupide, réponse idiote… Du moins, mauvaise réponse. Comme l’utilisateur va se fier à ce qui est affiché, il va par exemple saisir 80 6. L’ordinateur va alors considérer qu’il y a 80 enfants et 6 boules de gomme. Résultat : zéro friandise par enfant  ! C’est ce qu’illustre la Figure 7.4.

FIGURE 7.4

Comment rendre six enfants très malheureux.

Comme le savant fou dans un vieux film d’horreur, essayez ces expériences fascinantes !

Faites-le et cassez-le

Exécutez le programme du Listing  7.2. Quand le programme demande Combien

de

boules

de

gomme ? tapez  80.5  6  (vous pouvez aussi essayer de taper 80,5 au lieu de 80.5.) Quel message désagréable voyez-vous lors de cette exécution du programme ? Pourquoi voyez-vous ce message ?

Cassez-le encore une fois Exécutez le programme du Listing  7.2. Quand le programme demande Combien

de

boules

de

gomme ? tapez "80" "6" (avec les guillemets et tout). Quel message désagréable voyez-vous lors de cette exécution du programme ? Pourquoi voyez-vous ce message ?

Une petite machine à ajouter Écrivez un programme qui obtient deux chiffres du clavier et affiche la somme des deux chiffres.

Créer de nouvelles valeurs en appliquant des opérateurs

Quoi de plus réconfortant que votre vieil ami, le signe plus  ? C’est la première chose que vous avez apprise en calcul à l’école primaire. Pratiquement tout le monde sait additionner deux et deux. D’ailleurs, l’expression « comme deux et deux font quatre  » désigne bien quelque chose d’évident, de très facile. Chaque fois que vous voyez un signe plus, votre cerveau réagit immédiatement : « Ouf ! J’avais peur que ce ne soit plus compliqué. » Java a donc aussi un signe plus. Vous pouvez l’utiliser pour additionner deux nombres : int pommes, oranges, fruits; pommes = 5; oranges = 16; fruits = pommes + oranges; Évidemment,

le

signe

moins

est

également

présent : pommes = fruits - oranges; Pour multiplier et pour diviser, vous utilisez respectivement un astérisque et une barre oblique inverse :

double brutHoraire, paie, net; int heures; brutHoraire = 12.25; heures = 35; paie = brutHoraire * heures; ou bien : double distance, moyenne ; int heures ; distance = 60.72 ; heures = 3 ; moyenne = distance / heures ; Lorsque vous divisez une valeur int par une autre valeur

int,

vous

obtenez

une

valeur

int.

L’ordinateur conserve la partie entière et élimine le reste.

Si

vous

écrivez

System.out.println(11/4),

le

la résultat

ligne affiché

sera 2, pas 2.75. Si vous avez besoin d’une réponse décimale, définissez au moins l’un des deux nombres

comme

étant

de

type

double.

Par

exemple, la syntaxe System.out.println(11.0/4) renverra 2.75, car le premier nombre est un double.

Trouver le reste

Un autre opérateur utile fournit le reste dans une division entière. Son symbole est le signe de pourcentage.

Si

vous

System.out.println(11

écrivez %

par

4),

exemple

l’ordinateur

affichera  3. Onze contient deux fois quatre, et il reste trois. Ah, cette bonne vieille école primaire ! Cet opérateur est aussi appelé modulo.

Cet opérateur peut rendre bien des services. Après tout, c’est ce qui reste une fois que vous avez divisé vos deux nombres. Vous étiez 25 à jouer au Loto et vous avez réalisé le gain mirifique de  138  €. Comment se répartissent les gains  ? La Figure  7.5 l’illustre graphiquement. Chacun touchera 5 €, et il restera 13 € à remettre au pot.

FIGURE

7.5

Ah, les jolis bâtons.

Le code du Listing 7.3  utilise cette notion de reste pour vous familiariser avec les unités monétaires utilisées aux États-Unis (cela pourrait vous servir un jour). LISTING

7.3 Jouer avec les dollars.

import java.util.Scanner; class MakeChange { public static void main(String args[]) { Scanner keyboard = new

Scanner(System.in); int quarters, dimes, nickels, cents; int whatsLeft, total; System.out.print("Combien de centimes avez-vous ? "); total = keyboard.nextInt(); quarters = total / 25; whatsLeft = total % 25; dimes = whatsLeft / 10; whatsLeft = whatsLeft % 10; nickels = whatsLeft / 5; whatsLeft = whatsLeft % 5; cents = whatsLeft; System.out.println(); System.out.println("Avec " + total + " centimes vous avez :"); System.out.println(quarters + " quarters"); System.out.println(dimes + " dimes"); System.out.println(nickels + " nickels"); System.out.println(cents + " cents");

keyboard.close(); } } La Figure  7.6  illustre une exécution de ce code. Vous

partez

ici

d’un

total

de  138

centimes.

L’instruction :

FIGURE 7.6

Convertir 138 centimes en unités US.

quarters = total / 25; divise  138  par  25, ce qui vous donne  5. Autrement dit, il y a 5 « quarters » dans 138 centimes. Ensuite, l’instruction whatsLeft = total % 25;

divise à nouveau 138 par 25, et place uniquement le reste de la division, 13, dans la variable whatsleft. Vous êtes maintenant prêt à passer à l’étape suivante qui consiste à trouver le nombre de « dimes » dans 13 centimes. Et ainsi de suite. À la fin, il ne reste plus que le nombre des centimes qui sont tous seuls dans leur coin, soit 3. Le code du Listing  7.3  décompose la monnaie américaine selon les unités suivantes  : 1  cent, 5 cents (un nickel), 10 cents (une dime) et 25 cents (un quarter). En fait, le programme MakeChange vous offre plus qu’un simple jeu de pièces de monnaie totalisant jusqu’à  138  cents. La classe MakeChange vous donne le plus petit nombre de pièces qui totalisent  138  cents. Avec quelques modifications mineures, vous devriez pouvoir faire fonctionner ce code dans le système monétaire de pratiquement n’importe quel pays. En revanche, pour les dénominations de pièces dans certains pays, vous n’obtiendrez pas toujours le plus petit nombre de pièces dont l’addition forme un certain total… Lorsque deux variables ou plus ont des types similaires, vous pouvez les créer en combinant les déclarations. Par exemple, sur le Listing  7.3, les

variables quarters, dimes, nickels et cents sont toutes déclarées comme étant de type int sur une même ligne. Par contre, si deux variables sont de type

différent,

elles

doivent

être

déclarées

indépendamment l’une de l’autre. Par exemple, pour créer une variable int appelée total, et une variable double appelée montant, vous avez besoin d’une déclaration int total ; et d’une seconde déclaration double montant ; . Le

Listing 

7.3 

fait

un

appel

à

System.out.println() sans rien indiquer entre les parenthèses. Lorsque l’ordinateur exécute cette instruction, le curseur passe à la ligne suivante sans rien afficher. Cela permet d’insérer des lignes vierges dans la sortie du programme.

ENTIER, QUI ES-TU, QUE FAIS-TU ! L’exécution illustrée sur la Figure  7.6  semble artificielle. Pourquoi partir de  138  centimes  ? Pourquoi ne pas utiliser quelque chose de plus familier, comme 1,38 dollar (puisqu’il s’agit d’unités monétaires américaines)  ? La raison est que  1,38  n’est pas un nombre entier, et que les nombres entiers sont plus précis que tous les autres. En fait, sans ces nombres entiers, l’opérateur modulo ne serait pas très utile. Par exemple, 1.38  % 25  donne à peu près ceci  : 0.1299999999999999. Tous ces chiffres neuf ne sont pas réellement commodes à manier. Imaginez que vous trouviez un tel nombre sur un relevé bancaire. Vous penseriez sans doute qu’il y a erreur de la banque ! Le Chapitre 8 décrit un peu plus en détail les problèmes de précision provoqués par les valeurs double. Les exemples qui s’appuient sur des calculs de monnaie sont courants. Mais, pour plus de précision, évitez dans ce cas d’employer des valeurs double. Servez-vous d’entiers int, ou encore du type long présenté dans la dernière partie de ce

chapitre.

Mieux

encore,

recherchez

dans

la

documentation de Java des informations sur les types BigInteger et BigDecimal. Ils sont lourds à manier, mais offrent une plage de valeurs ainsi qu’une précision remarquables.

Supposons maintenant que vous vouliez entrer 1,38, et que votre

programme

convertisse

lui-même

ce

montant

en 138 centimes. Comment faire ? Ma première idée, c’est de multiplier 1.38 par 100 : // Ceci ne marche pas. double amount; int total; amount=keyboard.nextDouble(); total=amount*100; Dans

l’arithmétique

de

tous

les

jours,

multiplier

par 100 suffit à obtenir le résultat. Mais les ordinateurs sont difficiles. Vous devez faire très attention lorsque vous mixez des valeurs int et double. Le code ci-dessus ne fonctionne pas et il provoque une erreur de type (Figure 7.A). Pour glisser une valeur double dans une variable int, vous avez besoin de quelque chose que les programmeurs appellent casting (ou projection, si vous voulez). Eclipse utilise le terme transtypage. C’est un peu comme dire  : «  Je sais que le but est difficile à atteindre, mais je vais essayer. » Pour réaliser cette prouesse, vous placez le nom d’un type entre parenthèses, comme ceci : // Ceci fonctionne ! total = (int) (amount * 100);

Ce code transforme la valeur double  1.38  en la valeur entière 138, et tout le monde est content (Figure 7.B).

FIGURE 7.A

FIGURE 7.B

Arithmétique Java

Quelle est la valeur de chacune des expressions suivantes  ? Tapez chaque expression sur une ligne séparée dans JShell pour savoir si vos réponses sont correctes : 10 / 3 10 % 3 3 / 10 3 % 10 8 * 3 + 4 4 + 8 * 3 8 * (3 + 4) 34 % 5 - 2 * 2 + 21 / 5

Valeurs variables Quelle est la valeur de chacune des variables suivantes (a, b, c, etc.)  ? Tapez chaque instruction sur une ligne distincte dans JShell pour savoir si vos réponses sont exactes :

int a = 8 int b = 3 int c = b / a int d = a / b int e = a % b int f = 5 + e * d - 2

Recherche plombier, désespérément Un plombier local demande  75  € pour venir chez moi. De plus, pour chaque heure où le plombier intervient

chez

supplémentaires.

moi, Rédigez

il

demande  un

125 

programme

€ qui

indique le nombre d’heures pendant lesquelles un plombier travaille chez moi, et le montant total de la facture.

Encore des modifications Modifiez le code du Listing  7.3  de sorte qu’il obtienne un nombre de dollars et un nombre de cents tapés au clavier. Par exemple, au lieu

d’entrer 

138 

(soit 

138 

cents),

l’utilisateur

saisit 1 38 (1 dollar et 38 cents).

Je suis grand comment ? D’où je viens, nous n’utilisons pas de mesures métriques. Nous mesurons plutôt la taille de chaque personne

en

pieds

et

en

pouces.

Un

pied

fait 12 pouces, et je mesure 5,5 pieds. (Ma taille en pieds

est

la

valeur

double

5,5.)

Écrire

un

programme pour trouver ma taille en pouces. (C’est-à-dire,

partant

de  5,5  pieds,

calculer

66 pouces.) Modifiez le programme pour qu’il demande à l’utilisateur sa taille en pieds et qu’il affiche ensuite cette taille en pouces. Modifiez le programme pour qu’il demande à l’utilisateur sa taille en pieds et en pouces. Par exemple, une personne qui mesure cinq pieds et demi tape le chiffre 5  (pour cinq pieds) suivi du chiffre  6  (pour six pouces supplémentaires). Le programme donne alors la taille de la personne en pouces. Un pouce correspond à 2,54 centimètres, et un pied à 12 fois plus, soit 30,48 cm.

Combien d’anniversaires de mariage ? Ma femme et moi, nous nous sommes mariés un  29  février. Nous avons donc un anniversaire de mariage tous les quatre ans… Écrire un programme avec une variable nommée ans. En fonction de la valeur de cette variable ans, le programme affiche notre nombre d’anniversaires de mariage. Par exemple, si la valeur de ans est 4, le programme va afficher la phrase : Nombre d’anniversaires : 1. Si la valeur de ans est  7, le programme affichera toujours comme nombre d’anniversaires 1. Mais si ans passe à  8, alors le programme doit afficher  : Nombre d’anniversaires : 2.

Incrémenter et décrémenter Java possède de petits opérateurs qui rendent la vie plus facile à tout le monde (les ordinateurs, votre cerveau et vos doigts en particulier). Je parle ici des deux opérateurs servant à incrémenter et des deux autres servant à décrémenter. Incrémenter, c’est ajouter une unité. Décrémenter, c’est l’inverse, donc

soustraire

comment exemples.

ils

une

unité.

fonctionnent,

Pour

comprendre

voyons

quelques

Utiliser le pré-incrément Le premier exemple est illustré sur la Figure 7.7.

FIGURE 7.7

Utiliser le pré-incrément.

L’exécution du programme de la Figure  7.7  est illustrée sur la Figure 7.8. Le nombre de boules de gomme y est affiché trois fois. Le double signe plus peut prendre deux noms différents selon l’endroit où il est placé. Si vous le mettez devant une variable, il est appelé un préincrément. Autrement dit, il agit avant. Plus précisément :

FIGURE 7.8

Le pré-incrément en action.

» Vous placez les signes ++ avant la variable. » L’ordinateur ajoute 1 à la valeur de la variable avant que celle-ci soit utilisée dans d’autres parties de l’instruction. La Figure  7.9  précise ces notions. L’ordinateur y rencontre

l’opérateur

de

pré-incrément

dans

l’instruction System.out.println(++gumballs). Il exécute ensuite l’instruction System.out.println en utilisant la nouvelle valeur de la variable (29).

FIGURE 7.9

L’opérateur de pré-incrément en action.

Utiliser le post-incrément Une autre alternative est le post-incrément. Post, c’est donc après. C’est-à-dire : » Vous placez les signes ++ après la variable. » L’ordinateur ajoute 1 à la valeur de la variable une fois que celle-ci a été utilisée dans d’autres parties de l’instruction. La Figure 7.10 illustre l’utilisation de l’opérateur de post-incrément rencontre

en

action.

l’instruction

Ici,

l’ordinateur

System.out.println

(gumballs++). Il exécute donc cette instruction avec l’ancienne valeur de gumballs

(28). Et il

ajoute ensuite  1 à la valeur de cette variable (soit 29).

FIGURE 7.10 Regardez

L’opérateur de post-incrément en action.

la

ligne

en

caractères

gras

sur

la

Figure  7.11. L’ordinateur affiche l’ancienne valeur de gumballs (28) à l’écran. Ce n’est qu’après que l’ordinateur ajoute 1  à la variable (dont la valeur passe donc de 28 à 29).

FIGURE 7.11

Utiliser l’opérateur de post-incrément.

Avec

System.out.println(gumballs++),

l’ordinateur ajoute 1  à la variable gumballs après avoir affiché l’ancienne valeur de cette variable.

FIGURE 7.12 Un

L’exécution du code de la Figure 7.11.

exemple

d’exécution

du

code

de

la

Figure 7.11 est montré sur la Figure 7.12. Comparezle avec la Figure 7.8. » Avec le pré-incrément de la Figure 7.8, le second nombre affiché est 29. » Avec le post-incrément de la Figure 7.12, le second nombre affiché est 28. Sur la Figure 7.12, la valeur 29 n’apparaît sur l’écran qu’à la fin de l’exécution, lorsque l’ordinateur exécute un dernier System.out.println(gumballs). Vous vous demandez ce qui est le meilleur  ? Préincrément ou post-incrément ? Ne réfléchissez pas

trop longtemps. La plupart des programmeurs utilisent uniquement le post-incrément. Dans un programme Java typique, vous voyez souvent des choses

comme

gumballs++.

Par

contre,

vous

rencontrerez rarement la forme ++gumballs. En plus des opérateurs de pré-incrément et de post-incrément, Java en propose deux autres qui font exactement l’inverse. On peut les appeler prédécrément et post-décrément : » Avec le pré-décrément (--gumballs), l’ordinateur soustrait 1 de la valeur de la variable avant que celle-ci soit utilisée dans le reste de l’instruction. » Avec le post-décrément (gumballs--), l’ordinateur soustrait 1 de la valeur de la variable après que celle-ci a été utilisée dans le reste de l’instruction.

Explorer les opérateurs de pré-incrément et de post-incrément avec JShell Tapez le texte en gras, une ligne après l’autre, dans la fenêtre de JShell pour voir comment celui-ci répond : jshell> int i = 8

jshell> i++ jshell> i jshell> i jshell> i++ jshell> i jshell> ++i jshell> i

Explorer les opérateurs de pré-incrément et de post-incrément dans un programme Java Avant d’exécuter le code qui suit, essayez de prédire quelle sera la sortie produite. Exécutez ensuite le code pour savoir si votre prédiction est correcte : public class Main { public static void main(String[] args) { int i = 10; System.out.println(i++); System.out.println(--i); --i;

i--; System.out.println(i); System.out.println(++i); System.out.println(i--); System.out.println(i); } }

INSTRUCTIONS ET EXPRESSIONS Toute partie d’un programme informatique qui a une valeur est appelée une expression. Si vous écrivez gumballs = 30; alors 30 est une expression (une expression dont la valeur est la quantité 30). Si vous écrivez amount = 5.95 + 25.00; alors 5.95 + 25.00 est une expression (car 5.95 + 25.00 a la valeur 30.95). Et si vous écrivez gumballsPerKid = gumballs / kids; alors gumballs

/

kids

est une expression. Celle-ci

dépend évidemment des valeurs des variables gumballs et kids au moment où cette instruction est exécutée. Ceci nous renvoie aux variantes pré et post des opérateurs d’incrément et de décrément. Il y a deux manières de les considérer  : celle qui correspond au sens commun, et la bonne. L’explication que je donne dans ce qui précède, c’està-dire en employant les mots avant et après, relève de la première version. Pourtant, ce n’est pas la bonne explication. Lorsque vous voyez les caractères ++ ou  --, vous pouvez y

penser en termes de temps (avant ou après). Mais cette vérité apparente n’en est pas une. La bonne façon de s’y prendre, c’est de raisonner en termes d’instructions et d’expressions. Tout d’abord, souvenez-vous qu’une instruction demande à l’ordinateur de faire quelque chose, et qu’une expression possède une valeur (les instructions sont décrites dans le Chapitre 4 et les expressions un peu plus haut). Demandezvous alors à quelle catégorie appartient gumballs++. La réponse surprenante est  : aux deux. Oui, le code Java gumballs++ est à la fois une instruction et une expression. Supposons

que,

avant

d’exécuter

le

code

System.

out.println(gumballs++), la valeur de gumballs soit égale à 28 : » En tant qu’instruction, gumballs++

demande à

l’ordinateur d’ajouter 1 à gumballs. » En tant qu’expression, la valeur de gumballs++ est 28, pas 29. Ainsi, même si gumballs

se voir ajouter  1, le code

System.out.println(gumballs++)

signifie en réalité

System.out.println(28)

la

(voir

figure

qui

suit). Maintenant, tout ce que vous pouvez lire sur gumballs++ vaut également pour ++gumballs. La seule différence est

que, en tant qu’expression, ++gumballs se comporte d’une manière un peu plus intuitive. Supposons que la valeur de gumballs soit de 28 juste avant d’exécuter System.out.println(++-gumballs) : » En tant qu’instruction, ++gumballs

demande à

l’ordinateur d’ajouter 1 à gumballs. » En tant qu’expression, la valeur de ++gumballs est 29. Le code System.out.println(++gumballs) signifie donc en réalité ici System.out.println(29).

FIGURE 7.C

Opérateurs d’affectation Si vous avez lu ce qui précède (la section qui traite des opérateurs qui ajoutent 1), vous vous demandez sans doute comment manipuler ces opérateurs pour ajouter par exemple  2, 5  ou  100000. Pouvez-vous par exemple écrire gumballs++++ et continuer à dire que vous êtes un programmeur Java ? Eh bien, si vous essayez ce genre de chose, Eclipse vous renverra un message d’erreur vous indiquant : Argument non valide pour une opération « ++ » ou « -- » Si vous n’utilisez pas Eclipse, le message d’erreur sera un peu différent. Par exemple, JShell vous répondra : | | | | | |

Error: unexpected type required: variable found: value gumballs++++ ^--------^

Dans tous les cas, le problème est le même  : votre code contient une erreur, et vous devez la corriger.

Donc, est-il possible d’ajouter des valeurs autres que 1 et comment ? Comme vous avez de la chance, Java

met

effectivement

des

tas

d’opérateurs

d’affectation à votre disposition. Ces opérateurs vous permettent d’ajouter, soustraire, multiplier ou diviser ce que vous voulez. Et vous pouvez aussi faire d’autres opérations. Par exemple, vous pouvez ajouter  1  à une variable en écrivant : pommes += 1 ; C’est mieux que pommes++, ou pommes = pommes + 1, non ? Eh bien non. C’est juste une alternative. Si vous cueillez cinq pommes, votre panier pourra s’écrire ainsi : pommes += 5 ; Il n’est pas facile d’ajouter  5  en utilisant des préincréments ou des post-incréments. Et si vous avez trouvé le moyen de cloner vos pommes, le résultat s’écrira : pommes *= 2 ;

Les opérateurs d’affectation vous permettent de réaliser n’importe quelle opération arithmétique. Le nombre n’est pas nécessairement un littéral. Vous pouvez parfaitement vous servir d’une valeur quelconque (en respectant la cohérence des types) dans la partie droite de l’instruction : double montant = 25.95; double port = 5.00, remise = 1.5; montant += port; montant -= remise * 2; Ce code ajoute 5,00 (le frais de port) à la valeur de montant. Puis il soustrait  3.00 (remise * 2) de cette valeur. Quelle générosité ! Si le mot littéral ne vous évoque rien, revoyez à ce sujet le Chapitre 4.

Expérimenter avec les opérateurs d’affectation Avant d’exécuter le code qui suit, essayez de prédire quelle en sera la sortie. Exécutez ensuite le code pour savoir si votre prédiction est correcte : public class Main { public static void main(String[] args)

{ int i = 10; i += 2; i -= 5; i *= 6; System.out.println(i); System.out.println(i += 3); System.out.println(i /= 2); } }

Des changements, encore et toujours ! En plus des opérateurs d’affectation que je décris plus

haut,

Java

L’opérateur  %=

a fait

aussi

un

opérateur  %=.

pour

les

restes

ce

que

l’opérateur += fait pour l’addition. Modifiez le code du Listing 7.3 de façon à ce qu’il utilise l’opérateur d’affectation %= chaque fois que c’est possible.

Une affaire de taille Regardons les trois mots qui suivent  : carton, néfaste et tonne. Rien d’extraordinaire là-dedans.

Imaginons maintenant que vous vous retrouviez devant un texte compressé, c’est-à-dire dont tous les espaces ont été enlevés. Vous voyez la séquence de lettres suivante : cartonnefaste Comment l’interpréter (en laissant de côté cette ridicule histoire d’accent)  : carton nefaste, car tonne faste, carton ne faste ou encore, car ton nefaste ? Pour répondre à cette question, vous devez savoir quelle est la longueur de chaque mot à récupérer. Un ordinateur doit faire face à ce même type de problème. Lorsqu’il enregistre plusieurs nombres en mémoire ou sur un disque, il n’ajoute pas des espaces entre eux. Supposons qu’un minuscule morceau de la mémoire de l’ordinateur ressemble à l’illustration de la Figure  7.13  (oui, l’ordinateur travaille uniquement avec des zéros et des un, mais c’est juste pour faciliter la démonstration).

FIGURE 7.13

Enregistrement de la valeur 4221.

En fait, quel est le nombre qui est enregistré sur la Figure  7.13  ? Est-ce qu’il y a deux nombres, 42  et  21  ? Quatre chiffres, 4, 2, 2  et  1  ? Un seul nombre, 4221 ? Tout dépend de l’espace consommé par chaque valeur. Imaginez une variable qui mémorise le nombre de jours ouvrés dans un mois. Évidemment, ce nombre ne sera jamais plus grand que 31 (enfin, nettement moins, je l’espère pour vous). Huit zéros et un suffisent amplement à le représenter. Mais songez maintenant à une variable qui devrait compter le nombre d’étoiles dans l’univers. Il y en a très certainement des milliards de milliards, et pour représenter un tel nombre, vous avez besoin, disons, de  64  zéros et un (j’ai un peu arrondi tout cela pour faire simple). C’est alors que Java vient à la rescousse. Il a en effet quatre

types

de

nombres

entiers.

Dans

le

Listing  7.1, par exemple, j’ai écrit la déclaration suivante : int gumballsPerKid ; Mais je pourrais aussi déclarer :

byte joursOuvresDansUnMois ; ; short joursMaladieDansVotreCarriere; long nombreDEtoiles; Chacun de ces types (byte, short, int et long) possède sa propre plage de valeurs (voir

le

Tableau 7.1). 7.1

TABLEAU

Les types numériques primitifs de Java.

Nom du

Plage de valeurs

type Entiers

 

byte

–128 à 127

short

–32768 à 32767

int

–2147483648 to 2147483647

long

–9223372036854775808 à 9223372036854775807

Décimaux

 

float

–3.4×1038 à 3.4×1038

double

–1.8×10308 à 1.8×10308

Java

possède

deux

types

décimaux. Par exemple :

pour

les

nombres

double montant ; float monSalaire ; Même si j’ai le choix entre float et double, j’opte toujours pour double, car il offre une plus grande plage de valeurs et il est plus précis. Le Tableau  7.1  liste six types dits primitifs de Java (on dit aussi des types simples). En tout, Java contient huit types primitifs. Six sont donnés dans le tableau. Les deux autres seront étudiés dans le Chapitre 8. Le Chapitre 17  aborde des types qui ne sont pas primitifs. En tant que programmeur débutant, vous n’avez pas à vous poser des questions existentielles sur tous ces types. Utilisez simplement int pour des nombres entiers et double

pour des nombres

décimaux.

de

Si,

au

cours

vos

voyages

informatiques, vous rencontrez des mots comme short ou float dans un programme écrit par quelqu’un d’autre, souvenez-vous simplement de ceci : » Les types byte, short, int et long représentent des nombres entiers. » Les types float et double représentent des nombres décimaux.

La plupart du temps, c’est tout ce que vous avez besoin de savoir.

Chapitre 8

Des nombres ? Qui a besoin de nombres ? DANS CE CHAPITRE : » Travailler avec des caractères » Vrai ou faux ? » Java et ses types primitifs

n’aime pas particulièrement les fax. Ils sont si J einefficaces. Envoyez un fax court, et vous avez au final deux branches d’arbre en moins, une du côté qui envoie, et une autre du côté qui reçoit. Vous avez aussi des millions de points qui dessinent les mots sur la page imprimée, juste pour faire la différence entre le blanc et le noir. Quel gâchis ! Comparez un fax et un e-mail. Avec un e-mail, vous pouvez envoyer vos trente mots juste avec quelques petits milliers de zéros et de un, et aucune feuille de papier n’est consommée. Mieux encore,

votre e-mail ne décrit pas des points noirs et des zones blanches. Il contient des codes pour chacune des lettres (une suite de quelques zéros et une pour la lettre A, une séquence légèrement différente pour la lettre B, et ainsi de suite). Quoi de plus simple ? Imaginons maintenant la situation suivante : votre éditeur vous propose d’écrire un livre sur la programmation en Java pour les débutants. Vous répondez «  Oui  » par fax. Résultat  : deux feuilles de papier et du toner consommé pour juste trois lettres. Mais si vous pensez en termes d’ordinateur, il suffit de se mettre d’accord avec l’éditeur : 1 c’est « oui » , 0 c’est « non » . Question  : «  Voulez-vous écrire un livre sur la programmation en Java pour les débutants ? » Réponse : 1 Génial ! Quoi qu’il en soit, ce chapitre est consacré aux lettres, au vrai, au faux et à d’autres choses encore.

Il faut avoir des caractères Dans les Chapitres 6  et 7, vous avez enregistré des nombres dans toutes vos variables. C’est très bien.

Mais il n’y a pas que les nombres dans la vie. Par exemple, ce livre est écrit avec un ordinateur, et il contient des milliers et des milliers de signes non numériques que l’on appelle des caractères. Le type Java qui est utilisé pour stocker des caractères est char (pour character en anglais). Le Listing  8.1  propose un programme simple qui utilise le type char. Son exécution est illustrée sur la Figure 8.1. LISTING

8.1 Utiliser le type char.

class LowerToUpper { public static void main(String args[]) { char smallLetter, bigLetter; smallLetter = 'b'; bigLetter = Character.toUpperCase(smallLetter); System.out.println(bigLetter); } } Ici, la première affectation enregistre la lettre minuscule b dans la variable smallLetter. Dans cette instruction, remarquez que la lettre b est

délimitée par des apostrophes simples. Dans un programme Java, chaque littéral char commence et se termine par une apostrophe.

FIGURE 8.1 Lorsque

Excitant, n’est-ce pas ?

vous

entourez

une

lettre

par

des

apostrophes, vous indiquez à l’ordinateur qu’il ne s’agit pas d’un nom de variable. Si vous écriviez l’instruction

du

Listing  8.1  sous

la

forme

smallLetter = b, l’ordinateur rechercherait une variable appelée b, qu’il ne trouverait évidemment pas. Ce qui se traduirait par un désagréable message d’erreur. Dans l’instruction qui suit, le programme appelle une

méthode

de

l’API

dont

le

nom

est

Character.toUpperCase. Cette méthode convertit la lettre en majuscule (donc en un B). L’instruction affecte le résultat à la variable bigLetter, qui est finalement affichée à l’écran (voir l’illustration de la Figure 8.2).

FIGURE 8.2

Le Listing 8.1 en action.

Lorsque l’ordinateur affiche une valeur char à l’écran, il n’encadre pas le caractère avec des apostrophes.

Un peu de digression… Il y a quelque temps de cela, je me suis demandé ce qui

se

passerait

si

j’appelais

la

méthode

Character.toUpperCase avec un caractère qui ne soit pas une minuscule. J’ai pioché dans la documentation Java, mais je n’y ai pas trouvé d’information utile.

Aussi bête que cela paraisse, je me suis demandé ce que je ferais si j’étais la méthode toUpperCase. Quelqu’un me demande, à moi la méthode, de convertir

en

majuscule

la

lettre

R.

Vraisemblablement, je lui enverrais une lettre d’insultes

bien

senties.

Dans

le

jargon

de

l’ordinateur, cela s’appelle un message d’erreur. Bien. Donc, j’ai essayé. D’où le programme proposé sur le Listing 8.2. LISTING

8.2 Explorer le comportement de

toUpperCase. class MyExperiment { public static void main(String args[]) { char smallLetter, bigLetter; smallLetter = 'R'; bigLetter = Character.toUpperCase(smallLetter); System.out.println(bigLetter); smallLetter = '3'; bigLetter = Character.toUpperCase(smallLetter); System.out.println(bigLetter);

} } Dans cette expérience, je n’ai pas mélangé des produits

chimiques

pour

faire

exploser

le

laboratoire. J’ai juste fait ceci : » J’ai affecté 'R' à la variable smallLetter. La méthode a accepté mon affectation et affiché le même R majuscule (voir la Figure 8.3). Aucun message d’erreur. Donc, dans ce cas, la méthode ne fait strictement rien. » J’ai affecté '3' à la variable smallLetter. La méthode a accepté mon affectation et affiché le chiffre 3 (voir la Figure 8.3). Aucun message d’erreur. Donc, dans ce cas aussi, la méthode ne fait strictement rien.

FIGURE

8.3

Exécution du code du Listing 8.2.

J’ai réalisé cette petite expérience pour mettre en lumière un point important. Lorsque vous ne comprenez pas quelque chose dans une affaire de programmation, il est souvent utile d’écrire un programme de test pour comprendre ce qui se passe. Faites vous-même l’expérience, et voyez la manière dont l’ordinateur répond. J’avais supposé que le fait d’envoyer une lettre majuscule à la méthode toUpperCase provoquerait un

message

réponses

aux

d’erreur.

Mais

questions

ne

j’avais

tort.

Les

descendent

pas

directement du ciel. Les types qui ont créé l’API Java ont pris des décisions. Certains de leurs choix sont évidents, et d’autres le sont beaucoup moins. Personne ne sait tout sur les fonctionnalités de

Java. N’espérez pas pouvoir stocker toutes les réponses dans votre tête, aussi bien faite soit-elle. La documentation de Java est monumentale, mais pour chaque réponse qu’elle apporte, elle ignore trois autres questions. N’ayez pas peur de bricoler au milieu de tout cela. Écrivez des tas de petits programmes pour faire vos propres expériences. Vous n’allez pas détruire votre ordinateur pour autant  ! Avoir un esprit curieux et inquisiteur finit toujours par payer. Lire et comprendre la documentation de l’API Java est un art, pas une science.

Un caractère à la fois, s’il vous plaît Une variable char ne contient qu’un seul caractère. Ne tentez pas par exemple d’écrire : char smallLetters; smallLetters = 'barry'; cela

//Ne faites pas

Résistez à la tentation. Vous ne pouvez pas mettre plus d’une lettre à la fois dans une variable char, pas plus que dans des apostrophes simples. Si vous

voulez écrire un mot ou une phrase, vous devez utiliser un autre type appelé String. Ce type de variable est étudié dans le Chapitre 18.

Variables et recyclage Sur le Listing  8.2, j’utilise deux fois smallLetter et bigLetter. C’est pourquoi ils appellent ces choses des variables. La valeur de smallLetter est d’abord R. Plus loin, je fais varier sa valeur qui devient 3. Lorsque

j’affecte

smallLetter,

une

l’ancienne

nouvelle est

Figure 8.4 illustre ce mécanisme.

FIGURE 8.4

Variation de valeur.

valeur perdue.

à La

Est-ce que c’est correct  ? Pouvez-vous vous permettre

d’oublier

la

valeur

que

contenait

smallLetter auparavant  ? Oui, sur le Listing  8.2, cela ne pose aucun problème. Une fois que vous avez affecté la valeur voulue à bigLetter dans l’instruction : bigLetter = Character.toUpperCase(smallLetter); vous

pouvez

oublier

tout

ce

qui

concernait

smallLetter. Vous n’avez pas besoin de faire ceci : // Ce code est trop lourd. // Les variables supplémentaires sont inutiles. char smallLetter1, bigLetter1; char smallLetter2, bigLetter2; smallLetter1 = 'R'; bigLetter1 = Character.toUpperCase(smallLetter1); System.out.println(bigLetter1); smallLetter2 = '3'; bigLetter2 = Character.toUpperCase(smallLetter2); System.out.println(bigLetter2);

Il est inutile de mémoriser l’ancienne et la nouvelle valeur dans des variables séparées. Il suffit de réutiliser les variables smallLetter et bigLetter comme sur le Listing 8.2. Cette réutilisation des variables ne vous fait pas gagner du temps de saisie. Et cela ne fait pas non plus une différence sensible en mémoire. Par contre, réutiliser des variables dans un programme lui fait gagner de la lisibilité. Si vous regardez le Listing 8.2, vous comprenez d’un coup d’œil que ce code comporte deux parties, et que ces deux parties font sensiblement la même chose. Le code du Listing  8.2  est simple et facilement gérable. Ici, cela n’a pas grande importance. Par contre,

dans

un

gros

programme,

réfléchir

soigneusement à une utilisation judicieuse de chaque variable est très important.

Quand faut-il ne pas réutiliser une variable ? Dans la section précédente, je vous ai expliqué pourquoi la réutilisation des variables permet de rendre un programme plus fluide et plus facile à lire.

Mais,

comme

toujours,

cette

assertion

comporte une autre face. Ici, le problème posé va vous forcer à créer de nouvelles variables. Supposons que vous écriviez un programme qui inverse un mot de quatre lettres. Chaque lettre est enregistrée dans sa propre variable. Le code correspondant est montré sur le Listing  8.3, et le résultat correspondant est illustré sur la Figure 8.5. LISTING

8.3 Mettre un mot à l’envers.

import java.util.Scanner; class ReverseWord { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); char c1, c2, c3, c4; c1 = keyboard.findWithinHorizon(".", 0).charAt(0); c2 = keyboard.findWithinHorizon(".", 0).charAt(0); c3 = keyboard.findWithinHorizon(".", 0).charAt(0); c4 = keyboard.findWithinHorizon(".", 0).charAt(0);

System.out.print(c4); System.out.print(c3); System.out.print(c2); System.out.print(c1); System.out.println(); keyboard.close(); } } Toute l’astuce réside dans ceci : » Des valeurs sont affectées aux variables c1, c2, c3 et c4 dans cet ordre. » Ces valeurs sont affichées dans le sens inverse (c4, c3, c2 puis c1). C’est ce qu’illustre la Figure 8.6.

FIGURE 8.5

Stoppez ces pots !

Si

vous

n’utilisez

pas

quatre

variables,

vous

n’obtiendrez pas le résultat escompté. Imaginons que vous ne définissiez qu’une seule variable. Vous lancez le programme, et vous tapez le mot pots. Au moment d’afficher la réponse, l’ordinateur n’aura retenu que la dernière lettre, le s. Les trois autres seront oubliées, comme l’illustre la Figure 8.7.

FIGURE 8.6

Utiliser quatre variables.

J’aimerais bien pouvoir vous donner une douzaine de règles pour vous aider à décider quand réutiliser et quand ne pas réutiliser des variables. Mais ce n’est pas possible. Tout dépend de ce que vous essayez de faire. Alors, comment vous décidez  ? Il

n’y a qu’une seule réponse  : la pratique, encore la pratique, toujours la pratique !

FIGURE 8.7

Une seule variable, et votre mot est perdu.

Lire des caractères Les types qui ont créé la classe Scanner n’ont pas défini de méthode next pour lire un seul caractère. Pour résoudre ce problème, j’ai donc accolé deux méthodes : findWithinHorizon et charAt.

Le Tableau  5.1  du Chapitre  5  introduit cette technique pour lire une saisie qui ne comporte qu’un caractère, et le Listing  8.3  y fait appel (à quatre reprises) pour lire un seul caractère à la fois. Remarquez le format de la saisie sur la Figure 8.5. Pour entrer les caractères du mot pots, j’ai tapé quatre lettres, l’une après l’autre, sans espace entre elles

et

sans

apostrophes.

findWithinHorizon(".",

La

technique

0).charAt(0)

fonctionne de cette manière, et je n’en suis ni coupable ni responsable. D’autres méthodes de lecture

de

caractères

utilisées

par

certains

programmeurs se comportent aussi de cette façon. Quelle que soit la technique employée, la lecture des caractères diffère de celle des nombres. En effet : » Avec des méthodes comme nextDouble et nextInt, vous tapez des espaces entre les nombres. Si je tape 80 6, alors deux appels à nextInt me renvoient 80, puis 6. Si je tape 806, alors la valeur 806 sera lue dès le premier appel à nextInt. C’est ce qu’illustre la Figure 8.8.

FIGURE 8.8

Lire des nombres et des caractères.

» Avec la méthode findWithinHorizon(".", 0).charAt(0), vous ne tapez pas d’espace entre les caractères. Si je tape po, alors deux appels successifs à findWithinHorizon(".", 0).charAt(0) me renvoient la lettre p, puis la lettre o. Si je tape p o, alors ces mêmes appels me retourneront la lettre p suivie d’une espace (oui, l’espace est aussi un caractère !). C’est ce qu’illustre également la Figure 8.8. Pour représenter un caractère unique dans le corps d’un

programme,

vous

le

placez

entre

des

apostrophes. Par contre, si vous tapez un caractère en réponse à un programme, vous ne saisissez pas ces apostrophes. Supposons que votre programme appelle nextInt puis findWithinHorizon(".", 0).charAt(0). Si vous tapez  80x au clavier, vous provoquerez une erreur de type InputMismatchException (puisque la méthode nextInt attend un nombre suivi d’un espacement). Si, au lieu de cela, vous tapez au clavier  80  x, le programme va bien récupérer la valeur numérique  80, suivie d’une espace pour le caractère qui suit. Pour que le programme lise la lettre

x,

il

findWithinHorizon(".",

faudrait 0).charAt(0)

appeler une

seconde fois. Cela semble superfétatoire, mais cela prend tout son sens au fil du temps.

CE QUI SE CACHE DERRIÈRE CETTE CHOSE ÉTRANGE, FINDWITHINHORIZON Sans entrer dans des détails trop techniques, voyons comment fonctionne la technique findWithinHorizon ( « . » , 0).charAt(0). La méthode findWithinHorizon

de Java recherche

quelque chose en regardant vers un certain horizon, en l’occurrence ce qui est saisi au clavier. Ce quelque chose dépend de ce que vous mettez entre les parenthèses. Par exemple, un appel à findWithinHorizon( « \\d\\d\\d » , 0) rechercherait un groupe formé de trois chiffres. Prenons la ligne de code suivante : System.out.println(keyboard.findWit hinHorizon(«\\d\\d\\d», 0)); Si je tape : Test 123 Test l’ordinateur répondra en affichant 123. Dans cet appel, chaque \\d correspond à un chiffre unique. Il s’agit de l’une des multiples abréviations d’un code spécial appelé expressions régulières.

Voici maintenant quelque chose d’étrange. Dans le monde des expressions régulières, un point remplace un caractère quelconque

(donc

pas

findWithinHorizon(

forcément

«

.

»

,

un 0)

point).

Ainsi,

demande

à

l’ordinateur de retrouver le prochain caractère, quel qu’il soit, tapé par l’utilisateur sur le clavier. C’est donc une syntaxe extrêmement utile si vous avez besoin de récupérer un caractère unique. Dans l’appel findWithinHorizon( « \\d\\d\\d » , 0), le chiffre 0 à la fin demande à la méthode de poursuivre ses recherches jusqu’à la fin de la saisie. Toute autre valeur limiterait l’opération à un certain nombre de caractères. C’est d’ailleurs pourquoi le nom de la méthode contient le mot horizon. Cet horizon signifie aussi loin que la méthode peut voir. Prenons quelques exemples : » Avec comme saisie Test 123 Test Test, l’appel findWithinHorizon(

«

\\d\\d\\d

»

,

6)

retourne null. En effet, les six premiers caractères de la saisie sont Test 1 (quatre lettres, une espace et un chiffre). Il n’y a donc pas trois chiffres successifs comme le demande le motif \\d\\d\\d. » Toujours

avec

la

findWithinHorizon(

même «

saisie,

\\d\\d\\d

»

l’appel ,

7)

renverrait également null. C’est presque le même motif (Test 12), mais la même punition.

» Gardons

la

même

findWithinHorizon(

saisie. «

Cette

fois,

\\d\\d\\d

»

l’appel ,

8)

retournera  123, car les huit premiers caractères de la saisie (Test

123) contiennent bien trois chiffres

successifs. » Varions un peu le plaisir. Supposons que la saisie au clavier

soit

A57B442123

L’appel

Test.

findWithinHorizon( « \\d\\d\\d » , 12) va donner

comme

réponse  442.

Pourquoi  ?

Tout

simplement parce que la première séquence de trois chiffres consécutifs dans les douze premiers caractères de la saisie est effectivement 442. Attendez un peu  ! Pour obtenir un unique caractère au clavier, j’ai appelé findWithinHorizon(

«

.

»

,

0).charAt(0). Quel est donc le rôle de ce charAt(0) dans la lecture d’un unique caractère  ? Malheureusement, findWithinHorizon se comporte comme si elle allait trouver une masse de caractères, et pas un caractère unique. Si vous appelez findWithinHorizon( « . » , 0) et que l’ordinateur ne reçoit qu’un seul caractère du clavier, le programme Java traitera celui-ci comme un des éléments possibles d’une longue saisie. L’appel à charAt(0) permet de contourner ce problème. Il demande à Java de ne traiter que le caractère initial dans ce

qui est récupéré par findWithinHorizon. Oui, c’est compliqué. Eh oui, je n’aime pas à avoir à l’expliquer. Mais non, vous n’avez pas à comprendre tous ces détails. Contentez-vous de les lire et oubliez ce dont vous n’avez pas besoin.

Qu’y-a-t-il dans un nom ? En plus de sa méthode Character.toUpperCase. Java a une méthode Character.toLowerCase. Dans cet esprit, écrivez un programme qui lit un mot de quatre lettres et qui l’écrit en mettant son initiale en

majuscule

lorsqu’il

s’agit

d’un

nom

de

personne. Par exemple, si le programme lit les lettres anne, il affiche Anne. Si le programme lit LiAm, il affiche Liam.

Arranger des lettres Rédigez un programme qui lit trois lettres sur le clavier et édite tous les arrangements possibles de ces trois lettres. Par exemple, si le programme lit les lettres : nez il affichera :

nez nze enz ezn zne zen

Le type booléen Je suis bien embêté. J’ai  140  boules de gomme et  15  gamins qui courent dans tous les sens dans mon salon en poussant de grands cris. Ils crient parce que chacun d’eux veut dix boules de gomme, et ils courent parce que c’est ce que font les enfants dans un salon. J’ai besoin d’un programme qui me dise si je peux donner leurs dix boules de gomme aux chenapans. Pour cela, j’ai besoin d’une variable de type booléen. Une telle variable ne peut contenir que l’une des deux valeurs suivantes : true ou false. True, c’est vrai, et donc je peux donner dix boules de gomme à chaque garnement. False, c’est faux, et je suis en très mauvaise posture. De toute manière, les enfants sont de plus en plus énervés, et j’ai donc écrit un petit programme pour me sortir de là. Ce

programme est exposé dans le Listing  8.4, et la sortie correspondante apparaît sur la Figure 8.9. LISTING

8.4 Utiliser le type booléen.

class CanIKeepKidsQuiet { public static void main(String args[]) { int gumballs; int kids; int gumballsPerKid; boolean eachKidGetsTen; gumballs = 140; kids = 15; gumballsPerKid = gumballs / kids; System.out.print("Vrai ou faux ?"); System.out.println("Chaque enfant reçoit 10 boules de gomme."); eachKidGetsTen = gumballsPerKid >= 10; System.out.println(eachKidGetsTen); } }

FIGURE

8.9

Oh, non !

Sur le Listing 8.4, la variable eachKidGetsTen est de type booléen (boolean). La valeur qui y est stockée ne peut être que de type vrai (true) ou faux (false). Elle ne peut donc contenir ni nombre ni caractère. Pour déterminer la valeur de eachKidGetsTen, le programme

regarde

si

gumballsPerKid

est

supérieur ou égal à  10  (via le symbole >=). Quelle pitié ! Il n’y a pas de touche spéciale pour cela sur le clavier des ordinateurs ! Comme gumballsPerKid vaut seulement environ neuf, la comparaison gumballsPerKid >= 10 est fausse. Et donc, la variable eachKidGetsTen va renvoyer false. Au secours, ils vont tout casser dans la maison  ! Le temps qu’ils terminent leur carnage, regardez l’illustration de la Figure 8.10.

FIGURE 8.10

Affecter une valeur à la variable eachKidGetsTen.

Expressions et conditions Sur le Listing 8.4, le code gumballsPerKid >= 10 est une expression. La valeur de cette expression dépend de celle qui est enregistrée dans la variable gumballsPerKid. Comme il s’agit d’une mauvaise journée, la valeur de gumballsPerKid >= 10 est false. La variable eachKidGetsTen se voit donc affecter la valeur false. Une expression comme gumballsPerKid >= 10, dont la valeur ne peut être que true ou false, est parfois appelée une condition.

Des valeurs comme true ou false peuvent donner l’impression qu’il s’agit de caractères, mais ce n’est pas le cas. En interne, la machine virtuelle Java n’enregistre pas les lettre t-ru-e ou f-a-l-s-e, mais des codes comme  1  pour true/vrai et  0  pour false/faux.

Et,

à

la

suite

de

l’instruction

System.out.println(eachKidGetsTen)),

la

machine virtuelle Java convertit  1  en true et  0  en false.

Comparer des nombres et comparer des caractères Sur le Listing  8.4, je compare la valeur d’une variable avec le nombre 10. Pour cela, j’utilise dans l’expression l’opérateur >= : gumballsPerKid >= 10 Bien entendu, il ne s’agit que de l’une des multiples possibilités offertes par Java. Le Tableau  8.1  vous montre les opérateurs que vous pouvez utiliser pour comparer des choses les unes avec les autres. TABLEAU

8.1

Opérateurs de comparaison.

Operateur Signification

Exemple

==

est égal à

monPari == nombreGagnant

!=

n’est pas égal à 5 != nombreDeVaches




est plus grand

nombreDeVaches > 1000

que =

est plus petit

nombreDeVaches +

ou égal à

nombreDeTaureaux = 10

ou égal à Avec les opérateurs du Tableau  8.1, vous pouvez comparer

aussi

bien

des

nombres

que

des

caractères. Remarquez le double signe égal au début du Tableau  8.1. N’essayez pas d’utiliser un seul signe égal pour effectuer des comparaisons. L’expression monPari = nombreGagnant (avec un seul signe égal) ne compare pas les deux variables monPari et nombreGagnant,

mais

affecte

la

valeur

de

nombreGagnant à monPari. Vous pouvez comparer d’autres choses (en plus des nombres et des caractères) avec les opérateurs ==

et ! =. Mais vous devez pour cela faire preuve de beaucoup de précautions. Pour plus d’informations à ce sujet, voyez le Chapitre 18.

Comparer des nombres Rien n’est plus monotone que comparer des nombres. «  Vrai ou faux  ? Cinq est-il plus grand que

dix  ?  »

Faux,

évidemment.

C’est

très

ennuyeux, non ? Comparer des nombres entiers relève de l’évidence. Par contre, comparer des nombres décimaux est plus délicat. Prenons le cas d’un programme qui convertit des degrés Celsius en degrés Fahrenheit. Un exemple de réponse est proposé à ce problème. LISTING

8.5 Souffler le chaud et le froid.

import java.util.Scanner; class CelsiusToFahrenheit { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); double celsius, fahrenheit;

System.out.print("Entrez la température Celsius : "); celsius = keyboard.nextDouble(); fahrenheit = 9.0 / 5.0 * celsius + 32.0; System.out.print("Température de la pièce ? "); System.out.println(fahrenheit == 69.8); keyboard.close(); } } Si vous saisissez le code du Listing 8.5  et que vous entrez la valeur 21, l’ordinateur va trouver la valeur de  9.0 / 5.0 * 21 + 32.0. Croyez-le ou non, mais vous voulez vérifier sa réponse. Qui sait, il s’est peut-être trompé  ? Vous avez besoin de faire un peu d’arithmétique, mais ne sortez pas votre calculatrice. Après tout, ce n’est jamais qu’une sorte de petit ordinateur. Vous allez donc devoir faire un peu de calcul à la main. Quoi  ? Vous êtes allergique  ? Bon. Je vous donne la réponse sur la Figure 8.11.

FIGURE 8.11

La température Fahrenheit est exactement égale à 69,8.

En procédant ainsi, la valeur que vous obtenez pour  9.0 de 

69,8.

/

5.0 Lancez

*

21

+32.0

est exactement

maintenant

le

code

du

Listing  8.5  et entrez  21  comme nombre de degrés Celsius. Vous devriez obtenir une réponse true comme valeur de fahrenheit == 69.8. Correct ? Eh bien non. Regardez le résultat de l’exécution illustré sur la Figure  8.12. Lorsque l’ordinateur évalue

fahrenheit

==

69.8,

la

valeur

qu’il

retourne est false, et non pas true. Pourquoi ?

FIGURE 8.12

Le code du Listing 8.5 en action.

Les séparateurs de groupes varient d’un pays à l’autre. L’illustration de la Figure  8.12  fonctionne presque

partout

dans

le

monde.

Mais

si

la

température en degrés Celsius est de vingt et un degrés et demi, vous tapez  21.5  (avec un point) dans certains pays et  21,5  (avec une virgule) dans d’autres. Le matériel de votre ordinateur n’a pas d’indicateur de pays intégré, mais lorsque vous installez le système d’exploitation de l’ordinateur, vous lui dites dans quel pays vous vivez. Les programmes Java accèdent à ces informations et les utilisent pour personnaliser le fonctionnement de la méthode nextDouble. Un petit travail de détective s’impose. Reprenons les faits : » Fait : La valeur de fahrenheit devrait être exactement de 69,8 (ou plutôt 69.8 dans le jargon de l’ordinateur).

» Fait : Si fahrenheit est égal à 69.8, alors fahrenheit == 69.8 est vrai. » Fait : Sur la Figure 8.12, l’ordinateur affiche le mot false. Donc l’expression fahrenheit == 69.8 n’est pas vraie (true). Comment réconcilier ces faits  ? Il ne peut pas y avoir vraiment de doute sur le fait que fahrenheit == 69.8 est faux. Cela dit quoi sur la valeur de fahrenheit ? Sa valeur n’est jamais affichée sur le Listing  8.5. Est-ce que le problème pourrait venir de là ? À ce stade, j’utilise un vieux truc de programmeur. J’ajoute des instructions pour afficher la valeur de fahrenheit. fahrenheit = 9.0 / 5.0 * celsius + 32.0; System.out.print("fahrenheit: "); //Ajout System.out.println(fahrenheit); //Ajout La Figure  8.13  illustre ce qui se passe maintenant lors de l’exécution. Au lieu de la valeur attendue, le calcul

effectué

par

l’ordinateur

donne  69.80000000000001. Et voilà le coupable  ! L’ordinateur effectue tous ses calculs avec des zéros et des un, pas comme nous qui utilisons une

arithmétique en base 10. La réponse de l’ordinateur n’est pas incorrecte. Elle est juste très légèrement imprécise.

FIGURE 8.13

Les degrés Fahrenheit au complet.

Souvenez-vous

que,

dans

un

exemple

du

Chapitre  7, l’opérateur modulo (%) de Java vous donnait la réponse  0.1299999999999999 au lieu du  0.13

que vous attendiez. C’est le même

phénomène étrange qui se produit ici. Et pourtant, le code du Listing  8.5  ne fait qu’utiliser vos vieux amis, la division, la multiplication et l’addition. Vous devez donc faire très attention lorsque vous comparez deux nombres pour savoir s’ils sont égaux (avec ==) ou différents (avec !

=). Des

petites imprécisions peuvent survenir pratiquement n’importe où lorsque vous travaillez avec les types double ou float de Java. Et plusieurs petites imprécisions peuvent se cumuler pour devenir une

très grosse imprécision. Avec ces types, l’égalité parfaite n’est pratiquement jamais au rendez-vous. Si votre programme ne réagit pas comme vous le pensiez, ajoutez à votre code des instructions print et println pour contrôler le comportement de vos variables. Si vous comparez des valeurs double, laissez-vous une certaine marge. Au lieu d’utiliser une égalité parfaite, demandez plutôt si une valeur particulière est raisonnablement proche de la valeur attendue. Par exemple, utilisez une condition du style fahrenheit >= 69.8 - 0.01 && fahrenheit Déboguer en tant que -> Application Java (d’accord, Déboguer tout simplement, c’est correct aussi). Vous devez sélectionner cette commande (et pas simplement Exécuter) dans le menu pour activer tous

les outils de débogage. Votre code se lance. Comme vous travaillez toujours avec le programme du Listing  8.5, il vous demande d’entrer une température Celsius. 4. Tapez le nombre 21 dans la console et appuyez sur Entrée. Votre code continue à s’exécuter jusqu’à ce qu’il atteigne le point d’arrêt. À ce moment, l’exécution stoppe pour vous permettre d’examiner la situation. 5. Dans le coin supérieur droit de la fenêtre d’Eclipse, regardez ce qui est affiché dans la vue Variables. Comme l’illustre la Figure 8.C, vous retrouvez dans cette vue toutes vos variables (ce qui n’est pas surprenant), et vous constatez immédiatement que la valeur de fahrenheit

est

de 

69.80000000000001.

Formidable  ! Grâce au débogueur, vous pouvez examiner les valeurs de vos variables en cours d’exécution ! 6. Pour terminer l’exécution du programme, cliquez sur le bouton Reprendre (Resume) de la fenêtre de débogage (Figure 8.C). 7. Pour revenir à la configuration Java traditionnelle, cliquez sur Fenêtre->Ouvrir la perspective->Java.

FIGURE 8.A

FIGURE 8.B

FIGURE 8.C

Comparer des caractères Les

opérateurs

de

comparaison

du

Tableau 8.1  fonctionnent aussi pour les caractères. En gros, l’opérateur plus petit que ( Character.isDigit('a') jshell> Character.isDigit('2') jshell> Character.isLetter('a') jshell> Character.isLetter('2') jshell> Character.isLetterOrDigit('4')

jshell> Character.isLetterOrDigit('@') jshell> Character.isLowerCase('b') jshell> Character.isLowerCase('B') jshell> Character.isLowerCase('7') jshell> Character.isJavaIdentifierPart('x') jshell> Character.isJavaIdentifierPart('7') jshell> Character.isJavaIdentifierPart('') jshell> Character.isJavaIdentifierPart(' ')

PARTIE 3 Contrôler les flux DANS CETTE PARTIE… Prendre de grandes décisions (ou, plus exactement, prendre des décisions pas si grandes) Répéter, répéter, répéter et encore répéter Lire des données dans des fichiers de votre disque dur

Chapitre 9

Des bifurcations sur la route DANS CE CHAPITRE : » Écrire des instructions qui font un choix entre des alternatives » Placer une instruction dans une autre » Écrire plusieurs types d’instructions pour prendre des décisions

une assertion qui aurait pu être écrite telle quelle dans le V oici Chapitre 8 :

Si vous essayez d’écrire des mots ou des phrases (pas simplement des lettres), vous avez besoin d’utiliser quelque chose appelé une chaîne (String). Ici, il y a deux éléments importants. Le premier, c’est l’utilisation de quelque chose appelé une chaîne. Le second, c’est que votre choix dépend d’un autre quelque chose qui peut être vrai ou faux. Il est vrai que si vous essayez d’enregistrer des mots ou des phrases, alors vous avez besoin d’utiliser quelque chose appelé une chaîne (String). Ce chapitre s’occupe des prises de décision, qui jouent un rôle fondamental dans la création des instructions. Avec ce qui est explicité ici, vous allez pouvoir faire un grand bond en avant dans vos compétences de programmeur.

Décisions, décisions ! Vous marchez le long d’une route de campagne tranquille. C’est un beau jour d’été. Il ne fait pas trop chaud, et une légère brise venant du nord vous rafraîchit agréablement. Vous tenez ce livre, ouvert au Chapitre 9. Vous lisez les paragraphes qui précèdent, et vous levez soudain les yeux. Vous voyez un embranchement sur la route. Il y a deux panneaux, un dirigé vers la gauche et l’autre vers la droite. Le premier indique «  Enregistrer des mots ou des phrases  ? Vrai  » et le second «  Ne pas enregistrer des mots ou des phrases  ? Faux  » . Vous évaluez la situation «  mots-ou-phrases  » , et vous virez à gauche ou à droite selon les résultats de cette évaluation. Cette histoire est illustrée sur la Figure 9.1.

FIGURE 9.1

De quel côté se diriger ?

La vie est remplie de tels embranchements. Prenons l’exemple d’une série d’actions à conduire pour réchauffer un plat congelé : » Avec un four à micro-ondes : Mettre le plat sur le plateau du micro-ondes. Régler le four à micro-ondes sur 900 C et la minuterie sur 2 minutes. Appuyer sur le bouton Marche. Régler la minuterie avec 2 minutes supplémentaires. » Avec un four traditionnel : Préchauffer le four à 350 oC. Placer le plat sur une feuille de cuisson. Faire cuire pendant 25 minutes. À nouveau, vous devez choisir entre deux alternatives. Si vous utilisez un four à micro-ondes, faites ceci. Sinon, faites cela. En fait, il est difficile d’imaginer des instructions utiles qui ne mettent pas en jeu des choix. Si vous êtes propriétaire et que vous avez moins de  60  ans, cliquez ici. Si vous ne vous souvenez plus comment utiliser les accolades dans Java, voyez le Chapitre 4. Estce que l’utilisateur a tapé son bon mot de passe ? Si oui, acceptez sa connexion. Si non, demandez-lui de recommencer. Si vous pensez que la Bourse va monter, alors achetez des actions. Sinon, achetez des obligations. Et si vous achetez des actions, lesquelles devriez-vous choisir ? Et quand devriez-vous vendre ?

Prendre des décisions (les instructions Java if)

Lorsque vous travaillez sur des programmes informatiques, vous avez à prendre une décision après l’autre. Pratiquement tous les langages de programmation ont une manière de traiter les embranchements. Dans Java (comme dans de nombreux autres langages), cette fonctionnalité est appelée l’instruction if (si). Le Listing 9.1 en propose un exemple très simple. LISTING

9.1 Une instruction if.

if (randomNumber > 5) { System.out.println("Oui. Évident, non ?"); } else { System.out.println("Non. Et ne posez plus la question."); } Pour voir un programme plus complet, reportez-vous (ou courez, sautez) un peu plus loin au Listing 9.2. L’instruction if du Listing  9.1  représente une branche, une décision, ou si vous préférez deux alternatives possibles. En bon français, elle pourrait se lire de la manière suivante : Si la valeur de la variable randomNumber est plus grande que 5, Afficher à l’écran « Oui. Évident, non ? », Sinon Afficher à l’écran « Non. Et ne posez plus la question. ». Cette «  fourche  » est représentée graphiquement sur la Figure 9.2.

FIGURE 9.2

Un nombre aléatoire décide de votre sort.

Précisions sur les instructions if Une instruction if peut prendre la forme suivante : if (Condition) { CertainesInstructions } else { AutresInstructions } Pour

obtenir

une

véritable

instruction

if,

remplacez

les

conteneurs Condition, CertainesInstructions et AutresInstructions par du code valide. Voici comment la situation se présente sur le Listing 9.1 : » J’ai remplacé Condition par randomNumber > 5. » J’ai remplacé CertainesInstructions par System.out.println("Oui. Évident, non ?") ; .

» J’ai remplacé AutresConditions par System.out.println("Non. Et ne posez plus la question.") ; . Ces remplacements sont illustrés sur la Figure 9.3.

FIGURE 9.3

Une instruction if et son format.

Pour distinguer les deux parties d’une instruction if, on les appelle généralement la clause if et la clause else (qui peut d’ailleurs ou non être présente). if (Condition) { clause if } else { clause else } Une instruction if

est un exemple d’instruction composée,

autrement d’une instruction qui en inclut d’autres. Sur le Listing 9.1, l’instruction if contient deux appels à println, et ces appels sont eux-mêmes des instructions. Remarquez la manière dont j’utilise les parenthèses et les pointsvirgules dans l’instruction if du Listing 9.1. En particulier :

» La condition doit être entre parenthèses. » Les instructions contenues dans la clause if se terminent par un point-virgule. Et c’est pareil dans la clause else. » Il n’y a pas de point-virgule après la condition. » Il n’y a pas de point-virgule immédiatement après le mot else. En tant que programmeur débutant, vous pourriez penser que ces règles sont arbitraires. Mais ce n’est pas le cas. Elles relèvent d’une grammaire extrêmement précise et réfléchie, plus logique même que celle de votre langue maternelle ! Le Tableau  9.1  vous montre ce qui peut se passer si vous ne respectez pas les règles de construction des instructions if. Les deux derniers exemples sont les plus notoires. Dans ce cas, le compilateur ne détecte pas l’erreur, ce qui vous donne une fausse sensation de sécurité. Par contre, lorsque vous exécutez le programme, le code ne se comporte pas comme vous l’aviez prévu. TABLEAU

9.1

Erreurs courantes dans les instructions if.

Erreur

Exemple

Messages ou résultats probables

Parenthèses manquantes

if randomNumber > 5 {

autour de la condition

Erreur de syntaxe sur le sème "5", ) était attendu après ce sème.

Point-virgule manquant après if (randomNumber > 5) { Erreur de une instruction de la clause

System.out.println("Y") syntaxe, insérez

if ou else

}

";" pour effectuer BlockStatements.

Point-virgule immédiatement if (randomNumber >

 

après la condition Erreur de syntaxe sur le sème  

5) ; {

System.out.println("Y") "else", supprimez ce sème. ; } else { Point-virgule immédiatement } else ; {

Pas d’erreur de

après le mot else

compilation, mais l’instruction qui suit else est toujours exécutée, quelle que soit la valeur de la condition.

Accolades absentes

if (randomNumber > 5)

Le programme

System.

se compile

out.println("Y") ; else parfois sans System.out.println("N") erreurs, mais son ;

exécution ne donne généralement pas ce que vous attendiez.

Lorsque vous composez votre code, pensez à une instruction if comme à une unité indivisible. Au lieu de taper la première ligne et de continuer, essayez d’écrire le « squelette » de l’instruction if en entier. if () { // À faire : remplir la condition. // À faire : compléter CertainesInstructions. } else {

// À faire : Compléter AutresInstructions. } Une fois que c’est fait, vous pouvez commencer à travailler sur votre liste de tâches. En appliquant cette méthode à une instruction composée, il est beaucoup plus difficile de commettre une erreur.

Un exemple complet, droit comme un if Le Listing  9.2  contient un exemple complet proposant une instruction if simple. Le code se comporte comme une sorte d’oracle (de charlatan  ?) électronique. Posez-lui une question à laquelle il peut répondre par oui ou par non, et il vous montrera sa sagesse. Bien entendu, cette réponse est générée de manière aléatoire. Mais qui s’en soucie ? C’est juste un exemple… LISTING

9.2 Je sais tout.

import java.util.Scanner; import java.util.Random; class AnswerYesOrNo { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); Random myRandom = new Random(); int randomNumber; System.out.print("Tapez votre question, mon enfant : "); keyboard.nextLine(); randomNumber = myRandom.nextInt(10) + 1;

if (randomNumber > 5) { System.out.println("Oui. C'est évident !"); } else; { System.out.println("Non. Et ne posez plus la question !"); } keyboard.close(); } } La Figure  9.4  montre plusieurs exécutions de ce programme. L’action se décompose en quatre parties :

FIGURE 9.4

L’oracle en action.

1. Une question est posée à l’utilisateur. C’est l’appel à System.out.print, qui demande à l’utilisateur de saisir sa question. 2. Récupération de la question posée par l’utilisateur. Sur la Figure 9.4, j’ai exécuté quatre fois le programme, en saisissant à chaque fois une question différente. L’appel à keyboard.nextLine lit la question, mais il n’en fait strictement rien. D’accord, c’est une anomalie, mais c’est aussi le but du jeu dans ce programme… Normalement, lorsqu’un programme récupère une saisie au clavier, il est censé en faire quelque chose. Par exemple, il peut l’affecter à une variable : amount = keyboard.nextDouble(); Une autre possibilité consiste à afficher un résultat à l’écran : System.out.println(keyboard.nextLine()); Mais le code du Listing 9.2 est différent. Lorsque le programme est exécuté, il demande à l’utilisateur de taper quelque chose (via l’appel à keyboard. nextLine). En fait, notre programme n’a aucun besoin d’enregistrer la saisie de l’utilisateur pour l’analyser. Bien entendu, ce n’est pas un comportement habituel. Mais un oracle électronique n’est pas non plus quelque chose d’ordinaire. 3. Construction d’un nombre aléatoire (une valeur int comprise entre 1 et 10).

D’accord. Vous venez tout juste de jeter la question de l’utilisateur dans la corbeille. Comment allez-vous lui répondre par Oui ou par Non ? Pas de problème ! Aucun ! Vous allez afficher la réponse de façon arbitraire. L’utilisateur n’est bien sûr pas au courant. Il vous suffit pour cela de générer un nombre aléatoire. Les entiers compris entre 1 et 10 conviennent parfaitement. Sur le Listing 9.2, l’instruction qui contient Random et myRandom ressemble de très près au code familier Scanner. Mais, bien entendu, il y a une différence importante. Un appel à la méthode nextInt(10) de la classe Random ne récupère rien au clavier. Elle se contente de produire un nombre ex nihilo. Le nom Random (aléatoire) est défini dans l’API de Java. L’appel dans le Listing 9.2 à myRandom.nextInt(10) génère un nombre entre 0 et 9. Je lui ajoute 1 pour que la plage s’étende de 1 à 10, et j’affecte le résultat à la variable randomNumber. Après quoi il est temps de s’occuper de la réponse à la question de l’utilisateur. Dans l’API de Java, le mot Random est le nom d’une classe, et nextInt celui d’une méthode. Pour plus d’informations sur les relations entre classes et méthodes, voyez les Chapitres 17, 18 et 19. 4. Répondez oui ou non. Appeler myRandom.nextInt(10), c’est un peu comme faire tourner une roue dans un jeu télévisé. La roue a des arêtes numérotées de 1 à 10. Si le nombre qui sort est plus grand que 5, le programme répond oui. Si ce nombre est inférieur ou égal à 5, il répond non. Vous pouvez me croire sur parole. J’ai pris des tas de décisions importantes grâce à ce programme.

LES NOMBRES ALÉATOIRES M’ÉTOURDISSENT Lorsque vous appelez myRandom.nextInt(10) + 1, vous obtenez un nombre entier compris entre  1  et 10. Pour faire un test, j’ai écrit un programme qui appelle cette instruction vingt fois. Random myRandom=new Random(); System.out.print (myRandom.nextInt(10) + 1); System.out.print(“ “); System.out.print (myRandom.nextInt(10) + 1); System.out.print(“ “); System.out.print (myRandom.nextInt(10) + 1); // ...Et ainsi de suite. J’ai exécuté ce programme plusieurs fois et noté les résultats sur la Figure 9.A. Jetez un coup d’œil à cette figure et notez deux tendances : » Il n’y a pas de manière évidente de prédire ce que sera le prochain nombre. » Aucun nombre ne « sort » nettement plus souvent que les autres. La machine Java fait tout son possible pour qu’il en soit ainsi. Car il faut savoir que produire des nombres réellement aléatoires est un véritable cassetête. Voici quelques faits intéressants à ce sujet : » Les mathématiciens et les autres appellent cela des nombres aléatoires. Mais, en réalité, aucun nombre n’est en soi aléatoire. Après tout, en quoi 9 est-il aléatoire ? Un nombre est aléatoire uniquement lorsqu’il appartient à une collection très désordonnée de nombres. Plus précisément, un nombre est aléatoire si le programme utilisé pour le générer respecte les deux

tendances ci-dessus. Lorsqu’ils ont le temps de finir leur phrase, les mathématiciens parlent de nombre généré aléatoirement. » Il est difficile de générer des nombres de manière aléatoire. Les programmes informatiques font de leur mieux, mais, au final, chacun suit une certaine méthodologie, et cette méthodologie n’est pas véritablement aléatoire. Pour générer des nombres d’une manière réellement aléatoire, il vous faut une grande boule remplie de balles numérotées, comme dans un jeu d’argent célèbre. Le problème, c’est que les ordinateurs n’ont pas ce genre de périphérique. Donc, strictement parlant, les nombres produits par la classe Random de Java ne sont pas aléatoires. C’est pourquoi les spécialistes les appellent des nombres pseudoaléatoires. » Même si cela semble surprenant, connaître une valeur générée de manière aléatoire n’aide en rien à prédire ce que sera le nombre suivant. Si vous jetez par exemple plusieurs fois une pièce, et qu’elle tombe systématiquement sur le côté face, pouvez-vous prédire ce que donnera le prochain jet ? Absolument pas. C’est toujours du 50-50. On apprend cela à l’école depuis Blaise Pascal, et pourtant des tas de gens continuent à croire qu’ils peuvent prédire le prochain tirage du Loto…

FIGURE 9.A

Indenter les instructions if dans votre code Remarquez comment, sur le Listing  9.2, les appels à println à l’intérieur de l’instruction if sont indentés. Strictement parlant, ce n’est pas une obligation. Du point de vue de l’ordinateur, vous pourriez parfaitement tout écrire sur une seule ligne, ou disposer cette structure en zigzag. Le problème, c’est que, si vous n’indentez pas vos instructions d’une manière logique, ni vous ni personne d’autre n’arrivera à comprendre votre code. Cette indentation aide vos yeux (et votre cerveau) à voir immédiatement que ces instructions sont subordonnées au flux général if/else. Indentez toujours votre code pour que le flux d’un programme soit apparent au premier coup d’œil. Vous n’avez pas forcément besoin de réfléchir à l’indentation de votre code, car Eclipse est capable de le faire automatiquement. Voyez à ce sujet le Chapitre 4.

Variations autour du même thème Je n’aime pas écorcher les chats. Mais j’ai entendu dire qu’on a le choix entre plusieurs techniques pour dépouiller la bête de son pelage. J’y penserai la prochaine fois que le mien prendra le tapis pour une litière. Que vous écorchiez les chats, plumiez une volaille, écailliez un poisson ou écriviez un programme d’ordinateur, le même principe s’applique. Vous avez toujours des alternatives possibles. Le Listing 9.2  vous montre une manière d’écrire une instruction if. Le reste de ce chapitre (et tout le Chapitre  10) vous en propose d’autres.

… Quoi d’autre ? Vous pouvez créer une instruction if sans clause else. Imaginez par exemple une page Web sur laquelle un visiteur choisi au hasard parmi dix possibilités se voit offrir une promotion. Pour cela, j’appelle la méthode nextInt de la classe Random, et je propose la promotion à tous ceux pour lesquels le tirage retourne la valeur 7. » Si myRandom.nextInt(10) + 1 génère le nombre 7, afficher un message spécial pour la promotion. » Si myRandom.nextInt(10) + 1 génère un nombre autre que 7, ne rien faire du tout. Le code pour implémenter une telle stratégie est montré sur le Listing 9.3. La Figure 9.5 illustre quelques exemples d’exécution. LISTING

9.3 Avez-vous de la chance ?

import java.util.Random; class SpecialOffer { public static void main(String args[]) { Random myRandom = new Random(); int randomNumber = myRandom.nextInt(10) + 1; if (randomNumber == 7) { System.out.println("Vous êtes l'heureux gagnant !"); } System.out.println(randomNumber); } }

FIGURE 9.5

Trois exécutions du code du Listing 9.3.

L’instruction if du Listing 9.3 n’a pas de clause else. Elle prend la forme suivante : if (Condition) { CertainesInstructions }

Si

randomNumber

vaut  7,

l’ordinateur

affiche

Vous

êtes

l’heureux gagnant ! Sinon, il n’affiche rien du tout. Cette action est illustrée sur la Figure 9.6.

FIGURE 9.6

Si vous n’avez rien d’intéressant à dire, taisez-vous !

Utilisez toujours (je dis bien toujours) un double signe d’égalité lorsque vous comparez deux nombres ou deux caractères dans la condition d’une instruction if. N’utilisez jamais (je dis bien jamais) un seul signe égal. Le signe égal tout seul effectue une affectation, pas une comparaison. Sur le Listing  9.3, j’ai pris la liberté d’ajouter à la fin de la méthode main un appel supplémentaire à println. Cet appel affiche le nombre aléatoire généré par nextInt. Dans le cas d’une page Web proposant une promotion à certains visiteurs, vous ne feriez probablement pas ce genre de chose. Mais il n’est pas

possible de tester ce programme sans savoir exactement ce qui se passe. D’autre part, l’appel à ce println

ne fait pas partie de

l’instruction if. Il est donc exécuté dans tous les cas, ce qui me permet de connaître la valeur du nombre aléatoire en toutes circonstances pour contrôler l’exécution du programme.

Toujours plus avec l’instruction if Voici une situation intéressante. Vous avez deux équipes de football, les Bleus et les Jaunes. Vous voulez afficher les scores de ces équipes sur deux lignes distinctes, avec le vainqueur en premier (ou les Bleus d’abord en cas de match nul). Le code correspondant est proposé sur le Listing 9.4. LISTING

9.4 Les meilleurs seront les premiers.

import java.util.Scanner; import static java.lang.System.in; import static java.lang.System.out; class TwoTeams { public static void main(String args[]) { Scanner keyboard = new Scanner(in); int blues, yellows; out.print(" Résultats des Bleus et des Jaunes ? "); blues = keyboard.nextInt(); yellows = keyboard.nextInt(); out.println(); if (yellows > blues) { out.print("Jaunes : ");

out.println(yellows); out.print("Bleus : "); out.println(blues); } else { out.print("Bleus : "); out.println(blues); out.print("Jaunes : "); out.println(yellows); } keyboard.close(); } } La Figure 9.7 montre quelques exemples d’exécution de ce code.

FIGURE 9.7

Le code du Listing 9.4 en action.

Avec des accolades, les quelques print et println sont sagement rangés à l’intérieur de la clause if. Il en va exactement de même pour la clause else. L’embranchement correspondant est illustré sur la Figure 9.8.

FIGURE 9.8

Suivez votre équipe préférée !

INSTRUCTIONS ET BLOCS Une manière élégante de considérer les instructions if consiste à réaliser que vous ne pouvez placer qu’une seule instruction à l’intérieur de chaque clause de celles-ci. if (Condition) uneInstruction else uneAutreInstruction Vous vous dites peut-être que je raconte n’importe quoi. Après tout, sur le Listing  9.4, chaque clause (la clause if et la clause else) semble contenir quatre instructions, pas une seule. Mais, d’un point de vue technique, la clause if de ce listing n’a qu’une seule instruction, et il en est de même pour la clause else. En réalité, lorsque vous encadrez une série d’instructions par des accolades, vous obtenez ce qui est appelé un bloc, et un bloc se comporte comme une instruction unique. La documentation de Java définit un bloc comme étant un type d’instruction (un des multiples types d’instructions). Par conséquent, sur le Listing 9.4, les lignes : { out.print(«Jaunes : «); out.println(yellows); out.print(“Bleus : “); out.println(blues); } forment un bloc, et donc une seule instruction qui en contient quatre autres. C’est ainsi que fonctionne cette règle. Dans une instruction if, si vous voulez que l’ordinateur exécute plusieurs instructions, vous les combinez pour les

transformer en un bloc. Et, pour cela, vous les regroupez entre des accolades.

Quelques déclarations d’importation utiles Sauf erreur de ma part, le Listing 9.4  devrait contenir dix lignes System.out.print. C’est lassant de devoir à chaque fois tout taper, vous ne trouvez pas  ? Est-ce qu’il ne serait pas mieux que l’ordinateur se souvienne de ce que signifie out.print, tout simplement ? Bien entendu, les ordinateurs ne fonctionnent pas de cette manière. Si vous voulez qu’un ordinateur «  sache  » ce que signifie out.print, il faut que cette connaissance soit codée quelque part dans le compilateur Java. Heureusement,

la

possibilité

d’abréger

des

choses

comme

System.out.print existe depuis Java  5.0. On appelle cela une importation statique. Vous en trouvez l’illustration au début du Listing 9.4. Chaque fois que je débute un programme par import static java.lang.System.out; je peux remplacer System.out

par out

dans le reste du

programme. Et c’est la même chose pour System.in. Grâce à la déclaration qui se trouve vers le haut du Listing  9.4, je peux remplacer new Scanner(System.in) par la forme plus simple new Scanner(in). Vous allez me poser des tas de questions, je le sens. Si je peux abréger java.util. Scanner en écrivant Scanner, qu’y a-t-il de spécial dans ce System.out ? Et pourquoi faut-il quand même écrire out.print ? Pourquoi pas tout simplement print ? Et

quand faut-il employer le mot static ? Quelle est la différence entre java.util et java.lang ? Désolé. Je ne peux pas vous donner des réponses à ces questions avant le Chapitre  18. Il faut en effet aborder d’abord d’autres notions, comme les classes, les packages et les membres statiques. D’ici là, croyez-moi sur parole. Collez ces trois déclarations d’importation tout en haut de vos programmes Java en espérant que tout fonctionnera correctement. Vous pouvez abréger System.out en out, et System.in en in. Pour cela, copiez dans vos programmes les trois déclarations d’importation du Listing  9.4. N’y changez rien. Toute déviation provoquerait une erreur de compilation. Exercez-vous un peu avec les instructions if !

Oups ! Qu’est-ce qui ne va pas avec le code suivant  ? Comment le corriger ? System.out.println("Combien d’œufs dans une douzaine ?"); int number = keyboard.nextInt(); if (number = 12) { System.out.println("Effectivement. C’est correct."); } else { System.out.println("Désolé. C’est incorrect."); }

N’écrivez pas du code de cette façon

Quand

j’ai

écrit

le

code

suivant,

je

ne

l’ai

pas

indenté

correctement. Quelle est la sortie produite par ce mauvais code  ? Pourquoi ? int n = 100; if (n > 100) System.out.println("n is big"); System.out.println("Will Java display this line of text?"); if (n = est =. L’opposé de && est ||. Si vous changez le prix, vous risquez de rencontrer quelques menus problèmes. En effet, avec une instruction telle que price = 5.00, la réponse renvoyée sera Vous devez 5.0 €. Bon spectacle ! La raison tient au fait que Java ne mémorise pas les deux zéros qui se trouvent à droite du point décimal (et il ne sait pas non qu’il s’agit d’un bon

spectacle à ce prix-là). Pour contourner ce genre de situation,

voyez

ce

qui

est

NumberFormat.getCurrencyInstance

dit

de

dans

le

Chapitre 18.

Quand faut-il initialiser ? Restons sur le Listing 10.1. Notez l’initialisation de la variable price : double price = 0.00 ; Cette ligne déclare la variable price, et définit pour elle une valeur initiale nulle. Si j’omets cette déclaration, je vais obtenir un message d’erreur : price ne peut pas être résolu en tant que variable Ici, je n’ai pas initialisé ma variable, mais le compilateur ne refuse pas d’exécuter le programme (quoiqu’il ait de sérieux doutes et me demande de confirmer

le

lancement).

Quel

est

alors

le

problème ? La réponse tient à l’emplacement des instructions d’affectation dans le code. Considérez les deux faits suivants :

» L’instruction qui affecte une valeur à age (age = keyboard.nextInt() ; ) ne se trouve pas dans une instruction if. Cette instruction d’affectation est donc toujours exécutée (à moins qu’un événement totalement imprévu survienne), et donc la variable est sûre de se voir attribuer une valeur. » Les deux instructions qui affectent une valeur à price (price = 9.25 ; et price = 5.25 ; ) se trouvent à l’intérieur des instructions if. Si vous regardez la Figure 10.3, vous verrez que chaque groupe d’âge est traité. Personne ne peut avoir un âge qui force les deux conditions à être fausses. Lorsque vous exécutez ce programme, une des deux instructions affectant une valeur à price sera donc obligatoirement traitée. Le problème, c’est que le compilateur n’est pas assez intelligent pour vérifier tout cela à l’avance. Il voit uniquement la structure de la Figure 10.4, et il s’effraie du fait que l’ordinateur pourrait peut-être ne jamais rencontrer une situation qui soit vraie.

FIGURE 10.4

Les choix du Listing 10.1.

Si, pour une raison qui nous échappe à tous (peutêtre qu’il y a dans le public des extraterrestres ayant un âge totalement inconnu de nos systèmes de calcul), les deux conditions if étaient fausses, jamais la variable price ne se verrait affecter une

valeur (plus précisément, elle n’aurait aucune valeur intentionnellement définie dans le code). C’est dans ces circonstances étranges que l’ordinateur atteint l’instruction System.out.print(price) ; . Il ne peut pas afficher la valeur de cette variable, puisqu’elle ne contient rien de significatif. Le compilateur lève alors ses yeux virtuels vers le ciel et lance sa complainte.

Toujours plus de conditions La pizzéria du coin fait en ce moment des promotions. Si vous achetez deux pizzas, vous gagnez un bon de réduction de  2  € pour le spectacle. Super ! Pour

intégrer

cette

réduction

dans

mon

programme, il faut que j’adapte le code du Listing  10.1.

Le

résultat

est

proposé

sur

le

Listing  10.2, et la Figure  10.5  propose quelques exemples d’exécution de ce code. LISTING

10.2 Avez-vous un bon de réduction ?

import java.util.Scanner;

class TicketPriceWithDiscount { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); int age; double price = 0.00; char reply; System.out.print("Quel est votre âge ? "); age = keyboard.nextInt(); System.out.print("Avez-vous un bon de réduction ? (O/N) "); reply = keyboard.findWithinHorizon(".", 0) .charAt(0); if (age >= 12 && age < 65) { price = 9.25; } if (age < 12 || age >= 65) { price = 5.25; } if (reply == 'O' || reply == 'o') {

price -= 2.00; } if (reply != 'O' && reply != 'o' && reply!='N' && reply!='n') { System.out.println("Pardon ?"); } System.out.print("Vous devez "); System.out.print(price); System.out.print("€. "); System.out.println("Bon spectacle !"); keyboard.close(); } }

FIGURE 10.5

Exemples d’exécution du code du Listing 10.2.

Le Listing  10.2  contient deux instructions if plus complexes : » Dans la première instruction, le programme vérifie si la variable reply contient la lettre O ou la lettre o. Si c’est le cas, il soustrait 2.00 au prix (pour plus d’informations sur des opérateurs tels que -=, revoyez le Chapitre 7). » La seconde instruction est un peu plus lourde. La condition teste la variable reply pour voir si elle contient quelque chose de raisonnable. Si la réponse n’est pas O, et n’est pas o, et n’est pas N, et n’est pas n, alors l’ordinateur exprime poliment son

incompréhension en affichant « Pardon ? » (ce qui devrait attirer votre attention). Lorsque vous créez une condition comportant de multiples parties, vous avez toujours plusieurs manières de prendre le problème. Par exemple, vous pourriez réécrire la dernière condition du Listing 10.2  sous cette forme  : if ( ! (reply == 'Y' || reply == 'y' || reply == 'N' || reply == 'n')). Ce qui se lirait : Si la réponse n’est pas Y, ou y, ou N, ou n, alors… Quel est le meilleur code, celui-ci ou celui du Listing  10.2  ? Aucun en particulier. C’est une affaire de choix et de style personnel. Bref, le mieux, c’est ce qui vous permet de bien comprendre la logique que vous devez coder.

Utiliser des variables booléennes Aussi bon soit-il, un programme peut toujours être amélioré. Prenez le code du Listing 10.2. Est-ce que cette forêt d’if vous rend nerveux  ? Est-ce que votre cerveau commence à fumer ? Est-ce que ce ne serait pas mieux si vous pouviez comprendre la condition en y jetant simplement un coup d’œil ?

Dans une certaine mesure, c’est possible. Si vous prenez

la

peine

de

créer

quelques

variables

supplémentaires, vous pouvez rendre votre code plus facile à lire. Le Listing  10.3  vous montre comment. LISTING

10.3 George Boole serait fier de ce code.

import java.util.Scanner; class NicePrice { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); int age; double price = 0.00; char reply; boolean isKid, isSenior, hasCoupon, hasNoCoupon; System.out.print("Quel est votre âge? "); age = keyboard.nextInt(); System.out.print("Avez-vous un bon de réduction ? (O/N) "); reply =

keyboard.findWithinHorizon(".", 0) .charAt(0); isKid = age < 12; isSenior = age >= 65; hasCoupon = reply == 'O' || reply == 'o'; hasNoCoupon = reply == 'N' || reply == 'n'; if (!isKid && !isSenior) { price = 9.25; } if (isKid || isSenior) { price = 5.25; } if (hasCoupon) { price -= 2.00; } if (!hasCoupon && !hasNoCoupon) { System.out.println("Pardon ?"); } System.out.print("Vous devez "); System.out.print(price); System.out.print("€. "); System.out.println("Bon spectacle !");

keyboard.close(); } } L’exécution

du

code

exactement

les

mêmes

Figure 

10.5.

La

du

seule

Listing  10.3  donne

résultats

que

différence

sur

la

entre

le

Listing  10.2  et le Listing  10.3  tient à l’emploi de variables booléennes. Sur le Listing  10.3, vous traitez

les

doubles

signes

d’égalité

et

les

comparaisons avant d’exécuter les instructions if. Au moment d’atteindre celles-ci, les conditions utilisent

maintenant

de

simples

mots,

en

l’occurrence isKid, isSenior et hasCoupon. Grâce à toutes ces variables booléennes, l’écriture des instructions if et leur lecture deviennent bien plus simples. Est-ce que c’est un enfant  ? Est-ce que c’est un sénior  ? Est-ce que la personne a un bon de réduction ? Ajouter une variable booléenne peut rendre votre code mieux gérable. Il est vrai que certains langages de programmation n’ont pas ce type d’objet,

et

c’est

pourquoi

de

nombreux

programmeurs préfèrent écrire leurs conditions if

à la volée. Dans ce livre, je me servirai selon les circonstances de ces deux méthodes.

Mixer différents opérateurs logiques Avec le programme du Listing 10.2, j’ai introduit la possibilité d’avoir un bon de réduction offert par la pizzéria du coin. Le problème, c’est que je ne peux pas utiliser un tel bon avec une autre remise. J’ai bien essayé de convaincre la caissière que j’avais moins de 12 ans, mais elle ne m’a pas cru. J’ai refait une tentative en prétendant que j’étais d’âge canonique, mais cela n’a pas marché non plus. Comment faire  ? Évidemment, en adaptant le code du Listing  10.2  à ces différentes situations. Le résultat vous est proposé sur le Listing  10.4  et la Figure 10.6 en illustre l’exécution.

FIGURE

LISTING

10.6

Exemples d’exécution du code du Listing 10.4.

10.4 Pas d’avantages indus pour les enfants

et les séniors ! import java.util.Scanner; class CheckAgeForDiscount { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); int age; double price = 0.00; char reply;

System.out.print("Quel est votre âge ? "); age = keyboard.nextInt(); System.out.print("Avez-vous un bon de réduction ? (O/N) "); reply = keyboard.findWithinHorizon(".", 0) .charAt(0); if (age >= 12 && age < 65) { price = 9.25; } if (age < 12 || age >= 65) { price = 5.25; } if ((reply == 'O' || reply == 'o') && (age >= 12 && age < 65)) { price -= 2.00; } System.out.print("Vous devez "); System.out.print(price); System.out.print("€. "); System.out.println("Bon spectacle !");

keyboard.close(); } } Le

Listing  10.4  ressemble

beaucoup

à

ses

prédécesseurs. La principale différence se trouve dans les lignes mises en caractères gras. Cette instruction

if

teste

deux

choses,

chacune

comportant deux parties : » Est-ce que le client a un bon de réduction ? Autrement dit, est-ce que la personne a répondu O ou o ? » Est-ce que le client appartient au groupe « standard » ? Autrement dit, est-ce que la personne a au moins 12 ans et moins de 65 ans ? Sur le Listing 10.4, j’ai relié les éléments  1  et  2  en utilisant l’opérateur &&. En effet, il faut que les deux

conditions

soient

vérifiées

pour

que

la

personne puisse bénéficier de la réduction. C’est ce qu’illustre la Figure 10.7.

Utiliser des parenthèses

Le Listing  10.4  démontre un point important concernant les conditions. Parfois, vous avez besoin de parenthèses pour qu’une condition fonctionne correctement.

Prenons

par

exemple

le

code

suivant : //Ce code est incorrect : if (reply == 'O' || reply == 'o' && age >= 12 && age < 65) { price -= 2.00; }

FIGURE 10.7

Les deux critères, âge et réponse, doivent être vrais.

Remarquez que, par rapport au Listing  10.4, plusieurs parenthèses ont été retirées. Ce code est

incorrect, car les conditions reply

==

'O'

et

reply == 'o' ne sont plus regroupées, de même que age >= 12 et age < 65. La Figure 10.8 illustre le résultat étrange résultant de cette absence de parenthèses.

FIGURE 10.8

Une offense impardonnable.

Vous remarquez sur la Figure  10.8  que le fait de répondre o ou O conduit à deux tarifs différents, même si l’âge de la personne n’a pas changé. En voici la raison  : en l’absence de parenthèses, chaque

opérateur

&&

est

évalué

avant

tout

opérateur ||. C’est la règle établie par le langage de programmation

Java,

comme

par

tous

les

logiciens : et (&&) a la prééminence sur ou (||). Si la réponse est O

(majuscule), la condition sans

parenthèses va se présenter ainsi :

reply == ‘O’ || le reste n’a pas d’importance Puisque le premier élément de la condition est vrai, celle-ci est entièrement évaluée comme étant vraie. C’est ce qu’illustre la Figure 10.9.

FIGURE 10.9

« Vrai ou faux » donne « vrai ».

Imbriquer les conditions Nous sommes à la fin des années  1960, et la série Le Prisonnier fait fureur sur le petit écran. Dans le

dernier épisode, le héros rencontre sa Némésis, «  Numéro un  » . Au début, Numéro un porte un genre de masque de Janus à double face. Puis le masque tombe et en révèle un autre, représentant un singe. Pour trouver ce qui se cache sous ce masque de singe, procurez-vous la série sur DVD dans une braderie. Mais, surtout, remarquez la stratification  : un masque sous un masque. Vous pouvez faire le même genre de chose avec des instructions if. L’exemple de cette section vous montre comment. Mais,

pour

commencer,

revenons

sur

le

Listing 10.4. Dans ce code, la condition age >= 12 && age < 65 est testée deux fois. Et, à chaque fois, l’ordinateur transmet les nombres  12, 65  et la variable age au travers d’une incroyable quantité de circuits. Tout cela pour obtenir la même réponse. C’est bien sûr une perte de temps, mais ce n’est pas la seule question. Imaginons par exemple que vous vouliez changer l’âge limite des séniors pour définir le prix du ticket d’entrée ? Vous relisez le code, et vous voyez la ligne qui contient le test age >= 12 && age < 65. Vous changez par exemple  65  en  100, et vous passez à autre chose. Le problème, c’est que vous

avez peut-être mis cette ligne à jour, mais pas les autres.

Est-ce

qu’il

ne

serait

pas

mieux

de

centraliser toutes ces comparaisons ? C’est là où le Listing  10.5  vient à votre rescousse. J’y ai regroupé toutes mes instructions if pour plus d’efficacité. Le code en est plus dense, mais il fait parfaitement le travail. LISTING

10.5 Des instructions if imbriquées.

import java.util.Scanner; class AnotherAgeCheck { public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); int age; double price = 0.00; char reply; System.out.print("Quel est votre âge ? "); age = keyboard.nextInt(); System.out.print("Avez-vous un bon de réduction ? (O/N) ");

reply = keyboard.findWithinHorizon(".", 0).charAt(0); if (age >= 12 && age < 65) { price = 9.25; if (reply == 'O' || reply == 'o') { price -= 2.00; } } else { price = 5.25; } System.out.print("Vous devez "); System.out.print(price); System.out.print("€. "); System.out.println("Bon spectacle !"); keyboard.close(); } }

Conditions if imbriquées D’accord, c’est le même titre que ci-dessus juste un peu réorganisé. Mais comment faire mieux  ? Si vous exécutez le code du Listing  10.5,

vous

obtiendrez

les

mêmes

résultats

qu’avec

le

Listing  10.4. Ici, l’idée principale consiste à placer une instruction if à l’intérieur d’une autre. Après tout, le Chapitre 9 vous explique qu’une instruction if peut prendre la forme suivante : if (Condition) { CertainesInstructions } else { AutresInstructions } Qui a dit que CertainesInstructions ne pouvait pas contenir une autre instruction if ? De la même manière,

AutresInstructions

parfaitement

contenir

une

peut

également

instruction

if.

Finalement, vous pouvez créer une instruction if qui contient une instruction if qui, elle-même, contient une instruction if… Et ainsi de suite sans qu’il n’y ait de limite prédéfinie à ces niveaux d’imbrication. if (age >= 12 && age < 65) { price = 9.25; if (reply == 'O' || reply == 'o') { if (isSpecialFeature) { price -= 1.00; } else {

price -= 2.00; } } } else { price = 5.25; } Les

instructions

if

imbriquées

ne

sont

pas

particulièrement difficiles à écrire, dès lors que vous

prenez

le

temps

d’y

réfléchir

et

d’en

décomposer la logique en étapes précises. Si cela peut vous aider, dessinez un diagramme comme celui de la Figure 10.10.

FIGURE 10.10

Le Listing 10.5 en action.

Lorsque vous imbriquez des instructions, vous devez être particulièrement attentif à l’emploi de l’indentation et des accolades (voir la Figure 10.11). Si l’indentation n’est pas correctement respectée, personne (pas même le programmeur qui a écrit le code)

n’arrivera

à

comprendre

comment

le

programme fonctionne. C’est le genre de chose qui peut

très

cauchemar.

rapidement

devenir

un

véritable

FIGURE 10.11

Faites très attention à l’indentation et aux accolades.

Des instructions if en cascade Voici une énigme  : vous avez deux équipes de foot (ou de ce que vous voulez), les Bleus et les Jaunes. Vous voulez afficher les scores de ces équipes sur deux lignes distinctes, le vainqueur en premier (donc au-dessus du perdant). Comment faire si un match se termine par un résultat nul ? Vous donnez votre langue au chat ? La réponse est la suivante : il n’y a pas de bonne réponse. Ce qui se passe dépend de la manière dont vous écrivez le programme. Reprenez le Listing  9.4. Lorsque les scores sont égaux, la condition yellows > blues est fausse. Le flux du programme est donc dérouté vers l’instruction else. Cette clause affiche le score des Bleus en premier, puis celui des Jaunes (reportez-vous à la Figure 9.7).

Il n’y a pas d’obligation à ce que le programme fonctionne ainsi. Si je modifie le Listing  9.4  en remplaçant yellows

>

blues

par yellows

>=

blues, c’est le score des Jaunes qui sera affiché en premier. Supposons maintenant que vous vouliez un peu plus de contrôle. Lorsque les scores sont égaux, vous souhaiteriez afficher un message du genre Match nul. Pour obtenir ce résultat, réfléchissez en termes de fourchette à trois dents. Vous avez une dent pour (ou contre…) les Jaunes quand ils gagnent, une autre dent pour les victoires des Bleus, et une troisième pour les matchs nuls. Vous pouvez écrire le code de différentes manières, mais je propose celle du Listing  10.6. La Figure  10.12 illustre trois exécutions de ce programme. LISTING

10.6 En cas de match nul…

import java.util.Scanner; import static java.lang.System.out; class WinLoseOrTie { public static void main(String args[]) { Scanner keyboard = new

Scanner(System.in); int yellows, blues; out.print("Résultats des Jaunes et des Bleus ? "); yellows = keyboard.nextInt(); blues = keyboard.nextInt(); out.println(); if (yellows > blues) { out.println("Victoire des Jaunes..."); out.print("Jaunes : "); out.println(yellows); out.print("Bleus : "); out.println(blues); } else if (blues > yellows) { out.println("Victoire des Bleus..."); out.print("Bleus : "); out.println(blues); out.print("Jaunes : "); out.println(yellows); } else { out.println("Match nul..."); out.print("Jaunes : "); out.println(yellows); out.print("Bleus : "); out.println(blues); }

keyboard.close(); } }

FIGURE 10.12

Allez les… qui au fait ?

Le Listing 10.6 représente une manière de réfléchir à un problème. Vous avez une question, mais plus de deux réponses possibles. En l’occurrence, la question est «  Qui a gagné  ?  » , et les réponses sont « Bleus » , « Jaunes » ou « Aucun » . Le problème est résolu grâce à une instruction if, mais ce type d’instruction ne peut avoir que deux branches  : vrai ou faux. Les alternatives sont donc combinées pour former des instructions if en cascade.

Sur le Listing  10.6, le format de cette cascade se présente ainsi : if (Condition1) { CertainesInstructions } else if (Condition2) { AutresInstructions } else { EncoreDesInstructions } En général, vous pouvez utiliser else if autant de fois qu’il est nécessaire : if (yellowsWin) { out.println("Victoire des Jaunes..."); out.print("Jaunes : "); out.println(yellows); out.print("Bleus : "); out.println(blues); } else if (bluesWin) { out.println("Victoire des Bleus..."); out.print("Bleus : "); out.println(blues); out.print("Jaunes : "); out.println(yellows); } else if (isATie) { out.println("Match nul..."); out.print("Jaunes : ");

out.println(yellows); out.print("Bleus : "); out.println(blues); } else if (gameCancelled) { out.println("Désolé, chers supporters, le match est annulé."); } else { out.println("Le match n’est pas encore terminé."); } Il n’y a rien de spécial à ce sujet. Ce n’est pas une nouvelle fonctionnalité du langage. C’est juste une espèce d’échappatoire offert par Java qui vous permet de réfléchir différemment aux décisions à prendre dans votre code. Le

Listing 

10.6 

utilise

une

déclaration

d’importation statique qui évite d’avoir à saisir je ne sais combien de fois System.out. Ce sujet a été rapidement évoqué dans le Chapitre 9, mais nous y reviendrons plus précisément dans le Chapitre 18.

Énumérer les possibilités Le Chapitre 8 décrit le type booléen de Java (un type qui ne peut prendre que deux valeurs, true ou false). Il est très commode, mais il peut aussi

arriver que vous ayez besoin de plus de valeurs. Après tout, passer au feu vert, c’est oui ou non, vrai ou faux, mais ce genre de feu a trois couleurs : vert, orange et rouge. Une suite de couleurs dans un jeu de cartes serait trèfle, carreau, cœur et pique. Un jour ouvrable de la semaine, c’est lundi, mardi, mercredi, jeudi ou vendredi. La vie est pleine de petits ensembles de possibilités, et Java (depuis sa version  5.0) possède une fonctionnalité qui peut refléter ce type de situation. On appelle cela un type énuméré.

Créer un type énuméré L’histoire racontée sur le Listing  10.6  a trois fins possibles  : ce sont les Jaunes qui gagnent, ou bien ce sont les Bleus, ou bien le match est nul. Vous pourriez représenter des possibilités par la ligne de code Java suivante : enum QuiGagne {domicile, visiteur, aucun} Si le match de dimanche se joue au Stade de France, la valeur domicile représentera une victoire pour les Bleus, et la valeur visiteur une victoire pour les Jaunes.

Un des buts de la programmation est que la structure de chaque programme reflète le problème qu’il sert à résoudre. Lorsque vous y arrivez, le programme maintenance

est

facile

coûte

à

peu.

comprendre Par

et

exemple,

sa un

programme servant à gérer des clients et des comptes devrait utiliser des noms comme clients et comptes. Et un programme devant traiter trois sorties possibles (l’équipe à domicile gagne, les visiteurs gagnent, il y a match nul) devrait aussi comporter une variable reflétant ces situations. C’est ce qu’illustre la ligne de code ci-dessus. Ici, QuiGagne est appelé un type énuméré. C’est un peu

comme

un

booléen

dans

un

espace

multidimensionnel. Au lieu de deux valeurs (true et false), le type QuiGagne

en possède trois

(domicile, visiteur et aucun). Et si vous brisez les frontières de la quatrième dimension, vos types énumérés pourront même contenir des tas d’autres valeurs. Une fois le type énuméré défini, vous pouvez créer une variable possédant ce type : QuiGagne qui ;

Cela étant fait, il est possible d’affecter une valeur à cette nouvelle variable : Qui = QuiGagne.domicile ; Dans la section suivante, nous allons mettre tout cela en forme et en action.

Utiliser un type énuméré Le Listing  10.7  vous montre comment utiliser un type énuméré pour notre championnat. Les noms de variables d’origine sont, comme à l’habitude, conservés pour des raisons de cohérence et pour éviter toute erreur. LISTING

10.7 Félicitons les vainqueurs, consolons les

perdants ! import java.util.Scanner; import static java.lang.System.out; class Scoreboard { enum WhoWins {home, visitor, neither} public static void main(String args[]) {

Scanner keyboard = new Scanner(System.in); int yellows, blues; WhoWins who; out.print("Résultats des Jaunes et des Bleus ? "); yellows = keyboard.nextInt(); blues = keyboard.nextInt(); out.println(); if (yellows > blues) { who = WhoWins.visitor; out.println("Victoire des Jaunes :-("); } else if (blues > yellows) { who = WhoWins.home; out.println("Les bleus gagnent :-)"); } else { who = WhoWins.neither; out.println("C'est un match nul :-|"); } out.println(); out.println("Ce jeu vous est offert par SnitSoft"); out.println("votre partenaire minceur."); out.println("SnitSoft, élu

produit de l'année"); out.println("dans le Chapitre 6."); out.println("SnitSoft, essayé et recommandé"); out.println("par de grandes marques."); out.println("SnitSoft vous souhaite un bon match."); out.println(); if (who == WhoWins.home) { out.println("C'est une victoire amplement méritée !"); } if (who == WhoWins.visitor) { out.println("L'arbitre nous a volé un penalty !"); out.println("Mais nous aurons notre revanche au match retour !"); } if (who == WhoWins.neither) { out.println("Un bon nul pour la suite du championnat !"); } keyboard.close();

} } Trois exemples d’exécution du Listing  10.7  sont illustrés sur la Figure 10.13.

FIGURE 10.13

Bienvenue au stade !

Voyons de plus près ce qui se passe dans ce listing : » Je crée une variable pour enregistrer les valeurs de type WhoWins. De même que la ligne double amount; déclare la variable amount comme étant de type double (pour des valeurs de type 5.95 ou 30.95), la ligne WhoWins who; déclare la variable who comme étant de type WhoWins (pour enregistrer des valeurs comme home, visitor et neither). » J’affecte une valeur à la variable who. Pour cela, j’exécute une instruction d’affectation de la forme who = WhoWins.quelqueChose;

L’affectation est basée sur le résultat de la comparaison if (yellows > blues). Remarquez bien que chacune des affectations est pleinement qualifiée : WhoWins.home, WhoWins.visitor et WhoWins.neither. Si j’oublie le préfixe et que j’écris par exemple simplement who = home; le compilateur me renverra un message d’erreur disant home ne peut pas être résolu en tant que variable. C’est ainsi que fonctionne le type énuméré. » Je compare la valeur de la variable avec chacune des composantes de WhoWins. Dans une instruction if, je teste la condition who == WhoWins.home. Dans les autres instructions if, j’effectue la comparaison avec les valeurs suivantes de WhoWins. Vers la fin du Listing 10.7, j’aurais pu me dispenser des valeurs enum

en testant par exemple une

seconde fois la condition yellows > blues.

if (yellows > blues) { out.println("Victoire des Jaunes :("); } // Plus loin dans le programme... if (yellows > blues) { out.println(""L'arbitre nous a volé un penalty !"); } Mais cette tactique serait maladroite. Avec un programme retrouver

plus avec

complexe, une

je

bonne

pourrais

me

douzaine

de

comparaisons de ce genre. Ce serait comme poser et reposer la même question je ne sais combien de fois. Au lieu de cela, les résultats possibles sont stockés dans une valeur énumérée dont je peux tester la valeur autant de fois qu’il est nécessaire. C’est une manière très propre de résoudre des problèmes de vérifications à répétition. Les lectures sur Java, c’est bien. Mais c’est encore mieux si vous travaillez avec Java. Voici quelques choses que vous pouvez faire pour assouplir vos muscles Java :

Des voies mystérieuses Expliquez pourquoi le code suivant affiche toujours Le premier est plus petit, quel que soit le nombre que l’utilisateur tape. Par exemple, si l’utilisateur tape 7 puis 5, le programme affiche Le premier est plus petit : int premierNombre = keyboard.nextInt(); int secondNombre = keyboard.nextInt(); boolean Pluspetit = premierNombre < secondNombre; if (Pluspetit = true) { System.out.println("Le premier est plus petit."); }

Quel genre de nombre ? Écrivez un programme qui lit un nombre sur le clavier et affiche l’un des messages positif, négatif ou nul pour décrire ce nombre. Utilisez des instructions if en cascade.

À l’approche d’un feu de signalisation

Votre manuel du parfait conducteur dit : « Lorsque vous

approchez

d’un

feu

vert,

traversez

l’intersection, à moins qu’il ne soit dangereux de le faire ou qu’un agent de police ne vous ordonne de faire autre chose » . Écrire un programme qui pose trois questions à l’utilisateur : » Est-ce que vous approchez d’un feu vert ? » Est-il sûr de traverser l’intersection ? » Est-ce qu’un officier de police vous ordonne de ne pas traverser l’intersection ? En réponse à chaque question, l’utilisateur répond par O ou par N. En se basant sur les trois réponses, afficher Allez ou Stop. Inutile de préciser que vous ne devriez pas exécuter ce programme tout en conduisant.

« Oui » ou « oui » ? Modifiez le programme « À l’approche d’un feu de signalisation  »

de

manière

à

permettre

à

l’utilisateur de répondre «  oui  » , avec un O majuscule ou bien un o minuscule.

Au rouge ou à l’orange ? Modifiez le programme « À l’approche d’un feu de signalisation  » pour qu’il demande la couleur du feu (V/O/R). Lorsque l’utilisateur répond O ou R, et qu’il n’est pas sûr de continuer à avancer, ou si l’agent

ordonne

aux

conducteurs

de

ne

pas

continuer, le programme affiche Stop. Sinon, le programme n’affiche rien. Ne me rendez en rien responsable des points que vous pourriez perdre sur votre permis de conduire si vous passez à l’orange ou au rouge. Après tout, il ne s’agit que d’un exercice virtuel !

Quoi ? Encore un programme de feux de signalisation ? Vous pouvez utiliser System.out.println

pour

afficher une valeur enum. Par exemple, dans le Listing 10.7, si vous ajoutez l’instruction : System.out.println(who); à la fin de la méthode main, le programme affiche un des mots home, visitor, ou neither. Essayez ceci en créant un type énuméré nommé Couleur avec pour valeurs vert, orange et rouge. Écrire un

programme qui demande de quelle couleur est le feu

tricolore

l’utilisateur

(V/O/R). pour

Couleur.vert,

Utilisez

affecter

la

l’une

réponse des

de

valeurs ou

Couleur.orange

Couleur.rouge à une variable nommée signal. Utilisez

System.out.println

pour

afficher

la

valeur de la variable signal.

Acheter des lunettes 3D Mon cinéma local demande trois dollars de plus par place pour un film projeté en  3D (en fait, il faut racheter à chaque fois une nouvelle paire de lunettes 3D. Je ne peux pas apporter la paire que j’ai payée la dernière fois que j’ai vu un film en 3D.) Modifiez le code du Listing  10.5  pour que le programme demande si le film est en 2D ou en 3D. Pour un film en  3D, le programme ajoute trois dollars au prix d’entrée. (Note  : L’ancienne série télévisée Twilight Zone  –  celle de  1959  –  avait commencé avec un discours du narrateur Rod Serling parlant d’une cinquième dimension. Je me demande ce que je devrais payer de nos jours pour voir Twilight Zone dans mon cinéma local ! )

Chapitre 11

Java et son commutateur virtuel DANS CE CHAPITRE : » Traiter de multiples alternatives » Sortir au milieu d’une instruction » Gérer des affectations alternatives

déclarer votre flamme, appuyez sur  1. «P our Pour un simple rendez-vous, appuyez sur  2. Pour annuler le rendez-vous, appuyez sur  3. Pour contacter une autre personne, appuyez sur  4.  » Et on fait comment à partir de 10 ? Quand une situation oblige à faire un choix parmi de multiples possibilités, il est temps de faire appel à l’instruction switch (commutateur) de Java.

À la rencontre du commutateur Java

Vous

vous

souvenez

que

le

code

du

Listing 9.2 simulait une sorte d’oracle électronique. Vous posiez une question au programme, et il vous répondait au hasard par oui ou par non. Mais il faut bien reconnaître que tout cela n’allait pas très loin. Il n’y avait que deux réponses possibles. Même la poupée parlante la moins sophistiquée qui soit est capable de faire mieux. Supposons donc que vous vouliez améliorer le code du Listing 9.2. L’appel à myRandom.nextInt(10) + 1 génère un nombre entre  1  et  10. Vous pourriez peut-être afficher une phrase différente pour chacun de ces nombres. Une grosse pile de conditions if ferait bien sûr l’affaire : if (randomNumber == 1) { System.out.println("Oui. C'est évident."); } if (randomNumber == 2) { System.out.println("Non. Et ne posez plus la question."); } if (randomNumber == 3) { System.out.print("Oye, oye !"); System.out.println(" Trois sacs pleins.");

} if (randomNumber == 4) . . . if (randomNumber < 1 || randomNumber > 10) { System.out.print("Désolé, l’oracle électronique"); System.out.println(" est fermé pour réparations."); } Mais cette approche semble bien trop lourde. Pourquoi ne pas créer une instruction qui vérifierait une seule fois la valeur de randomNumber et qui déciderait de la conduite à tenir en fonction du résultat  ? Sachez que cette instruction existe  ! Elle s’appelle switch et le Listing  11.1  en propose un exemple d’application. LISTING

11.1 Une réponse pour chaque occasion.

import java.util.Scanner; import java.util.Random; import static java.lang.System.out; class TheOldSwitcheroo {

public static void main(String args[]) { Scanner keyboard = new Scanner(System.in); Random myRandom = new Random(); int randomNumber; out.print("Tapez votre question, mon enfant : "); keyboard.nextLine(); randomNumber = myRandom.nextInt(10) + 1; switch (randomNumber) { case 1: out.println("Oui. C'est évident."); break; case 2: out.println("Non. Et ne posez plus la question."); break; case 3: out.print("Oye, Oye !"); out.println(" Trois sacs pleins."); break;

case 4: out.print("Qu'est-ce que vous ne comprenez pas"); out.println(" dans le mot 'non' ?"); break; case 5: out.println("Pas de chance, Hortense."); break; case 6: out.println("Sûr et certain."); break; case 7: out.print("Oui, mais seulement si"); out.println(" vous êtes gentil avec moi."); break; case 8: out.println("Oui (si ça vous fait plaisir)."); break;

case 9: out.print("Non, pas avant que"); out.println(" la marée soit haute."); break; case 10: out.print("Non, pas avant que"); out.println(" la marée soit basse."); break; default: out.print("Vous pensez que vous"); out.print(" avez des problèmes ?"); out.print(" Mon générateur de nombres"); out.println(" aléatoires est en panne !"); break; } out.println("Au revoir !"); keyboard.close();

} }

Les clauses case dans une instruction switch La Figure  11.1  vous montre trois exécutions du programme développé sur le Listing  11.1. Voici ce qui se passe à chaque fois :

FIGURE 11.1

Le code du Listing 11.1 en action.

» L’utilisateur tape une question existentielle, et la variable randomNumber fournit une valeur. Sur le second exemple de la Figure 11.1, cette valeur est de 4. » L’exécution du code du Listing 11.1 atteint alors le début de l’instruction switch. L’ordinateur commence à vérifier ce que disent les clauses

case. La valeur 4 n’est pas en début de liste (le premier case correspondant à 1). Il passe donc à la clause suivante. » Même motif, même punition pour les deux clauses case qui suivent (elles concernent les valeurs 2 et 3). » La valeur de la prochaine clause (le nombre 4) correspond à ce qu’il cherche. Il exécute donc les instructions qu’il trouve dans cette clause, c’est-àdire : out.print("Qu'est-ce que vous ne comprenez pas"); out.println(" dans le mot 'non' ?"); break; » Les deux premières instructions affichent le message que vous pouvez voir sur la Figure 11.1. La troisième, break, indique qu’il doit quitter immédiatement l’instruction switch sans plus s’occuper de ce qu’elle contient. L’heure de faire un break, en quelque sorte ! L’ordinateur laisse donc de côté les instructions case 5, case 6 et ainsi de suite. Il se rend directement à l’instruction qui se trouve juste après la fin de la structure switch.

» L’ordinateur n’a plus qu’à dire au revoir, puisque c’est ce que le programme lui demande de faire. L’idée

générale

qui

se

dissimule

derrière

le

Listing 11.1 est illustrée sur la Figure 11.2.

La valeur par défaut dans une instruction switch Supposons qu’il se produise un événement terrible pendant l’exécution du code du Listing  11.1. Par exemple, l’expression myRandom.nextInt(10) + 1 se met brutalement à générer une valeur qui déborde de la page allant de 1 à 10 (ce n’est qu’une image, bien sûr). Dans ce cas, l’ordinateur va passer en revue toutes les clauses case

sans

trouver la bonne valeur. Il arrive donc à la clause default, qu’il exécute sans se poser plus de questions, et il va donc afficher le message « Vous pensez que vous avez des problèmes ? » et ainsi de suite. Après quoi, il en a terminé avec l’instruction switch et peut dire « Au revoir ! » .

FIGURE 11.2

Une fourchette à onze dents.

Vous n’avez pas réellement besoin de placer un break tout à la fin d’une instruction switch (donc ici de la clause default). Je ne l’ai laissé que par souci du détail.

L’instruction switch décortiquée Une instruction switch peut prendre la forme suivante : switch (Expression) { case Valeur1 : Instructions case Valeur2 : AutresInstructions // ... autres cas... default: EncoreDesInstructions } » L’expression n’a pas à être une valeur entière (int). Elle peut être de type char, byte, short ou encore int. Par exemple, le code suivant fonctionne sous Java 5 et ultérieur (et même avec toutes les versions si vous n’utilisez pas la classe Scanner et sa méthode findWithinHorizon) :

char letterGrade; letterGrade = keyboard.findWithinHorizon(".",0).char At(0); switch (letterGrade) { case 'A': System.out.println("Excellent"); break; case 'B': System.out.println("Bien"); break; case 'C': System.out.println("Moyen"); break; } » Avec Java 7 ou supérieur, Expression peut être une chaîne de caractères. Par exemple : String description; description = keyboard.next(); switch (description) { case "Excellent": System.out.println('A'); break; case "Bien":

System.out.println('B'); break; case "Moyen": System.out.println('C'); break; } J’ai présenté brièvement la classe String de Java dans le Chapitre 8. J’y reviendrai plus en détail dans le Chapitre 18. » Expression n’est pas nécessairement une unique variable. Il peut s’agir d’une expression quelconque de type char, byte, short ou encore int. L’exemple qui suit simule le lancement de deux dés : int die1, die2; die1 = myRandom.nextInt(6) + 1; die2 = myRandom.nextInt(6) + 1; switch (die1 + die2) { //...etc. Les clauses case d’une instruction switch n’ont pas à res» pecter un ordre prédéfini. Le code suivant est parfaitement accep-

table : switch (randomNumber) { case 2: System.out.println("Non. Et ne posez plus la question."); break; case 1: System.out.println("Oui. C'est évident."); break; case 3: System.out.print("Oye, Oye !"); System.out.println(" Trois sacs pleins."); break; //...etc. Cette organisation peut ralentir très légèrement l’exécution du code, mais c’est parfaitement légal. Dans l’idéal, la valeur la plus probable devrait être placée en premier, et ainsi de suite dans l’ordre décroissant. Mais encore faut-il connaître la valeur la plus probable ! » Vous n’avez pas besoin d’une clause case pour chaque valeur de Expression. Le traitement de certaines valeurs peut être délégué à la clause default. Par exemple :

switch (randomNumber) { case 1: System.out.println("Oui. C'est évident."); break; case 5: System.out.println("Pas de chance, Hortense."); break; case 7: System.out.print("Oui, mais seulement si"); System.out.println(" vous êtes gentil avec moi."); break; case 10: System.out.print("Non, pas avant que"); System.out.println(" la marée soit basse."); break; default: System.out.print("Désolé,"); System.out.println(" je suis incapable de me décider."); break; } » La clause default est facultative.

switch (randomNumber) { case 1: System.out.println("Oui. C'est évident."); break; case 2: System.out.println("Non. Et ne posez plus la question."); break; case 3: System.out.print("Je suis très fatigué."); System.out.println(" Demandez à quelqu’un d’autre."); } System.out.println("Au revoir"); Si la clause default n’est pas définie et qu’aucune valeur n’est couverte par les clauses case qui précèdent, l’instruction switch ne fait rien. Si, par exemple, la valeur de randomNumber est égale à 4, le code ci-dessus affiche Au revoir et c’est tout. » D’une certaine manière, les instructions if sont plus souples que l’emploi de switch. Par exemple, vous ne pouvez pas utiliser une condition dans une instruction switch :

// Interdit : switch (age >= 12 && age < 65) De même, il n’est pas possible d’utiliser une condition comme valeur case, soit : // Interdit : switch (age) { case age Fichier (New -> File). La boîte de dialogue Nouveau fichier va s’ouvrir. 3. Dans le champ Nom de fichier, tapez le nom de votre nouveau fichier de données. Vous pouvez entrer tout ce que votre ordinateur considère comme étant un nom de fichier valide. Pour cet exemple, j’ai utilisé rawData.txt, c’est-àdire un texte contenant des données brutes. Mais des noms mesDonnées.aMoi, ou encore listeNombres.dat sont parfaitement acceptables. Par mesure de précaution, il vaut peut-être mieux éviter les espaces ou des noms peu explicites, du genre unTruc, mais au final c’est vous qui décidez (ou votre patron, ou bien votre client). 4. Cliquez sur le bouton Terminer. Le nom du fichier apparaît dans l’Explorateur de packages. De plus, une vue d’éditeur vide, avec son onglet s’ouvre dans Eclipse. 5. Tapez votre texte dans l’éditeur.

Pour cet exemple, j’ai saisi comme texte 19,95 5 (voir la Figure 13.4). Vous pouvez bien entendu faire un tout autre choix.

FIGURE 13.4

Éditer un fichier d’entrées.

Rappelez-vous : les valeurs numériques en entrée se servent du séparateur décimal du pays défini dans le système d’exploitation de l’ordinateur. En français, vous devez donc taper une virgule et non un point pour séparer partie entière et partie décimale. Si vous utilisez un autre éditeur que celui d’Eclipse, vous devez faire attention à la manière dont celui-ci gère la création des fichiers. Par exemple, le BlocNotes de Windows ajoute par défaut l’extension .txt aux noms de fichiers (TextEdit sur un Mac ajoute l’extension .rtf). Pour ne pas voir votre topsecret.data transformé par mégarde en topsecret.data.txt par le Bloc-Notes de

Windows, ruinant ainsi le fonctionnement de votre programme et vous faisant perdre des heures avant de détecter le problème, écrivez ce nom entre guillemets, comme ceci : "topsecret.data". Sur un Mac, vous choisirez l’option d’enregistrement au format texte avant de sauvegarder le fichier. De plus, vous devriez aussi décocher dans la boîte de dialogue Enregistrer sous l’option d’ajout automatique de l’extension .txt.

Exécuter le code Pour

qu’Eclipse

exécute

votre

code,

suivez

exactement la même procédure que pour les autres programmes Java. Sélectionnez votre projet (13-02 dans cet exemple), puis choisissez la commande Exécuter dans le menu de même nom. Lorsque vous lancez le code du Listing  13.2, rien n’apparaît dans la vue Console d’Eclipse. Cette absence totale d’information visuelle traumatise certaines

personnes.

En

vérité,

dans

un

tel

programme, tout se déroule en coulisse. Il n’y a aucune instruction qui lise quelque chose au clavier, ou qui écrive quelque chose à l’écran. Aucune interaction avec l’utilisateur, donc. Au pire,

si votre disque dur est assez bruyant, entendrezvous un léger chuintement dans la machine. Rien de plus. Tout ce que produit ce programme est envoyé dans un fichier du disque dur. Mais comment voir le contenu de celui-ci ?

Voir le contenu du fichier de sortie Pour voir ce que donne votre sortie, suivez ces étapes : 1. Dans le Navigateur d’Eclipse, sélectionnez la branche 13-02. 2. Dans le menu principal, choisissez Fichier>Actualiser (Refresh). 3. Dans le Navigateur, développez la branche 1302. Un nouveau fichier appelé cookedData.txt devrait apparaître sous la branche 13-02. 4. Faites un double clic sur la ligne cookedData.txt. Le contenu de ce fichier apparaît dans un éditeur d’Eclipse (voir la Figure 13.5).

Notez à nouveau que la valeur calculée par le programme est enregistrée selon les canons de Java, c’est-à-dire avec un point comme séparateur décimal.

Les fichiers disque et leurs problèmes Lorsque vous exécutez le code du Listing  13.2, l’ordinateur

rencontre

l’instruction

Scanner(new

File("rawData.txt")).

new Si

la

machine virtuelle Java ne trouve pas le fichier rawData.txt et que vous avez lancé l’exécution via le raccourci F11, la vue Déboguer affiche une série impressionnante

de

messages

comme

l’illustration de la Figure 13.6.

FIGURE 13.5

Visualiser le contenu du fichier de sortie.

sur

FIGURE 13.6

Ce stupide ordinateur ne trouve pas votre fichier.

Si vous avez lancé l’exécution du programme par la commande Exécuter du menu de même nom (le raccourci est Ctrl+F11), ou avec Exécuter en tant que  -> Application Java, le message d’erreur sera plus fruste mais tout autant impressionnant (voir la Figure 13.7).

FIGURE 13.7

Mais il est où, ce fichier ?

Cette situation peut être très frustrante. Dans la plupart des cas, vous savez pertinemment qu’il existe bel et bien un fichier appelé rawData.txt sur votre disque dur. Mais il n’existe aucun procédé rapide, simple et à l’épreuve des balles pour

résoudre ce problème. Cependant, vous devriez toujours contrôler pour commencer les points suivants : » Vérifiez une nouvelle fois si un fichier appelé rawData.txt est bien présent. Ouvrez l’Explorateur Windows ou le Finder du Mac et recherchez un fichier portant ce nom. Selon la configuration de votre système, il est possible que l’extension des fichiers n’apparaisse pas. Dans ce cas, vous verrez simplement rawData. Pour vous débarrasser une fois pour toutes de ce genre de situation, référez-vous au Chapitre 2. » Vérifiez qu’il n’y a pas d’erreur dans le nom du fichier. Le nom indiqué dans le programme et celui enregistré sur le disque dur doivent être totalement identiques. Il suffit d’une lettre mal placée ou encore d’une espace presque invisible pour « planter » le programme. Avec Linux ou toute autre variante d’UNIX, mis à part Mac OS X, les majuscules et les minuscules sont différenciées. rawData.txt et

rawdata.txt seront donc considérés comme étant deux fichiers différents. » Vérifiez que le fichier se trouve dans le bon dossier. D’accord, vous avez un fichier appelé rawData.txt. Mais ne vous attendez pas à ce que Java consulte la liste de tous les dossiers de votre disque dur pour savoir où se trouve précisément ce fichier. Comment alors savoir dans quel dossier vous devez placer rawData.txt et ses congénères ? Voici comment tout cela fonctionne : chaque projet Eclipse possède son propre dossier sur le disque dur de votre ordinateur. Par exemple, sur la Figure 13.5, vous voyez le dossier 13-02 et son sous-dossier src. Mais, il existe également d’autres sous-dossiers dénommés .settings ou encore bin. Ces dossiers contiennent les fichiers qui les concernent. Vous pouvez cependant remarquer que les fichiers rawData.txt et cookedData.txt se trouvent directement sous 13-02. Autrement dit, ils sont stockés à la racine du projet.

Dans notre exemple, le fichier rawData.txt devrait être placé à la racine du projet 13-02. C’est pourquoi je vous ai demandé au début de la section « Créer un fichier d’entrées » de sélectionner le projet 13-02, et non un sousdossier de celui-ci. La Figure 13.8 vous montre les fichiers en entrée et en sortie dans le dossier racine du projet 13-02 d’Eclipse. Mais, en général, les emplacements des fichiers peuvent être assez délicats à localiser, surtout si vous n’utilisez pas Eclipse. La règle de base décrite ici peut ne pas s’appliquer du tout dans d’autres environnements.

FIGURE 13.8

Le contenu du projet 13-02 sur votre disque dur.

Voici donc une astuce que vous pouvez utiliser dans tous les cas de figure (même si vous ne

passez pas par Eclipse, et même si vous écrivez du code Java sans vous servir d’un environnement de développement intégré). Voyez cette version aménagée du code du Listing 13.2 : import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; class JustWrite { public static void main(String args[]) throws FileNotFoundException { PrintStream diskWriter = new PrintStream("cookedData.txt"); diskWriter.println(99.75); diskWriter.close(); } } Ce programme n’a pas besoin d’un quelconque fichier rawData.txt. Si vous exécutez ce code et que vous n’obtenez pas de message d’erreur, recherchez la sortie (cookedData.txt) sur votre disque dur. Notez le nom du dossier qui contient ce fichier. Une fois que vous aurez placé

rawData.txt dans ce même dossier, tous vos problèmes d’exécution du Listing 13.2 devraient s’évanouir. » Vérifiez le contenu du fichier rawData.txt. Cela ne peut jamais faire de mal d’aller jeter un coup d’œil sur le contenu du fichier rawData.txt pour s’assurer qu’il contient les bonnes valeurs (surtout si vous avez un doute sur le séparateur de décimales employé). Si ce fichier n’apparaît pas dans l’Explorateur de packages ou le Navigateur d’Eclipse, rafraîchissez l’affichage. Assurez-vous que la branche rawData.txt est bien présente et faites un double clic dessus pour afficher son contenu. Par défaut, La classe Scanner de Java recherche des espaces vierges entre les valeurs servant à la saisie. Dans notre exemple, rawData.txt devrait contenir la ligne 19,95 5, et non pas 19,955 ou 19,95.5. La classe Scanner recherche n’importe quel type d’espace vierge entre les valeurs. Il peut donc s’agir d’espaces au sens usuel du terme, mais aussi de tabulations ou encore de sauts de ligne. Par exemple, plusieurs espaces pourraient

séparer 19,95 et 5. Mais ces valeurs pourraient tout aussi bien se trouver sur deux lignes distinctes.

Écrire un programme orienté disque Le Listing 13.2  ressemble beaucoup au Listing  13.1. En fait, vous pouvez passer de l’un à l’autre avec un minimum de travail d’édition. Voici comment : » Ajoutez les lignes d’importation suivantes au début de votre code : import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; » Ajoutez la clause throws suivante à l’en-tête de la méthode : throws FileNotFoundException » Dans l’appel à new Scanner, remplacez System.in par un appel à new File :

Scanner aVariableName = new Scanner(new File("nomFichierEntrée")) » Créez un PrintStream pour écrire les données dans un fichier disque : PrintStream anotherVariableName = new PrintStream("nomFichierSortie"); » Utilisez le nom de la variable Scanner pour appeler nextInt, nextLine, et ainsi de suite. Par exemple, pour passer du Listing 13.1 au Listing 13.2, j’ai changé unitPrice = keyboard.nextDouble(); quantity = keyboard.nextInt(); en unitPrice = diskScanner.nextDouble(); quantity = diskScanner.nextInt(); » Utilisez le nom de la variable PrintStream dans les appels à print et println.

Par exemple, pour passer du Listing 13.1 au Listing 13.2, j’ai changé System.out.println(total); en diskWriter.println(total); » Utilisez le nom de la variable Scanner dans l’appel à close. Par exemple, pour passer du Listing 13.1 au Listing 13.2, j’ai changé keyboard.close(); en diskScanner.close(); » Utilisez le nom de la variable PrintStream dans un appel à close. Par exemple, pour passer du Listing 13.1 au Listing 13.2, j’ai ajouté

diskWriter.close(); à la fin de la méthode main.

Lire le contenu d’un fichier Toutes les méthodes Scanner

peuvent lire le

contenu d’un fichier. Par exemple, pour lire un mot dans un fichier appelé monDiscours, vous pourriez écrire ce genre de code : Scanner diskScanner = new Scanner(new File("monDiscours")); String oneWord = diskScanner.next(); Pour lire un caractère dans un fichier appelé lettres.dat, puis afficher ce caractère à l’écran, vous pouvez faire quelque chose comme ceci : Scanner diskScanner = new Scanner(new File("lettres.dat")); System.out.println( diskScanner.findWithinHorizon(".",0).char At(0));

Que votre fichier comporte ou non une extension, le nom que vous spécifiez dans votre code, et celui sous lequel il est enregistré sur votre disque dur doivent être strictement identiques.

Écrire dans un fichier Les

méthodes

print

et

println

permettent

d’écrire des données dans un fichier. Voici quelques exemples : » Lors de l’exécution du code du Listing 13.2, la variable total mémorise le nombre 99.75. Pour déposer cette valeur dans le fichier cookedData.txt, vous exécutez diskWriter.println(total); L’appel à println écrit bien le total dans le fichier désigné par diskWriter grâce à l’instruction suivante : PrintStream diskWriter = new PrintStream("cookedData.txt"); » Dans une autre version du programme, vous pourriez décider de ne pas utiliser de variable

pour le total. Dans ce cas, il vous suffirait d’enregistrer directement le résultat de l’opération, comme ceci : diskWriter.println(unitPrice * quantity); » Pour afficher OK à l’écran, vous pouvez utiliser cet appel de méthode : System.out.print("OK"); Pour écrire OK dans un fichier nommé approuve.txt, vous pourriez faire appel au code suivant : PrintStream diskWriter = new PrintStream("approuve.txt"); diskWriter.print("OK"); » Vous pouvez aussi décider d’écrire OK sous la forme de deux lettres séparées, par exemple ainsi : System.out.print('O'); System.out.print('K');

La même procédure appliquée à l’écriture dans un fichier donnerait ceci : PrintStream diskWriter = new PrintStream("approuve.txt"); diskWriter.print('O'); diskWriter.print('K'); » Comme leurs contreparties pour System.out, les méthodes d’écriture sur disque print et println diffèrent dans leur comportement quant aux fins de ligne. Supposons que vous vouliez afficher le texte suivant sur l’écran : Jaunes

Bleus

1

7

Vous pouvez procéder aux appels de méthode cidessous : System.out.print("Jaunes "); System.out.println("Bleus"); System.out.print(1); System.out.print(" "); System.out.println(7);

Pour enregistrer maintenant ce même texte dans un fichier appelé scores. dat, vous pourriez utiliser le code suivant : PrintStream diskWriter = new PrintStream("scores.dat"); diskWriter.print("Jaunes "); diskWriter.println("Bleus"); diskWriter.print(1); diskWriter.print(" "); diskWriter.println(7);

NOMMEZ CE FICHIER Comment faire si un fichier contenant vos données ne se trouve pas dans le dossier du projet  ? Dans ce cas, il est nécessaire de spécifier le chemin d’accès à ce fichier lorsque vous appelez new File. Sous Windows, par exemple, votre projet

pourrait

\utilisateurs\

se

trouver

dans

le

dossier

votrenom\workspace\13-09,

c

:

tandis

qu’un fichier appelé total.dat serait enregistré dans un autre dossier, disons c : \calculs. Pour faire référence à ce fichier, vous devez alors inclure le nom du dossier, celui du fichier et (par mesure de sécurité) celui de l’unité de disque : Scanner diskScanner = new Scanner (new File(«c:\\calculs\\total. dat»)); Remarquez les doubles barres obliques servant à délimiter la lettre du disque, le nom du dossier et celui du fichier. Si vous avez lu l’encadré «  Évasion  » dans le Chapitre  12, vous vous souvenez peut-être que la chaîne \total avec une seule barre oblique serait interprétée comme une tabulation (\t) suivie

de

otal.

Ce

qui,

évidemment,

absolument pas le résultat attendu.

ne

donnerait

En doublant la barre oblique, vous indiquez que vous voulez signifier

un

chemin

d’accès,

\\calculs\\total.dat

»

et

donc

doit

que

être

lu

«

c

:

comme

représentant c : \calculs\total.dat. Si ce doublement vous ennuie, sachez qu’il est aussi possible d’utiliser la barre oblique classique à la place. Ainsi, Windows répondra de la même manière à new

File(

«

c

:

\\calculs\\total.dat » ) et à new File( « c : /calculs/total.dat » ). Si vous travaillez sous Linux, UNIX ou Mac OS X, cette affaire de double barre ne s’applique pas à vous. Écrivez simplement Scanner diskScanner = new Scanner (new File( «/Users/me/calculs/total.dat»)); ou quelque chose de semblable qui soit conforme à la structure de votre système de fichiers.

Écrire et réécrire J’ai l’esprit parfois un peu tortueux. Je me suis donc demandé ce qui se passerait si je lançais plusieurs fois de suite le même programme d’écriture dans un fichier. J’ai donc créé une petite application que

j’ai exécutée deux fois (voir le Listing  13.5). J’ai ensuite examiné le contenu de mon fichier de sortie pour constater qu’il ne contenait que deux lettres (voir la Figure 13.9). LISTING

13.5 Une petite expérience.

import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; class WriteOK { public static void main(String args[]) throws FileNotFoundException { PrintStream diskWriter = new PrintStream(new File("approuve.txt")); diskWriter.print ('O'); diskWriter.println('K'); diskWriter.close(); } }

FIGURE

13.9

Tester les OK.

Voyons de plus près la séquence des événements : 1. Avant d’exécuter le code du Listing 13.5, aucun fichier approuve.txt n’existe sur mon disque dur. Il faut bien qu’une expérience ait un point de départ. 2. J’exécute une première fois le code du Listing 13.5. L’appel à new PrintStream crée un fichier appelé approuve.txt. À cet instant, ce fichier ne contient aucune lettre. Par la suite, les appels à print et à println y enregistrent deux caractères. Lorsque le code se termine, le fichier approuve.txt contient donc les lettres OK. 3. J’exécute le code du Listing 13.5 une seconde fois.

Je pourrais imaginer que le fichier approuve.txt va maintenant contenir OKOK. Mais ce n’est pas ce que je constate sur la Figure 13.9. Pourquoi ? » L’appel à new PrintStream supprime mon fichier approuve.txt existant. Il produit un tout nouveau (new !) fichier vide portant le même nom. » Une fois ce nouveau fichier approuve.txt créé sur le disque, les méthodes print et println y enregistrent successivement les lettres O et K. Et voilà toute l’histoire. Chaque fois que vous relancez

le

programme,

il

jette

le

fichier

approuve.txt s’il constate qu’il est déjà présent sur le disque dur (sans même avoir la courtoisie de le mettre dans la corbeille  ! ). Il ajoute ensuite les données au tout nouveau fichier approuve.txt. C’est OK ! La manipulation des fichiers peut être délicate. Si vous rencontrez des difficultés au début, il est facile de

se

sentir

frustré.

Voici

donc

quelques

expériences pour vous mettre sur la bonne voie.

Exécutez le projet de Barry

Je suppose que vous avez bien suivi les instructions données au début de ce livre pour télécharger et installer

les

exemples

développés

dans

les

différents chapitres. Vérifiez que le projet  1302  contient bien son propre fichier rawData.txt. Exécutez-le, puis vérifiez dans l’Explorateur de projets d’Eclipse que le code a bien créé un fichier appelé cookedData.txt.

Où est mon fichier ? Créez un projet Eclipse contenant le code suivant : import import import import

java.util.Scanner; java.io.File; java.io.FileNotFoundException; java.io.PrintStream;

class ReadAndWrite { public static void main(String args[]) throws FileNotFoundException { Scanner diskScanner = new Scanner(new File("data.txt")); PrintStream diskWriter = new PrintStream("data.txt");

diskWriter.println("Bonjour");

System.out.println(diskScanner.next()); diskScanner.close(); diskWriter.close(); } } Lorsque vous exécutez ce code, vous voyez un message d’erreur dans la vue Console d’Eclipse. Pourquoi ?

Écrire et ensuite lire Modifiez le code de l’expérience ci-dessus, (Où est mon

fichier  ?)

de

sorte

que

la

déclaration

PrintStream diskWriter précède la déclaration Scanner diskScanner. Lorsque vous exécutez le code, le mot Bonjour devrait apparaître dans la vue Console d’Eclipse. Vérifiez ensuite que votre projet Eclipse contient un fichier nommé data.txt.

Enregistrer des nombres aléatoires dans un fichier

Créez un programme qui écrit dix nombres générés au hasard dans un fichier disque. Après avoir écrit ces nombres, le programme lit le contenu du fichier et l’affiche dans la vue Console d’Eclipse.

Chapitre 14

Des boucles dans les boucles DANS CE CHAPITRE : » Stratégies en boucle » Diagnostiquer les problèmes de boucles » Créer des boucles imbriquées

S précisément sur la collection « Pour les Nuls » ,

i vous travaillez chez First Interactive, et plus

ne lisez pas ce qui suit. Je vais y révéler un important secret  : comment écrire un ouvrage à succès dans cette magnifique collection. Voici le processus à suivre : » Écrivez plusieurs mots à la suite pour former une phrase. Répétez cela plusieurs fois pour obtenir un paragraphe. Répétez ce qui suit pour former un paragraphe : Répétez ce qui suit pour former

une phrase : Écrivez un mot. » Répétez les instructions précédentes afin d’obtenir une section. Créez plusieurs sections pour obtenir un chapitre, puis plusieurs chapitres. Répétez ce qui suit pour écrire un best-seller Pour les nuls : Répétez ce qui suit pour former un chapitre : Répétez ce qui suit pour former une section : Répétez ce qui suit pour former un paragraphe : Répétez ce qui suit pour former une phrase : Écrivez un mot. En résumé, un best-seller, c’est une boucle dans une boucle dans une boucle dans une boucle dans une boucle. C’est bien clair pour tout le monde ? Dans le monde des ordinateurs, ce type de situation se produit tout le temps. En règle générale, les boucles à cinq niveaux (ou plus) se dissimulent derrière des appels de méthodes. Mais des boucles dans des boucles (deux niveaux) sont le pain

quotidien des programmeurs. Ce chapitre vous explique donc comment y arriver. Et c’est quelque chose de très utile. Maintenant, ami éditeur, tu peux reprendre ta lecture pour devenir toi aussi programmeur en Java.

Revisiter un vieux code Dans

le

Chapitre 

12,

le

programme

du

Listing 12.5 permettait d’extraire un nom dans une adresse de messagerie. Par exemple, ce programme lisait [email protected] au clavier, et il écrivait John sur l’écran. D’accord, dans ce livre, j’ai déjà invoqué quelques explications un peu boiteuses pour justifier mes exemples, mais, là, on atteint des sommets  ! Pourquoi irait-on taper une adresse de messagerie au clavier juste pour afficher le nom, dont tout le monde sait qu’il se trouve devant le

caractère @  ? Il doit bien y avoir une meilleure utilisation de ce type de code. C’est

évident.

L’administratrice

réseau

de

BurdBrain.com a une liste contenant les adresses de messagerie des 10 000 employé(e)s de l’entreprise. Plus précisément, elle a sur son disque dur un fichier appelé email.txt

où sont enregistrées

toutes ces adresses. Eh oui, 10  000  adresses dans un même fichier, chacune occupant sa propre ligne, comme sur la Figure 14.1. Le logiciel de messagerie de l’entreprise a une fonction intéressante. Pour envoyer un courrier en interne, vous n’avez pas besoin de taper les adresses en entier. Par exemple, pour contacter John, vous pouvez entrer simplement John, au lieu de

[email protected]

(la

partie

@BurdBrain.com est ce que l’on appelle le nom d’hôte).

FIGURE

14.1

Une liste d’adresses de messagerie.

FIGURE

14.2

Les noms des utilisateurs extraits de la liste des adresses

de messagerie.

L’administratrice réseau de la société souhaite filtrer le contenu de son fichier email.txt. Elle veut un nouveau fichier, appelé par exemple usernames.txt, qui contienne uniquement les

noms des utilisateurs, sans le nom d’hôte, comme sur la Figure 14.2.

Retravailler du code existant Pour résoudre le problème de notre administratrice, nous devons modifier le code du Listing 12.5. Cette nouvelle version lit une adresse de messagerie dans un fichier du disque, et elle écrit le nom de l’utilisateur dans un autre fichier. C’est ce que propose le Listing 14.1. LISTING

14.1 D’un fichier à un autre.

import import import import

java.util.Scanner; java.io.File; java.io.FileNotFoundException; java.io.PrintStream;

class ListOneUsername { public static void main(String args[]) throws FileNotFoundException { Scanner diskScanner = new Scanner(new File("email.txt"));

PrintStream diskWriter = new PrintStream("usernames.txt"); char symbol; symbol = diskScanner.findWithinHorizon(".",0).char At(0); while (symbol != '@') { diskWriter.print(symbol); symbol = diskScanner.findWithinHorizon(".",0).char At(0); } diskWriter.println(); diskScanner.close(); diskWriter.close(); } } Ce listing fait pratiquement la même chose. La seule

et

principale

différence,

c’est

qu’il

ne

demande aucune interaction avec l’utilisateur. Tout se passe sur le disque dur.

Exécuter le code Voyons comment exécuter le code du Listing 14.1 : 1. Créez un fichier appelé email.txt dans le dossier de votre projet Eclipse. Placez une seule adresse dans ce fichier. N’importe quelle adresse convient, du moment où elle contient un signe @. 2. Placez le fichier ListOneUserName.java (le code du Listing 14.1) dans le sous-dossier src de votre projet. 3. Exécutez le code du Listing 14.1. Vous n’allez strictement rien voir dans la vue Console d’Eclipse (du moins si vous n’avez pas fait d’erreur). Quelle pitié ! 4. Visualisez le contenu du fichier usernames.txt. Si le fichier email.txt contient par exemple [email protected], alors usernames.txt devrait contenir John. Pour plus de détails sur ces étapes, reportez-vous dans le Chapitre  13  aux explications données à propos des Listings 13.2, 13.3 et 13.4.

Créer du code utile La section précédente décrit le problème rencontré par une administratrice réseau : créer un fichier de noms d’utilisateurs à partir d’un autre fichier rempli d’adresses de messagerie. Le code du Listing  14.1  résout une partie de ce problème  : il extrait le nom d’une unique adresse e-mail. C’est un bon point de départ, mais il n’y a pas de quoi mobiliser un ordinateur, une maison d’édition et une myriade de libraires pour y arriver. Un morceau de papier et un stylo, et le tour est joué ! Ne laissons donc pas notre administratrice réseau languir plus longtemps. Dans cette section, vous allez développer un programme capable de traiter des dizaines, des centaines et même des milliers d’adresses de messagerie à partir d’un fichier de votre disque dur. Vous avez tout d’abord besoin d’une stratégie pour réaliser ce programme. Prenez les instructions du Listing  14.1, et exécutez-les de manière répétée. Mieux encore, laissez-les le faire toutes seules. Heureusement, vous savez déjà quelle est la bonne réponse  : une boucle (le Chapitre  12  présente les notions de base à connaître sur les boucles).

La stratégie à mettre en œuvre est finalement assez simple  : prendre les instructions du Listing 14.1  et les insérer à l’intérieur d’une boucle : while (on n’est pas à la fin du fichier email.txt) { Exécuter les instructions du Listing 14.1 } Si vous revenez au Listing 14.1, vous constatez qu’il contient déjà une boucle while. Notre stratégie nécessite donc à placer une boucle dans une autre : while (on n’est pas à la fin du fichier email.txt) { // Blah-blah while (symbol != '@') { // Blah-blah-blah } // Blah-blah-blah-blah } Dans une telle situation, on parle de boucles imbriquées. L’ancienne boucle (celle qui a pour condition symbol ! = '@') est appelée la boucle intérieure. La nouvelle (ce n’est pas la fin du

fichier

email.txt)

est

appelée

la

boucle

extérieure.

Tester la fin d’un fichier Tout ce dont vous avez besoin maintenant, c’est d’une méthode pour tester la condition dans la boucle extérieure. Comment savoir si la fin du fichier email.txt est atteinte ? La réponse réside dans la classe Scanner de Java. Cette classe possède une méthode hasNext

qui

répond par vrai ou par faux à la question suivante : Est-ce qu’il y a quelque chose à lire dans email.txt (en plus de ce qui a déjà été lu) ? Si les appels du programme à findWithinHorizon n’ont pas déjà avalé tous les caractères du fichier email.txt, la valeur de diskScanner.hasNext() est true (vrai). Pour réitérer la boucle tant que vous n’avez pas atteint la fin du fichier email.txt, vous agissez ainsi : while (diskScanner.hasNext()) { Exécuter les instructions du Listing 14.1 }

Le Listing  14.2  montre la première réalisation de cette stratégie. LISTING

14.2 Combinaison mécanique de deux

boucles. /* * Ce code ne marche PAS * (mais vous apprenez de vos erreurs). */ import import import import

java.util.Scanner; java.io.File; java.io.FileNotFoundException; java.io.PrintStream;

class ListAllUsernames { public static void main(String args[]) throws FileNotFoundException { Scanner diskScanner = new Scanner(new File("email.txt")); PrintStream diskWriter = new PrintStream("usernames.txt"); char symbol;

while (diskScanner.hasNext()) { symbol = diskScanner.findWithinHorizon(".",0) .charAt(0); while (symbol != '@') { diskWriter.print(symbol); symbol = diskScanner.findWithinHorizon(".",0) .charAt(0); } diskWriter.println(); } diskScanner.close(); diskWriter.close(); } } Lorsque vous exécutez ce code, vous obtenez le message désappointant illustré sur la Figure 14.3.

FIGURE 14.3

Vous avez fait une gaffe.

Vous vous sentez comment dans la peau d’un ordinateur ? Qu’est-ce

qui

ne

va

pas

avec

le

code

du

Listing  14.2  ? Pour le découvrir, j’essaie de me mettre à la place de l’ordinateur. «  Si j’étais un ordinateur, je ferais quoi quand j’exécute le code du Listing 14.2 ? » Les premières choses que je devrais faire sont illustrées sur la Figure 14.4. Je lirais la lettre J de John, puis la lettre o, toujours dans John.

FIGURE 14.4

Petit jeu de rôle avec l’ordinateur.

N’oubliez pas que les ordinateurs pensent en anglais, mais cela ne devrait pas outrepasser vos souvenirs d’école. Après quelques passages dans la boucle intérieure, j’atteins

le

signe

[email protected].

dans

@ C’est

ce

que

l’adresse décrit

la

Figure 14.5.

FIGURE 14.5

On arrive à la fin du nom de l’utilisateur.

Trouver le signe @

me fait quitter la boucle

intérieure pour remonter à la boucle extérieure, comme le montre la Figure 14.6.

FIGURE 14.6

Quitter la boucle intérieure.

Donc je lis la lettre B de BurdBrain, et je navigue vers la boucle extérieure. Mais soudain (quelle horreur  ! ), je m’aperçois que je dois écrire cette lettre B dans le fichier usernames.txt (voir la Figure 14.7).

FIGURE 14.7

L’erreur de ma vie.

Voici où se trouve l’erreur ! Je ne veux bien sûr pas écrire

le

nom

d’hôte

dans

mon

fichier

usernames.txt. Lorsque l’ordinateur rencontre le

signe @, il devrait sauter tout le reste de l’adresse de messagerie de John. Arrivé là, vous avez deux possibilités. Ou bien vous passez directement au code corrigé du Listing 14.3, ou bien vous continuez votre lecture afin d’en apprendre plus sur le message d’erreur de la Figure 14.3. Moi, je choisis la seconde option.

Pourquoi l’ordinateur dépasse accidentellement la fin du fichier ? Ah  ! Vous vous demandez d’où vient le méchant message d’erreur de la Figure 14.3 ? Je me suis mis dans la peau de l’ordinateur pour m’aider à comprendre ce qui n’allait pas. Repartons de la Figure 14.7. En réalité, je ne devrais pas traiter la première lettre B (le début du nom d’hôte) dans la boucle intérieure. Malheureusement, c’est ce que j’ai fait. Donc, je continue l’exécution. Lorsque j’arrive à la dernière adresse de messagerie, je lis le m

de

BurdBrain.com, et je reviens au test sur le signe @, comme l’illustre la Figure 14.8.

FIGURE 14.8

La dernière étape du voyage.

Maintenant, j’ai une autre difficulté. Ce dernier m n’est certainement pas un signe @. Donc je retourne dans la boucle intérieure, et j’essaie de lire un autre caractère (voir la Figure  14.9). Mais le fichier email.txt n’en contient plus, et par conséquent Java envoie un message d’erreur à l’écran de l’ordinateur

(c’est

le

message

NullPointerException de la Figure 14.3). Que veut dire ce NullPointerException

? Le

fichier email.txt n’a plus de caractères, et donc l’appel à findWithinHorizon(".",0) ne fait que renvoyer du vide (il n’y a plus rien à trouver). En Java, une manière plus précise de décrire ce vide est le mot null. L’appel à findWithinHorizon(".",0) est null, et donc tenter de pointer vers un caractère via (charAt(0))

est une tâche sans

avenir. Très poliment, Java le signale en affichant le message NullPointerException.

FIGURE

14.9

Quand on essaie de dépasser la fin d’un fichier…

Résoudre le problème Le Listing  14.3  propose une solution au problème décrit

ci-dessus.

Ce

code

est

pratiquement

identique à celui du Listing 14.2. La seule différence est l’appel supplémentaire à nextLine. Lorsque l’ordinateur

atteint

un

signe

@,

cet

appel

à

nextLine avale le reste de la ligne courante sans le tester (en fait, il le lit, mais ne l’enregistre pas). Cette idée fonctionne, car chaque adresse de messagerie se trouve sur une ligne différente. Après avoir gobé d’un coup @BurdBrain.com, l’ordinateur se déplace gracieusement vers la ligne de texte suivante.

LISTING

14.3 C’est bien mieux !

/* * Ce code est correct ! ! */ import import import import

java.util.Scanner; java.io.File; java.io.FileNotFoundException; java.io.PrintStream;

class ListAllUsernames { public static void main(String args[]) throws FileNotFoundException { Scanner diskScanner = new Scanner(new File("email.txt")); PrintStream diskWriter = new PrintStream("usernames.txt"); char symbol; while (diskScanner.hasNext()) { symbol = diskScanner.findWithinHorizon(".",0) .charAt(0);

while (symbol != '@') { diskWriter.print(symbol); symbol = diskScanner.findWithinHorizon(".",0) .charAt(0); } diskScanner.nextLine(); diskWriter.println(); } diskScanner.close(); diskWriter.close(); } } Pour exécuter le code du Listing  14.3, vous avez besoin d’un fichier email.txt, comme celui qui est proposé sur la Figure  14.1. Dans votre fichier email.txt,

saisissez

plusieurs

adresses

de

messagerie. N’importe quelle adresse de ce type peut convenir, dès lors qu’elle contient le signe @ et que chacune occupe sa propre ligne. Sauvegardez ce fichier dans le dossier de votre projet, ainsi que ListAllUsernames. java (le code du Listing 14.3). Pour plus de détails, sur cette manipulation,

reportez-vous dans le Chapitre 13  aux explications qui accompagnent les Listings 13.2, 13.3 et 13.4. Avec le Listing  14.3, vous avez atteint un palier important. Vous avez analysé un délicat problème et trouvé une solution complète et fonctionnelle. Vos outils ont été une réflexion sur les stratégies possibles, et une incursion dans la peau de l’ordinateur. Plus vous avancerez, et mieux vous serez capable d’employer ces outils pour résoudre des problèmes de plus en plus difficiles. Rien n’est plus difficile pour les programmeurs débutants que de créer des boucles imbriquées. C’est pourquoi j’aborde ces techniques dans ce chapitre, et dans les deux chapitres suivants. On pourrait dire que je boucle mon traitement des boucles de programmation. Essayez d’écrire le code que je suggère dans les paragraphes suivants. N’ayez pas peur de faire beaucoup

d’erreurs.

Si

vous

êtes

bloqué,

ralentissez, prenez du recul, et réfléchissez à ce que l’ordinateur fera lorsqu’il suivra les instructions à la lettre. Les solutions se trouvent sur ma page Web, à l’adresse www.allmycode.com/Be-ginProg. Mais ne

sautez pas dessus tant que vous n’avez pas expérimenté beaucoup d’idées différentes. Suivez cette formule éprouvée : Écrivez du code ; Éxécutez votre code ; Tant que (votre programme ne fonctionne pas correctement) { Parcourez votre code, une instruction après l’autre, en notant les valeurs des variables et les sorties de l’ordinateur, comme Java suit vos instructions exactement comme elles sont écrites ; Dans l’exécution pas à pas des instructions, notez l’endroit où Java fait quelque chose que vous ne voulez pas qu’il fasse ; Demandez-vous comment vous pourriez changer les instructions pour que Java puisse faire ce que vous voulez qu’il fasse ; Modifiez les instructions de votre code ; Éxécutez à nouveau votre code ; }

Fin de la route

Un fichier nommé input.txt

ne contient que

quatre caractères : Java Quelle est la sortie obtenue lorsque vous exécutez le code suivant ? import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Main { public static void main(String[] args) throws FileNotFoundException { Scanner diskScanner = new Scanner(new File("input.txt")); while (diskScanner.hasNext()) { char symbol = diskScanner.findWithinHorizon(".", 0).charAt(0); System.out.print(Character.toUpperCase(sy mbol)); } diskScanner.close();

} }

Sur la piste des étoiles Dans la section « Vous vous sentez comment dans la peau d’un ordinateur  ?  » de ce chapitre, j’examine chaque ligne du code d’un programme et je me demande ce que fait l’ordinateur quand il exécute cette ligne. Opérez de même avec le programme suivant : import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; class ReadStars { public static void main(String args[]) throws FileNotFoundException { Scanner diskScanner = new Scanner(new File("input.txt")); char symbol; while (diskScanner.hasNext()) { symbol =

diskScanner.findWithinHorizon(".", 0).charAt(0); while (symbol == '*') { System.out.print(symbol); symbol = diskScanner.findWithinHorizon(".", 0).charAt(0); }

System.out.println(); } diskScanner.close(); } }

Un bouillon de boucles Faites

un

tableau

pour

garder

la

trace

des

changements des valeurs de i et de j au fur et à mesure que Java exécute le code suivant : int i = 5; int j; while (i > 0) { System.out.println(i);

i--; j = 3; while (j > 0) { System.out.print(j); j--; } System.out.println(); } D’après les valeurs de votre tableau, quel sera le résultat affiché par le code ? Exécutez ce code dans Eclipse pour savoir si votre prédiction est correcte.

Un peu de changement… Modifiez le code de l’expérience précédente ( « Un bouillon de boucles  » ) de sorte que la sortie n’ait pas de lignes contenant la séquence de chiffres 321, mais l’inverse, c’est-à-dire 123.

Des étoiles plein la vue Cette expérience se divise en deux parties. La première ne nécessite qu’une seule boucle  ; la seconde nécessite des boucles imbriquées. » Écrire un programme qui demande à l’utilisateur combien d’étoiles il doit afficher. Lorsque l’utilisateur saisit un nombre, le programme

affiche la quantité d’étoiles demandée. Voici un exemple d’exécution : Combien d’étoiles ? 5 ***** » Écrire un programme qui demande de manière répétitive si l’utilisateur veut voir une rangée d’étoiles. Tant que l’utilisateur répond par la lettre o, le programme reproduit le comportement précédent. En d’autres termes, il demande à l’utilisateur un nombre d’étoiles, puis il affiche la quantité d’étoiles demandée. Dès que l’utilisateur répond par la lettre n, le programme s’arrête. Voici un exemple d’exécution du programme : Voulez-vous une rangée d’étoiles ? (o/n) o Combien d’étoiles ? 5 ***** Voulez-vous une rangée d’étoiles ? (o/n) o Combien d’étoiles ? 2 ** Voulez-vous une rangée d’étoiles ? (o/n) o Combien d’étoiles ? 9

******** Voulez-vous une rangée d’étoiles ? (o/n) n Pour créer ce programme, prenez le code que vous avez écrit dans la première partie de cet exercice et insérez-le dans une seconde boucle.

À propos de rien Sur la Figure 14.3, l’exécution d’un programme Java lance une exception NullPointerException. Ces messages NullPointerException ne sont jamais amusants, mais plus vous en rencontrez, et moins ils deviennent effrayants. Pour

vous

aider

désensibilisation, intentionnellement.

à

faire

une

cure

générez

un

tel

Tapez

les

deux

de

message lignes

suivantes, l’une après l’autre, dans la fenêtre de JShell : String name = null; System.out.println(name.length());

Chapitre 15

Action !

DANS CE CHAPITRE : » Créer des actions répétitives » Améliorer les techniques d’imbrication » Obtenir une réponse valide de l’utilisateur » Parcourir des valeurs énumérées

m’en souviens comme si c’était hier. De cette J esensation de terreur que je ressentais lorsqu’on allait chez la tante Edna. C’était une vieille dame, et ses intentions étaient certainement bonnes. Mais aller chez elle était toujours une véritable agonie. D’abord, on s’asseyait dans son salon, et les adultes parlaient de choses et d’autres. Pour ce que j’en comprenais, tout se passait bien. Après cela, mon père se mettait à aider Edna pour ses factures. C’était assez amusant à regarder, car la tante Edna avait hérité d’une maladie quasiment génétique dans la famille. Comme moi et la plupart de mes

ancêtres, elle était incapable de gérer ses papiers. C’est comme si ces formalités administratives produisaient

des

substances

allergènes

qui

irritaient la peau de tante Edna. Au bout de dix minutes, mon père finissait par trouver une erreur ou quelque chose dans la comptabilité qui attirait son attention. Il interrogeait Edna, qui se contentait de hausser les épaules. Mon père s’agitait en essayant de résoudre le problème, tandis que la tante Edna roulait des yeux tout en souriant avec le contentement

de

l’ignorance.

C’était

un

bel

amusement. Quand ces questions étaient réglées, on s’asseyait pour manger. Et c’est là que la terreur commençait. Le déjeuner était insupportable. Tante Edna croyait au Fletcherisme  –  un mouvement dans lequel les adeptes mâchaient cent fois chaque bouchée de nourriture. Les sectateurs les plus convaincus utilisaient même un tableau, avec un nombre différent de mastications pour chaque type de nourriture. Le nombre minimal était de trentedeux fois, une par dent. Mes parents trouvaient tout cela stupide, mais ils respectaient tante Edna et ils ne voulaient pas la mécontenter. De mon côté, je croyais exploser de

monotonie. Chaque plat était interminable. Chaque bouchée était un vrai supplice. Je peux encore me souvenir

de

mon

mantra,

les

mots

que

je

prononçais intérieurement pour tenir le coup : J’ai mâché 0 fois jusqu’ici Est-ce que j’ai mâché 100 fois ? Si non, alors Mâcher ! Ajouter 1 au nombre de fois que j’ai mâché. Retourner à la phrase « Est-ce que j’ai mâché » pour trouver si j’ai terminé.

Répéter des instructions un certain nombre de fois (l’instruction Java for) La vie est remplie d’exemples de boucles de comptage. Et un programme d’ordinateur est une sorte d’imitation de la vie (ou l’inverse  ?). Il est courant de dire à un ordinateur qu’il doit imprimer trois lignes, traiter dix comptes, appeler un million de numéros de téléphone, et ainsi de suite. Comme ce

genre

de

comptage

est

si

fréquent

en

programmation, les gens qui ont créé les langages

de programmation ont développé des instructions particulières rien que pour des boucles de ce type. En Java, une instruction qui répète quelque chose un

certain

nombre

de

fois

est

appelé

une

instruction for. Le Listing  15.1  montre un exemple d’utilisation de cette instruction for. LISTING

15.1 La revanche des Fletchériens.

import static java.lang.System.out; class AuntEdnaSettlesForTen { public static void main(String args[]) { for (int count = 0; count < 10; count++) { out.print("J'ai mâché "); out.print(count); out.println(" fois."); } out.println("10 fois ! Hourra !"); out.println("Je peux avaler !"); } }

La Figure  15.1  vous montre ce que vous obtenez lorsque vous exécutez ce programme :

FIGURE 15.1

Mâcher dix fois.

» L’instruction for du Listing 15.1 commence par initialiser la variable count avec la valeur 0. » Elle effectue ensuite un test pour déterminer si la valeur de count est bien plus petite que 10 (à ce stade, c’est certainement vrai). » L’instruction for se lance sur le grand plongeoir et elle exécute les instructions d’affichage qui se trouvent entre les accolades. Au tout début, elle affiche donc tout simplement J’ai mâché 0 fois.

» Elle exécute ensuite la dernière instruction qu’elle rencontre dans les parenthèses, count++. Ceci ajoute 1 à la valeur de count. La première itération se termine. Bien entendu, le travail de mastication n’est pas fini. » Avec count maintenant égal à 1, l’instruction for reprend son bâton de pèlerin pour savoir si count est toujours inférieur à 10. Effectivement, 1 est plus petit que 10. » Comme le test est positif, l’instruction for exécute ce que contiennent les accolades. Elle affiche donc J’ai mâché 1 fois. » Son devoir étant fait, l’instruction for incrémente à nouveau count (avec count++). Notre variable vaut donc 2. Et ainsi de suite. La procédure se répète jusqu’à ce que, au bout de dix itérations, count finisse par atteindre

le

Saint

Graal,

en

l’occurrence

la

valeur  10. À cet instant, le test qui compare count à 10 échoue, et l’exécution de la boucle se termine. L’ordinateur saute alors sur l’instruction qui suit immédiatement la boucle for. Il affiche donc J’ai

mâché 10 fois ! Hourra ! Je peux avaler ! Tout ce processus est illustré sur la Figure 15.2.

FIGURE 15.2

L’action de la boucle for du Listing 15.1.

Anatomie d’une instruction for Une instruction for typique se présente ainsi : for (Initialisation; Condition; modification) {

Instructions } Après le mot for, vous voyez trois choses entre les parenthèses : une initialisation, une condition, et une modification. Chacun de ces éléments joue sa propre partition : » Initialisation : Celle-ci est exécutée une seule fois, lorsque le programme atteint l’instruction for. Elle permet de donner une valeur de départ au compteur de la boucle. » Condition : La condition est testée plusieurs fois (au départ de chaque itération). Elle permet de savoir où en est le compteur. » Modification : Elle change la valeur du compteur (sans quoi, on rentrerait dans une boucle infinie), et elle est exécutée à la fin de chaque itération. Si cela peut vous aider, essayez de transcrire la boucle sous la forme d’une sorte de pseudo-texte : // Ceci n’est PAS du vrai code int count = 0 for count < 0 { out.print("J’ai mâché "); out.print(count); out.println(" time(s).");

count++; } Vous ne pouvez pas écrire un véritable code de cette manière (le compilateur le jetterait immédiatement dans la corbeille). Pour autant, c’est dans cet ordre que les instructions for sont exécutées. La première ligne d’une instruction for (le mot for

suivi

d’une

certaine

séquence

entre

parenthèses) n’est pas une instruction en soi. C’est pourquoi vous ne la faites pas suivre d’un pointvirgule. Si vous faisiez ce genre d’erreur : // NE FAITES PAS CECI : for (int count = 0; count < 10; count++) ; { vous feriez généralement entrer l’ordinateur dans une boucle sans fin. Ici, l’ordinateur se contenterait d’incrémenter la variable count jusqu’à  9. Après quoi,

il

s’occuperait

immédiatement (l’instruction for

après

de la

ce

qui

première

se

trouve accolade

se terminerait en effet juste

après le point-virgule, et donc ce qui suit celui-ci ne ferait pas partie de la boucle).

Initialiser une boucle for Regardez la première ligne de la boucle for sur le Listing 15.1, et notez la déclaration int count = 0 qu’elle contient. Il y a ici quelque chose de nouveau. Lorsque vous créez une telle boucle, vous pouvez déclarer une variable (telle que count) afin de l’initialiser. Si vous procédez de cette manière, vous ne pouvez pas déclarer cette variable en dehors de la boucle. Essayez Listing 

par 15.1 

exemple pour

placer

de

modifier une

le

instruction

out.println(count) après la fin de la boucle : // Ce code ne se compile PAS for ( int count = 0 ; count < 10; count++) { out.print("J’ai mâché "); out.print(count); out.println(" fois."); } out.print( count ); // La variable count n’existe plus. Avec cette référence supplémentaire à la variable count, le compilateur vous renvoie un message d’erreur (voir la Figure  15.3). Si vous n’êtes pas

familiarisé avec les instructions for, ce message peut vous surprendre. Il indique en effet que count ne peut être résolu en tant que variable. Bon. Mais la variable count est bien déclarée dans l’initialisation de la boucle for, non  ? Oui, mais à l’extérieur de cette boucle, la variable count n’existe pas. Pour utiliser une variable en dehors d’une boucle for, vous devez donc la déclarer à l’extérieur de celle-ci.

Et

vous

pouvez

même

le

faire

en

conservant le nom du compteur de la boucle for. Le Listing 15.2 vous en propose un exemple. LISTING

15.2 Utiliser une variable déclarée en

dehors de la boucle. import static java.lang.System.out; class AuntEdnaDoesItAgain { public static void main(String args[]) { int count; for (count = 0; count < 10; count++) { out.print("J'ai mâché ");

out.print(count); out.println(" fois."); } out.print(count); out.println(" fois ! Hourra !"); out.println("Je peux avaler !"); } }

FIGURE 15.3 pas.

La variable count ? Quelle variable count ? Je ne la vois

L’exécution

du

exactement

le

code

du

même

Listing  15.2  donne résultat

qu’avec

le

Listing  15.1  (reportez-vous à la Figure  15.1). Notez cependant les mots count = 0 dans le Listing 15.2. Du fait que count est déclaré avant l’instruction for, vous n’avez plus à le faire dans celle-ci. J’ai essayé de voir ce que donnerait une double déclaration, comme dans le code suivant : // Ceci ne marche PAS : int count; for ( int count = 0; count < 10; count++) { ...etc. Immédiatement, Eclipse me répond : Variable locale count en double

SOUPLES, LES BOUCLES ! Si vous étiez naufragé sur une île déserte avec une seule sorte de boucle, laquelle choisiriez-vous  ? La réponse est  : vous pouvez survivre avec n’importe laquelle. Le choix entre while et for est une question de style de programmation et d’efficacité. Pas de nécessité. Tout ce qui peut être fait avec une boucle for peut aussi être réalisé avec une boucle while. Considérez par exemple la boucle for du Listing  15.1. Voici comment vous pourriez arriver au même résultat avec une boucle while : int count = 0; while (count < 10) { out.print(«J’ai mâché «); out.print(count); out.println(« fois.»); count++; } Dans la boucle while, vous avez une instruction explicite pour déclarer, initialiser et incrémenter le compteur, count. Cela vaut bien entendu dans le sens inverse. Tout ce que vous pouvez faire avec une boucle while peut aussi être réalisé avec une boucle for. Mais, dans certains cas, cela

semble peu naturel, voire tiré par les cheveux. Regardons par exemple la boucle while du Listing 12.2 : while (total < 21) { card = myRandom.nextInt(10) + 1; total += card; System.out.print(card); System.out.print(“ “); System.out.println(total); } Transformer

ce

code

en

une

boucle

for

a

pour

conséquence de ne rien mettre dans une bonne partie des parenthèses : for ( ; total < 21 ; ) { card = myRandom.nextInt(10) + 1; total += card; System.out.print(card); System.out.print(« «); System.out.println(total); } Cette boucle a une condition, mais aucune initialisation ou modification du compteur count, du moins à l’intérieur des parenthèses. C’est parfaitement correct. Sans initialisation, il ne se produit rien de particulier lorsque l’ordinateur entre

dans la boucle for. Et sans modification du compteur, rien de spécial ne se produit à la fin de chaque itération. C’est étrange, mais cela fonctionne. En règle générale, lorsque vous écrivez une boucle for, vous comptez combien de fois quelque chose doit être répété. Mais, en vérité, vous pouvez réaliser pratiquement n’importe quel type de répétition avec une instruction for.

Imbriquer les boucles Voici votre nouvelle mission, si vous l’acceptez. Vous gérez un grand hôtel. Le prochain chapitre vous expliquera tout ce que vous avez besoin de savoir sur ce travail. Mais, dans cette section, vous allez faire vos premières classes. Votre hôtel a neuf étages, et chaque étage a vingt chambres. C’est vraiment un grand hôtel  ! Par un après-midi ensoleillé, quelqu’un vous donne une clé USB contenant un fichier rempli de nombres. Vous copiez ce fichier hotelData sur votre disque dur, puis vous l’affichez dans l’éditeur d’Eclipse. Ce que vous voyez est illustré sur la Figure 15.4.

FIGURE 15.4

Un fichier contenant des données sur l’occupation d’un

hôtel.

Ce fichier vous donne le nombre de résidents dans chaque chambre. Par exemple, vous voyez  2 1 2 au

début

du

fichier.

Ceci

signifie

que

la

chambre  1  du premier étage a deux clients, la chambre 2 un seul, et la chambre 3 également deux clients. Vous continuez à lire, et vous remarquez un peu plus loin la série  0 2 2. Au second étage, la chambre 



est

libre,

tandis

que

les

chambres  2  et  3  sont occupées par deux clients. Et ainsi de suite jusqu’à la fin du fichier, qui vous indique

que

quatre

clients

occupent

la

chambre 20 du neuvième étage. Vous aimeriez afficher ces nombres d’une manière un peu plus ordonnée, comme sur la Figure  15.5. Vous vous précipitez donc sur votre clavier pour écrire un programme Java.

Dans ce genre de situation, vous commencez par vous demander combien de fois chaque instruction doit

être

exécutée

afin

de

décider

de

leur

emplacement dans le programme. Ici, vous avez neuf étages, soit neuf lignes dans le fichier, et chaque étage possède vingt chambres, soit vingt chiffres par ligne : for (chacun des 9 étages) for (chacune des 20 chambres d’un étage)

FIGURE 15.5

Un affichage plus lisible des données de la Figure 15.4.

lire un nombre dans le fichier et afficher ce nombre sur l’écran.

Votre programme va donc contenir une boucle for dans une autre boucle for, autrement dit des boucles for imbriquées. Remarquez maintenant comment chaque ligne débute sur la Figure 15.5. Vous voyez le mot Étage, suivi du numéro de celui-ci. Comme il y a neuf étages, l’instruction qui affiche ceci doit se trouver dans la boucle extérieure, juste avant le for (chacune des 20 chambres d’un étage). Nous obtenons donc ceci : for (chacun des 9 étages) afficher le mot Étage et le numéro de l’étage for (chacune des 20 chambres d’un étage) lire un nombre dans le fichier et afficher ce nombre sur l’écran. Vous êtes presque prêt à écrire le code. Mais il y a encore un détail qu’il est facile d’oublier (enfin, un détail que j’oublie toujours). Après qu’il ait affiché vingt nombres, le programme doit avancer à la ligne suivante. Cette action ne se produit que neuf fois lors de l’exécution, et toujours après l’affichage d’une série de vingt nombres :

for (chacun des 9 étages) afficher le mot Étage et le numéro de l’étage for (chacune des 20 chambres d’un étage) lire un nombre dans le fichier et afficher ce nombre sur l’écran, puis passer à la ligne suivante. Et voilà. C’est tout ce dont vous avez besoin. Le code

permettant

de

créer

l’affichage

de

Figure 15.5 est proposé sur le Listing 15.3. LISTING

15.3 Vous avez une chambre de libre ?

import import import import

java.util.Scanner; java.io.File; java.io.FileNotFoundException; static java.lang.System.out;

class DisplayHotelData { public static void main(String args[]) throws FileNotFoundException { Scanner diskScanner = new Scanner(new File("hotelData"));

la

for (int floor = 1; floor