Résumé

À travers la réalisation d’un forum de discussion et plus de 50 études de cas, cet ouvrage montre à tous les programmeurs comment exploiter la richesse de Java en mettant l’accent sur la fi abilité et l’évolutivité.

L’excellence didactique d’Emmanuel Puybaret (eteks.com) pour apprendre la programmation Java !

Cet ouvrage met à la portée de tous les développeurs les meilleures pratiques Java, depuis l’installation des outils de développement et la création d’un premier objet jusqu’à la programmation multitâche, en passant par l’accès aux bases de données, la conception d’interfaces utilisateur, la gestion de formulaires, de fi chiers, la maîtrise des subtilités objet…

L’intégralité des études de cas a été testée sous Linux, Windows et Mac OS X !
Téléchargez l’ensemble du code source à l’adresse www.editions-eyrolles.com

Au sommaire

Présentation des études de cas • Forum de discussion • Module de messagerie instantanée • Principes de base et installation de l’environnement • De l’utilité d’une démarche objet • Cycle de développement • Télécharger et installer Java sous Windows, Linux et Mac OS X • Création de classes • Pourquoi typer ? • Encapsulation • Créer ses propres classes • Organisation des fi chiers des classes • Package et import • Opérateurs et instructions de contrôle • Réutilisation des classes • Composition • Héritage • Polymorphisme • Classes de base • L’ancêtre Object • Gestion des dates • Tableaux • Collections • Généricité • Abstraction et interface • Gestion des erreurs avec les exceptions • Pile d’exécution • Intercepter avec try et catch • Déclencher avec throw • Exceptions contrôlées • Gestion des fi chiers • Flux de données • Filtres • XML et Java • DTD • Schéma XML • XSLT • SAX • DOM • JAXB • Connexion à une base de données avec JDBC • Installer MySQL • Programmer en SQL avec JDBC • Interfaces utilisateur avec Swing • Composants et conteneurs • Layouts • Gestion événementielle et listeners • Création d’applets • Serveurs web avec servlets/JSP/JavaBeans • HTTP et CGI • Servlets • Installer Tomcat • Application web • Balises JSP • JavaBeans • Interface utilisateur du forum • Scénario d’utilisation • Programmation des pages JSP du forum • Programmation multithread • Timer • Thread • Programmation du chat • Synchronisation • Annexes • Licences logicielles • Organisation des fi chiers du forum • Eclipse • Erreurs de compilation les plus fréquentes • Glossaire.

À qui s’adresse cet ouvrage

– À tout développeur venant d’autres langages (C, C++, C#, PHP, Python…) qui souhaite rapidement apprendre à programmer en Java ;

– Aux développeurs souhaitant des rappels en programmation objet par la pratique de Java ;

– Aux étudiants et leurs enseignants ayant besoin d’un support de cours dynamique et appliqué pour l’apprentissage du langage Java.

Biographie auteur

E. Puybaret

Ingénieur en informatique et aéronautique, Emmanuel Puybaret a plus de quinze ans d’expérience en programmation objet multiplateforme dans des domaines aussi variés que l’industrie, les télécoms, la banque et l’édition de logiciels. Consultant indépendant partagé entre développements et formations, il est l’auteur du site eteks.com consacré à Java, ainsi que des outils Open Source Sweet Home 3D, PJA Toolkit et Jeks.

www.editions-eyrolles.com

Bien programmer
en Java 7

Avec plus de 50 études de cas
et des comparaisons avec C++ et C#

Emmanuel Puybaret

ÉDITIONS EYROLLES
61, bd Saint-Germain
75240 Paris Cedex 05
www.editions-eyrolles.com

Cet ouvrage est la 4e édition, avec mise à jour, nouveau titre et nouvelle présentation,
de l’ouvrage d’Emmanuel Puybaret paru à l’origine sous le titre
Les Cahiers du programmeur Java 1.4 et 5 (ISBN 978-2-212-11916-9)

Attention : la version originale de cet ebook est en couleur, lire ce livre numérique sur un support de lecture noir et blanc peut en réduire la pertinence et la compréhension.

En application de la loi du 11 mars 1957, il est interdit de reproduire intégralement ou partiellement le présent ouvrage, sur quelque support que ce soit, sans l’autorisation de l’Éditeur ou du Centre Français d’exploitation du droit de copie, 20, rue des Grands Augustins, 75006 Paris.
© Groupe Eyrolles, 2012, ISBN : 978-2-212-12974-8

Ouvrage du même auteur

Cahier du programmeur Swing – L’étude de cas Sweethome 3D, E. Puybaret, Eyrolles 2007, 500 pages.

Avant-propos

Java est reconnu comme l’un des meilleurs langages de programmation objet. Suivant une démarche didactique progressive, cet ouvrage vous aidera à comprendre la modélisation objet telle qu’elle est appliquée en Java et dans sa bibliothèque. Chaque concept est abordé isolément et accompagné d’une application simple et aussi concrète que possible. Enfin, pour vous aider à percevoir l’environnement Java dans sa globalité, cet ouvrage met en œuvre la création d’un forum de discussion.

imagesConfiguration logicielle requise

Les études de cas présentées dans cet ouvrage peuvent être reproduites sur toute machine qui supporte Java 7 (ou une version ultérieure) et le système de gestion de bases de données MySQL, c’est-à-dire à peu près sur...

chapitre 1

Présentation des études de cas

Cet ouvrage décrit la création de différents types d’applications, depuis une simple application isolée mettant en pratique un concept Java, jusqu’au développement d’un forum de discussion détaillé sur plusieurs chapitres.

SOMMAIRE

imagesApplications isolées

imagesCarnet d’adresses

imagesCalcul de mensualités d’emprunt

imagesForum de discussion

imagesMessagerie instantanée (chat)

MOTS-CLÉS

images Application

images Java

images Base de données

images MySQL

images Tomcat

images Forum

images Chat

Applications isolées

Le tableau 1-1 donne la liste des applications isolées (définies sur une ou deux sections qui se suivent) les plus intéressantes de cet ouvrage. Celles-ci pourront servir de socle pour le développement de vos propres applications.

Tableau 1–1 Description des applications isolées

Titre de l’application | Chapitre | Description
Convertir un nombre en toutes lettres | 4 | Montre comment convertir en toutes lettres un nombre compris entre 0 et 99 en tenant compte des exceptions de la langue française.
Quelques calculs de probabilité classiques | 4 | Calcule quelques probabilités connues en appliquant les formules mathématiques du calcul combinatoire.
Calculer les intérêts d’un compte épargne | 5 | Montre comment organiser deux types de comptes bancaires, l’un simple et l’autre permettant de calculer des intérêts cumulés.
Ce que connaît la JVM de votre système | 6 | Affiche les informations que connaît un programme Java sur votre système et son

...

chapitre 2

Principes du langage et installation de l’environnement

Java intègre les concepts les plus intéressants des technologies informatiques récentes dans une plate-forme de développement riche et homogène. L’approche objet de ce langage, mais aussi sa portabilité et sa gratuité en font un des outils de programmation idéaux pour s’initier à la programmation objet.

SOMMAIRE

imagesComprendre la démarche objet

imagesVue d’ensemble sur l’architecture Java

imagesInstallation

MOTS-CLÉS

images Objets et classes

images JVM

images JDK

images javadoc

Programmer en Java : une démarche objet

Du binaire à l’objet, 50 ans d’évolution de la programmation

B.A.-BA Vocabulaire de la programmation objet

L’une des difficultés de la programmation en Java passe par l’utilisation des nombreux termes associés aux concepts de la programmation objet. Ces termes, décrits au fur et à mesure de cet ouvrage, sont repris dans le glossaire en annexe si vous voulez vous rafraîchir la mémoire en cas de besoin.

La programmation identifie les données d’une information et les traitements qui s’y appliquent, puis les codifie pour les rendre compréhensibles par un ordinateur. Le microprocesseur d’un ordinateur ne manipulant que des instructions et des données codées en binaire, différents langages de programmation ont été créés pour permettre aux programmeurs de coder des concepts plus humains que des 0 et des 1. Le texte d’un tel programme est traduit par un compilateur ou un interpréteur en instructions que le microprocesseur peut alors exécuter.

Figure 2–1 Compilation et exécution d’un programme

REGARD DU DÉVELOPPEUR Les atouts de Java

Mis au point par Sun Microsystems, Java est un langage de programmation utilisé dans de nombreux domaines. Son succès est dû à un ensemble de caractéristiques dont voici un aperçu :

• Langage de programmation objet et fortement typé : contraignants pendant le développement, l’approche objet et le typage fort du langage Java rendent plus robuste un programme Java dès sa conception.

• Syntaxe proche du C et C++ : en reprenant une grande partie de la syntaxe de ces deux langages, Java facilite la formation initiale des programmeurs qui les connaissent déjà.

• Gestion de la mémoire simplifiée : le ramasse-miettes (garbage collector en anglais) intégré à Java détecte automatiquement les objets inutilisés pour libérer la mémoire qu’ils occupent.

• Gestion des exceptions : Java l’intègre autant pour faciliter la mise au point des programmes (détection et localisation des bogues) que pour rendre un programme plus robuste.

• Multitâche : grâce aux threads, Java permet de programmer l’exécution simultanée de plusieurs traitements et la synchronisation des traitements qui partagent des informations.

• Système de sécurité : Java protège les informations sensibles de l’utilisateur et le système d’exploitation de sa machine en empêchant l’exécution des programmes conçus de façon malintentionnée (contre un virus par exemple).

• Bibliothèque très riche : la bibliothèque fournie en standard avec Java couvre de nombreux domaines (gestion de collections, accès aux bases de données, interface utilisateur graphique, accès aux fichiers et au réseau, utilisation d’objets distribués, XML…, sans compter toutes les extensions qui s’intègrent sans difficulté à Java !).

• Exécutable portable : comme l’exprime l’accroche Write Once Run Anywhere, un programme Java, une fois écrit et compilé, peut être exécuté sans modification sur tout système qui prend en charge Java.

• Gratuit : développement gratuit avec les commandes de bases Java, ou certains outils plus évolués, et exécution gratuite des programmes.

Les langages de programmation ont évolué pour permettre aux programmeurs d’utiliser des concepts de plus en plus proches de la réalité et du langage naturel. La programmation en assembleur a remplacé le codage en binaire des données par un codage en hexadécimal, et les instructions codées en binaire du microprocesseur par des instructions symboliques.

EXEMPLE

MOVE 02 R1

MOVE 10 R2

ADD R1 R2

Ces instructions écrites en assembleur Motorola 68000 placent la valeur 2 dans le registre R1, la valeur 16 (10 en hexadécimal) dans le registre R2, puis additionnent les valeurs de ces deux registres.

Assembleur et langage d’assemblage

On appelle assembleur le programme qui transforme en code binaire ou en exécutable un programme écrit en langage d’assemblage. Ce dernier se compose de mnémoniques (plus lisibles que le code binaire) représentant les instructions binaires d’un microprocesseur.

Un programme directement écrit en langage d’assemblage exploite de façon...

chapitre 3

Création de classes

Java permet de créer des classes robustes grâce à un typage fort et au procédé de l’encapsulation. À partir des classes et des objets créés dans ce chapitre, nous allons voir comment il convient de mettre en œuvre ces principes et d’organiser les fichiers d’un programme.

SOMMAIRE

imagesTyper

imagesEncapsuler

imagesCréer une classe et ses objets

imagesOrganiser les fichiers des classes

MOTS-CLÉS

images Type

images Encapsulation

images class

images this

images Constructeur

images javac

images import

Typer : pourquoi et comment ?

Il y a quatre catégories de données Java : les valeurs littérales (pour manipuler une valeur fixe comme 1 3.4 'a'), les variables locales (pour stocker des valeurs temporaires utilisées dans les calculs d’une méthode), les paramètres de méthode (pour paramétrer une méthode) et les champs (pour stocker les valeurs décrivant l’état d’un objet).

Chacune de ces données Java est dotée d’un type, soit primitif (numérique, caractère, booléen), soit objet. Le type d’une donnée est utilisé d’une part pour calculer la taille de son espace de stockage, et d’autre part pour déterminer les opérations qu’il est possible de lui appliquer avec les opérateurs Java, sans provoquer d’erreur de compilation ni d’exécution.

C++ Pas de unsigned, typedef et sizeof en Java

Le seul type entier non signé Java est le type char. Pour éviter toute confusion sur le type d’une variable, il n’existe aucun équivalent en Java des synonymes de type avec typedef. Comme tous les types primitifs ont une taille fixe en Java, l’opérateur sizeof n’existe pas.

Tableau 3–1 Types primitifs de Java

Type | Description
byte | entier signé sur 8 bits (valeurs de –128 à 127)
short | entier signé sur 16 bits (valeurs de –32 768 à 32 767)
int | entier signé sur 32 bits (valeurs de –2 147 483 648 à 2 147 483 647)
long | entier signé sur 64 bits (valeurs de –9 223 372 036 854 775 808 à 9 223 372 036 854 775 807)
float | décimal à virgule flottante sur 32 bits (valeurs de ± 10⁻⁴⁵ à ± 10³⁸ environ)
double | décimal à virgule flottante sur 64 bits (valeurs de ± 10⁻³²³ à ±10³⁰⁸ environ)
char | code Unicode sur 16 bits (peut être utilisé aussi comme entier non signé)
boolean | valeur booléenne (vrai ou fausse)

C++ Le type char Java est sur 16 bits

L’équivalent du type wchar_t du C++ est char en Java.

B.A.-BA Identificateur

En Java, un identificateur ne peut ni commencer par un chiffre ni être un mot-clé Java. Cela mis à part, il peut s’agir de n’importe quelle suite alphanumérique (lettres ou chiffres Unicode) associée à des caractères _ ou $.

Exemples : nom nombre $Nombre reseau_1 appeler getId

Dans le cas des variables, il faut les déclarer avant leur première utilisation, en écrivant le type de la variable suivi de son nom ou identificateur.

type identificateurVariable

À RETENIR Mots-clés Java

Chaque mot-clé Java a un sens prédéterminé et s’utilise avec une syntaxe particulière. Il est interdit de s’en servir comme identificateur pour éviter toute confusion de sens.

* assert est un mot-clé introduit avec Java 1.4. enum est un mot-clé introduit avec Java 5. goto et const sont des mots-clés réservés mais qui ne sont pas utilisés par Java.

Types de données objet et références

Les données de type objet relèvent d’une classe de la bibliothèque standard Java (par exemple java.lang.String, java.lang.Object…), d’une autre bibliothèque ou de votre propre programme.

Exemple

java.lang.String mot déclare la référence mot de type java.lang.String.

Une variable de type objet est appelée une référence. Soit une référence désigne un objet, soit elle est égale à null. Un objet peut être référencé par plusieurs variables.

C++ null Java ≈ NULL C++

L’équivalent du pointeur NULL du C++ est la référence null en Java.

C ++ Référence ≈ pointeur≈ adresse ¹ objet

La notion de pointeur ou d’adresse sur un objet du C++ est remplacée par la notion de référence en Java, proche de celle du C++, mais limitée aux variables qui désignent des objets alloués dynamiquement. Observez bien au passage que l’instruction java.lang.String mot; ne crée aucun objet en Java mais une référence sur un objet de classe java.lang.String.

Écrire une valeur littérale

Une valeur littérale représente une valeur fixe et se note différemment d’un type à un autre.

Type
Notation valeur littérale
Exemples

byte
short
Les valeurs littérales entières peuvent se noter de 3 façons (faire suivre le nombre d’un L pour une valeur de type long).

int
Suite de chiffres décimaux
3443 –1234567 10000000000L

long
Suite de chiffres hexadécimaux (base 16) précédée de 0x
0x2F 0X12ab 0xFFFFFFFFFFL

Suite de chiffres octaux (base 8) précédée de 0. Rarement utilisée, cette notation est signalée pour éviter que l’on ajoute 0 devant un entier par simple effet de style (ajouter plutôt des espaces).

Depuis Java 7, suite de chiffres binaires (base 2) précédée de 0b

0123 056

0b1110

float
double

Les valeurs littérales décimales se notent avec un point pour le séparateur décimal et la lettre E pour séparer la mantisse de l’exposant : 3.14E-5 = 3,14 10⁻⁵

Par défaut, toute valeur littérale numérique avec un point étant de type double, faire suivre le nombre d’un f pour indiquer qu’une valeur est de type float. Depuis Java 7, il est possible d’utiliser un caractère de soulignement _ comme séparateur dans une valeur littérale entière ou décimale pour en améliorer la lisibilité : 10_000.

10. 0.34 .4e12 3.14E-5 12.3f

3.141_593 10_000_000

char
Les valeurs littérales de type caractère se notent entre apostrophes (’).

Caractère du code ASCII
'a' '@' '9' '?'

Caractère du code Unicode : \u suivi des 4 chiffres hexadécimaux du code du caractère
'\u00e9' '\u20ac'

Caractères spéciaux les plus courants :
'\n' pour un retour à la ligne
'\t' pour une tabulation
'\"' pour le caractère "
'\'' pour le caractère '
'\\' pour le caractère \
'\n' '\t' '\"' '\'' '\\'

boolean
Les valeurs littérales booléennes sont true et false.
true false

java.lang.String
Les valeurs littérales de type texte ou chaîne de caractères se notent avec des caractères entre guillemets (").
"Bonjour" "\u00e9l\u00e9ment"

Autre type objet
La seule valeur littérale des références d’un autre type objet est null.

...

chapitre 4

Contrôle des traitements avec les opérateurs, boucles et branchements

Après avoir étudié comment organiser ses informations sous forme d’objets, ce chapitre expose comment programmer un traitement avec quelques applications de calcul. La syntaxe des opérateurs et des instructions de contrôle de Java étant très proche de celle du langage C, les programmeurs C, C++ et C# s’y sentiront particulièrement à l’aise…

SOMMAIRE

imagesOpérateurs

imagesInstructions de branchement

imagesBoucles

MOTS-CLÉS

images Cast

images Concaténation

images if

images switch

images while

images for

Opérateurs à connaître

B.A.-BA Mais pourquoi de tels symboles ?

Les opérateurs et les instructions Java ont été repris du C pour faciliter l’apprentissage de Java aux programmeurs C/C++. Ce choix explique les symboles inhabituels de certains opérateurs (%&|!…) et la complexité de la syntaxe de certaines instructions (for).

Les opérateurs Java se répartissent en trois catégories :

• les opérateurs arithmétiques utilisés pour calculer des expressions ;

• les opérateurs de comparaison et les opérateurs logiques programmés dans les conditions des instructions de branchement ;

• les opérateurs d’affectation utilisés pour modifier la valeur d’une variable.

Tableau 4–1 Opérateurs arithmétiques

Opérateur
Expression
Description

+
expr1 + expr2
renvoie l’addition de expr1 et de expr2.

-
expr1 - expr2 -expression
renvoie la soustraction de expr1 et de expr2.
renvoie la valeur opposée de expression.

*
expr1 * expr2
renvoie la multiplication de expr1 par expr2.

/
expr1 / expr2
renvoie la division de expr1 par expr2, ou déclenche une exception de classe java.lang. ArithmeticException, si expr2 est nulle et la division s’opère sur des expressions entières. Si les expressions sont entières, la division est entière (8 / 3 donne 2).

%
expr1 % expr2
renvoie le reste de la division de expr1 par expr2, ou déclenche une exception de classe java.lang.ArithmeticException, si expr2 est nulle, et les expressions sont entières.

Tableau 4–2 Opérateurs de comparaison

Opérateur
Expression
Description

<
expr1 < expr2
renvoie true si expr1 est strictement inférieure à expr2.

>
expr1 > expr2
renvoie true si expr1 est strictement supérieure à expr2.

<=
expr1 <= expr2
renvoie true si expr1 est inférieure ou égale à expr2.

>=
expr1 >= expr2
renvoie true si expr1 est supérieure ou égale à expr2.

==
expr1 == expr2
renvoie true si expr1 est égale à expr2.
Si expr1 et expr2 sont des références sur des objets, le résultat est true si les 2 références désignent le même objet, ou si elles sont égales à null.

!=
expr1 != expr2
renvoie true si expr1 est différente de expr2.
expr1 != expr2!(expr1 == expr2)

instanceof
objet instanceof Type
renvoie true si objet désigne une instance de la classe Type ou des classes dérivées de Type.
Si objet est égal à null, le résultat est toujours false.
Si Type est une interface, objet instanceof Type renvoie true si la classe d’objet implémente Type.

Tableau 4–3 Opérateurs logiques

Opérateur
Expression
Description

!
!exprBool
renvoie le complément logique de exprBool, c’est-à-dire false si exprBool est égale à true, et inversement.

&&
exprBool1 && exprBool2
renvoie le résultat d’un ET logique entre les opérandes. Si exprBool1 est false alors exprBool2 n’est pas évaluée, et false est renvoyé immédiatement.

||
exprBool1 || exprBool2
renvoie le résultat d’un OU logique entre les opérandes (le caractère | s’obtient en activant AltGr + 6 sur PC et Alt + Shift + L sous Mac OS).
Si exprBool1 est true alors exprBool2 n’est pas évaluée, et true est renvoyé immédiatement.

Table de vérité de l’opérateur ET
&& | true | false
true | true | false
false | false | false

Table

...

chapitre 5

Réutilisation des classes

Si le concept sur lequel repose une classe est clair et homogène, pourquoi ne pas le réutiliser comme brique de base pour concevoir d’autres classes ?
Ce chapitre présente les différentes façons de réutiliser une classe, de l’enrichir, voire d’en altérer l’implémentation sans la modifier.

SOMMAIRE

imagesComposition

imagesHéritage

imagesPolymorphisme

imagesConversion de référence

imagesRedéfinition de méthode

imagesMéthode de classe

imagesÉnumération

MOTS-CLÉS

images extends

images super

images static

images final

images enum

Réutiliser des classes existantes, qu’elles fassent partie de la bibliothèque Java ou qu’elles aient été créées par vous, est indispensable pour pouvoir développer de manière productive. La réutilisation s’exprime de plusieurs manières : une classe peut en référencer une autre grâce à la composition, reprendre les caractéristiques d’une autre grâce à l’héritage, ou modifier l’implémentation des méthodes d’une autre grâce au polymorphisme.

Réutiliser en composant : la relation « a un »

La composition associe un objet à un autre objet, définissant une relation a un entre ces deux objets : un objet de la classe Personne peut par exemple « avoir » un objet de la classe Adresse.

En Java, cette relation s’utilise simplement en déclarant un champ de type classe :

private ClasseReutilisee champ;

DANS LA VRAIE VIE Composition avec la classe java.lang.String

La classe java.lang.String est la classe le plus souvent utilisée en composition et permet de stocker une information textuelle d’un objet, par exemple le champ intitule de la classe com.eteks.outils.Service.

Par l’exemple : une même adresse pour deux personnes

Cet exemple montre comment programmer les classes représentant l’adresse d’une personne avec une relation de composition. La troisième classe met ensuite en œuvre les deux premières dans une application.

EXEMPLE com/eteks/outils/Adresse.java

package com.eteks.outils;

public class Adresse

{

Champ mémorisant la rue et son numéro.

Champ mémorisant le code postal.

Champ mémorisant la ville d’une adresse.

private String rue;

private int codePostal;

private String ville;

Constructeur initialisant les champs d’une nouvelle adresse.

public Adresse(String rue, int codePostal, String ville)

{

this.rue = rue;

this.codePostal = codePostal;

this.ville = ville;

}

Renvoie la rue de cette adresse.

public String getRue()

{

return this.rue;

}

Renvoie le code postal de cette adresse.

public int getCodePostal()

{

return this.codePostal;

}

Renvoie la ville de cette adresse.

public String getVille()

{

return this.ville;

}

}

La classe précédente, com.eteks.outils.Adresse, est réutilisée par la classe com.eteks.outils.Personne avec une relation de composition pour mémoriser l’adresse d’une personne (une personne a une adresse) :

EXEMPLE com/eteks/outils/Personne.java

package com.eteks.outils;

public class Personne

{

Champ mémorisant le nom d’une personne.

Champ mémorisant le prénom d’une personne.

Champ mémorisant l’adresse d’une personne.

private String nom;

private String prenom;

private Adresse adresse;

Constructeur initialisant le nom et le prénom d’une nouvelle personne.

public Personne(String nom, String prenom)

{

this.nom = nom;

this.prenom = prenom;

}

Renvoie le nom de cette personne.

public String getNom()

{

return this.nom;

}

Renvoie le prénom de cette personne.

public String getPrenom()

{

return this.prenom;

}

Modifie l’adresse de cette personne.

public void setAdresse(Adresse adresse)

{

this.adresse = adresse;

}

Renvoie l’adresse de cette personne.

public Adresse getAdresse()

{

return this.adresse;

}

}

L’application de classe com.eteks.test.DeuxPersonnesUneAdresse utilise les deux classes précédentes et montre qu’il est possible de partager une même instance de la classe com.eteks.outils.Adresse pour deux personnes.

EXEMPLE com/eteks/test/DeuxPersonnesUneAdresse.java

package com.eteks.test;

import com.eteks.outils.*;

class DeuxPersonnesUneAdresse

{

public static void main(String[] args)

{

Personne personne1;

Création d’une instance de com.eteks.outils.Personne pour Thomas Durand.

personne1 = new Personne("Durand", "Thomas");

Adresse adresse1;

Création d’une instance de com.eteks. outils.Adresse.

adresse1 = new Adresse("5, rue de Rennes", 75006, "PARIS");

Affectation de son adresse à Thomas.

personne1.setAdresse(adresse1);

Création d’une autre instance de com.eteks.outils.Personne pour Sophie Martin.

Personne personne2 = new Personne("Martin", "Sophie");

Affectation directe de l’autre adresse avec une nouvelle instance.

personne2.setAdresse(new Adresse("3, pl. de la Gare",

95300, "PONTOISE"));

Plus tard… Sophie déménage chez Thomas et partage donc son adresse.

personne2.setAdresse(personne1.getAdresse());

Plus tard… ils voient plus grand et déménagent tous les deux.

Adresse adresseCommune =

new Adresse("8, rue de Rennes", 75006, "PARIS");

personne1.setAdresse(adresseCommune);

personne2.setAdresse(adresseCommune);

Et vous annoncent la nouvelle. Les références renvoyées par personne1.getAdresse() et personne2.getAdresse() sont égales et désignent le même objet.

String adresse = personne1.getAdresse().getRue() + " \u00e0 "

+ personne2.getAdresse().getVille();

String nouvelle =

personne1.getPrenom() + " et " + personne2.getPrenom()

+ " habitent maintenant au " + adresse;

Affiche Thomas et...

chapitre 6

Les classes de base de la bibliothèque Java

Manipulation des textes, des dates, calcul mathématique, gestion d’ensemble d’objets : les classes présentées dans ce chapitre illustrent les choix de modélisation objet proposés par les inventeurs de Java pour ces concepts fondamentaux. Ce sera aussi l’occasion de définir les classes de base utiles à la mise en œuvre du forum de discussion développé dans les chapitres suivants.

SOMMAIRE

imagesHiérarchie de classes depuis Object

imagesChaînes de caractères

imagesJVM et système

imagesDates et heures

imagesTableaux

imagesCollections

MOTS-CLÉS

images Object

images String

images System

images Classe d’emballage

images deprecated

images GregorianCalendar

images ArrayList

images TreeSet

images HashMap

La bibliothèque Java contient des classes qu’il faut absolument connaître, telles java.lang.Object sur laquelle repose toute la hiérarchie des classes Java, java.lang.String pour représenter des chaînes de caractères, ou java.lang.System utilisée pour communiquer avec la JVM. Outre ces classes incontournables, les classes utilitaires pour gérer la date, l’heure et les ensembles d’objets s’avèrent indispensables pour programmer des applications.

La super-classe de toutes les classes : java.lang.Object

C# java.lang.Object = System.Object = object

La classe java.lang.Object ou plus simplement Object (attention au O majuscule) est l’équivalent en Java de la classe object de C#.

Java utilise une hiérarchie unique pour toutes les classes et dont la classe java.lang.Object est la super-classe. Une classe simple hérite donc nécessairement de la classe java.lang.Object et de toutes ses méthodes, la relation d’héritage étant implicite : class ClasseTest équivaut à écrire class ClasseTest extends java.lang.Object. Les méthodes de la classe java.lang.Object le plus souvent utilisées et redéfinies sont les méthodes equals, hashCode et toString pour modifier l’implémentation proposée par la classe java.lang.Object.

La méthode equals

Cette méthode est souvent redéfinie dans une classe pour renvoyer true si deux objets distincts sont égaux en comparant les valeurs de leurs champs. La relation d’égalité définie entre deux objets doit alors être réflexive, commutative et transitive (voir la javadoc de la méthode equals dans la classe java.lang.Object pour une description détaillée de ces relations). Par exemple, la classe java.lang.String redéfinit cette méthode pour déterminer si deux chaînes sont égales en comparant un à un leurs caractères.

public boolean equals

(java.lang.Object obj)

objetA.equals(objetB) renvoie true si objetA == objetB et inversement.

La méthode hashCode

Elle renvoie un code entier utilisé pour le stockage des objets dans les tables de hash (java.util.HashSet, java.util.HashMap…).

public int hashCode()

Pour deux références obj1 et obj2 désignant deux objets quelconques, la relation suivante doit être vérifiée :

Si obj1.equals(obj2) renvoie true alors obj1.hashCode() == obj2.hashCode() est vrai.

ATTENTION Redéfinition des méthodes equals et hashCode

Une classe qui redéfinit la méthode equals doit aussi redéfinir la méthode hashCode et renvoyer le même code pour deux objets égaux par la méthode equals. La condition inverse n’est pas obligatoire : deux objets peuvent renvoyer un même code de hash tout en étant différents par la méthode equals.

B.A.-BA Code de hash

Le code de hash renvoyé par la méthode hashCode est utilisé par certaines classes de collection comme java.util.HashSet et java.util.HashMap pour classer un ensemble d’objets et optimiser les recherches dans cet ensemble (voir la section « Les collections pour gérer des ensembles d’objets » de ce chapitre). Une recherche dans ce type d’ensemble est comparable à la démarche effectuée pour consulter un dictionnaire pourvu d’onglets pour chaque lettre de l’alphabet. Si vous cherchez le mot « Java », vous saisirez alors directement l’onglet « J » pour tomber sur le premier mot commençant par cette lettre. Pour assurer une efficacité maximale à ce système de classement, les codes de hash des objets doivent être répartis sur l’ensemble des entiers int.

La méthode toString

Elle renvoie une chaîne de caractères décrivant la classe de l’objet courant suivi du caractère @ et de la valeur en hexadécimal renvoyée par hashCode (par exemple, com.eteks.outils.Telecarte50@6a55fa).

public java.lang.String toString()

Cette méthode est souvent redéfinie dans une classe pour renvoyer un texte décrivant l’objet avec la valeur de ses champs. Quand l’un des opérandes d’une concaténation avec l’opérateur + est un objet, c’est cette méthode qui est appelée pour obtenir la forme textuelle de cet objet.

REGARD DU DÉVELOPPEUR Quand redéfinir les méthodes equals, hashCode et toString ?

Ces méthodes sont souvent redéfinies dans les classes de la bibliothèque Java comme java.lang.String, java.lang.Float… et c’est en les utilisant que vous percevrez mieux pourquoi les concepteurs de Java ont choisi de déclarer ces méthodes dans la classe java.lang.Object.

La plupart du temps, les méthodes equals et hashCode sont redéfinies dans une classe pour comparer ses objets ou les retrouver dans un ensemble (voir la classe com.eteks.forum.Utilisateur qui suit et l’application d’agenda au chapitre 7, « Abstraction et interface »).

La méthode toString renvoyant la forme textuelle d’un objet, la redéfinition de cette méthode dans une classe est un des moyens les plus simples quand vous avez besoin d’afficher la valeur de ses objets (voir les classes com.eteks.forum.Utilisateur et com.eteks.forum.Message de ce chapitre).

JAVA Autres méthodes de java.lang.Object

La classe java.lang.Object définit aussi les méthodes suivantes moins souvent utilisées :

• getClass renvoie une instance de la classe java.lang.Class qui décrit la classe d’un objet.

• wait et notify sont utilisées pour la synchronisation des threads abordée au dernier chapitre.

• clone crée une copie d’un objet.

• finalize est redéfinie dans une classe pour décrire les traitements spécifiques à effectuer à la destruction d’un objet par le ramasse-miettes.

Forum : utilisateur du forum de discussion

La première classe du forum de discussion abordée dans cet ouvrage décrit un utilisateur du forum. Représenté par une instance de la classe com.eteks.forum.Utilisateur, chaque utilisateur a :

• un pseudonyme et un mot de passe personnel qui lui permettent de s’identifier pour participer au forum ;

• une autorisation qui lui accorde les droits d’utilisateur ou de modérateur. Un utilisateur identifié a le droit de poster des messages et de modifier ses messages. Un modérateur a en outre le droit de modifier n’importe quel message, qu’il en soit l’auteur ou non.

Ces informations correspondent aux champs pseudonyme, motDePasse et autorisation de la classe Utilisateur. Les valeurs de ces champs peuvent être modifiées ou interrogées grâce à leurs accesseurs get…et mutateurs set… correspondants.

Figure 6–1 Diagramme UML de la classe com.eteks.forum.Utilisateur

FORUM com/eteks/forum/Utilisateur.java

package com.eteks.forum;

/**

* Utilisateur du forum avec son pseudonyme, son mot de passe

* et les droits sur le forum qui lui sont accordés.

*/

public class Utilisateur

{

Déclaration des champs mémorisant les informations d’un utilisateur.

private String pseudonyme;

private String motDePasse;

private Autorisation autorisation;

Constructeur.

public Utilisateur(String pseudonyme, String motDePasse,

Autorisation autorisation)

{

this.pseudonyme = pseudonyme;

this.motDePasse = motDePasse;

this.autorisation = autorisation;

}

public String getPseudonyme()

{

return this.pseudonyme;

}

public void setPseudonyme(String pseudonyme)

{

this.pseudonyme = pseudonyme;

}

public String getMotDePasse()

{

return this.motDePasse;

}

public void setMotDePasse(String motDePasse)

{

this.motDePasse = motDePasse;

}

public Autorisation getAutorisation()

{

return this.autorisation;

}

Méthode vérifiant si cet utilisateur est un modérateur.

public boolean isModerateur()

{

return this.autorisation == Autorisation.MODERATEUR;

}

public void setAutorisation(Autorisation autorisation)

{

this.autorisation = autorisation;

}

@Override

Redéfinition de la méthode equals de la classe java.lang.Object pour renvoyer true si cet utilisateur et obj ont le même pseudonyme.

public boolean equals(Object obj)

{

if (this.pseudonyme != nul l)

Si l’objet en paramètre est une instance de la classe com.eteks.forum.Utilisateur.

if (obj instanceof Utilisateur)

{

Conversion de obj en une référence de com.eteks.forum.Utilisateur puis comparaison de leur pseudonyme.

Utilisateur utilisateur = (Utilisateur)obj;

return this.pseudonyme.equals(utilisateur.pseudonyme);

}

return false;

}

@Override

Redéfinition de la méthode hashCode de la classe java.lang.Object.

public int hashCode()

{

if (this.pseudonyme != null)

Réutilisation du code de hash de la classe java.lang.String.

return this.pseudonyme.hashCode();

else

Si pseudonyme n’est pas défini, le code de hash par défaut est renvoyé.

return super.hashCode();

}

@Override

Redéfinition de la méthode toString de la classe java.lang.Object.

public String toString()

{

if (isModerateur())

return this.pseudonyme + " (Mod\u00e9rateur)";

else if (this.pseudonyme != null)

return this.pseudonyme + " (Utilisateur)";

else

return "Utilisateur inconnnu";

}

}

Le type de l’autorisation...

chapitre 7

Abstraction et interface

Les classes abstraites et les interfaces sont l’aboutissement d’une bonne conception objet. Même s’il paraît difficile de bien cerner la portée d’utilisation de cette surcouche d’abstraction du langage Java, ce chapitre montre comment mettre en œuvre ces concepts largement utilisés par la bibliothèque Java.

SOMMAIRE

imagesClasses abstraites

imagesInterface

imagesImplémentation

imagesTri d’objets

imagesÉnumération

imagesEncapsulation

MOTS-CLÉS

images abstract

images implements

images iterator

images Collections

images Tri

images Comparable

chapitre 8

Gestion des erreurs avec les exceptions

Les exceptions permettent de séparer la logique d’un traitement des erreurs qu’il peut provoquer. À l’usage, vous découvrirez que l’intégration des exceptions à Java facilite la mise au point de vos programmes, notamment grâce à leur diagnostic.

SOMMAIRE

imagesPile d’exécution

imagesIntercepter une exception

imagesDéclencher une exception

imagesExceptions contrôlées/non contrôlées

imagesGérer une exception contrôlée

MOTS-CLÉS

images try

images catch

images throw

images finally

images throws

images Throwable

images RuntimeException

images Error

images Exception

images printStackTrace

images réflexion

chapitre 9

Lecture et écriture de fichiers

Basée sur un modèle d’accès aux données sous forme de flux, l’architecture des classes du package java.io permet de lire et d’écrire de façon similaire dans un fichier ou dans d’autres sources de données.
L’application développée dans ce chapitre vous montre comment organiser une application capable de compter le nombre de lignes hors commentaires d’un ensemble de fichiers Java.

SOMMAIRE

imagesAccès au système de fichiers

imagesFlux de données

imagesFiltrer un flux de données

imagesCompter les lignes de code

imagesFichiers de configuration

MOTS-CLÉS

images java.io

images File

images InputStream

images OutputStream

images Reader

images Writer

images IOException

images FilterReader

images BufferedReader

chapitre 10

chapitre 11