Vous êtes sur la page 1sur 96

REPUBLIQUE DU CAMEROUN REPUBLIQUE OF CAMEROUN

PAIX – TRAVAIL - PATRIE PEACE – WORK – FATHERLAND


-=-=-=-=-=-=-=-=-=-=- -=-=-=-=-=-=-=-=-=-=-

UNIVERSITE DES MONTAGNES


---------------------

GBM - GIS

Approche Orientée Objets


et Développement en
JAVA

Pr. NKENLIFACK Marcellin Julius A.


Chef du Département de Génie Informatique à l’IUTFV de l’Université de Dschang
&
Coordonnateur de l’Académie Régionale des Hautes Technologies et Cisco

mnkenlif@hotmail.com

« Version mars 2013 »


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Sommaire

1 PRESENTATION DU COURS ...................................................................................................................................................1


1.1 OBJECTIFS : .........................................................................................................................................................................1
1.2 PRE-REQUIS : .......................................................................................................................................................................1
1.3 RECOMMANDATIONS SUR L’ORGANISATION ET LE TRAVAIL : ..............................................................................................1
1.4 PETITE ETUDE ANECDOTIQUE SUR LA CONCEPTION MODULAIRE ..........................................................................................1
2 Quelques Rappels sur l’Approche orientée Objet ......................................................................................................................2
2.1 INTRODUCTION ...................................................................................................................................................................2
2.2 CONCEPTS DE BASE .............................................................................................................................................................2
2.2.1 Abstraction ( ≡ définition d’une classe) ....................................................................................................................3
2.2.2 Encapsulation ............................................................................................................................................................3
2.2.3 Modularité .................................................................................................................................................................3
2.2.4 Hiérarchie (héritage) .................................................................................................................................................3
2.2.5 Le typage ...................................................................................................................................................................3
2.2.6 Simultanéité ...............................................................................................................................................................3
2.2.7 Persistance.................................................................................................................................................................3
2.3 L’APPROCHE PAR OBJETS ....................................................................................................................................................3
2.3.1 L’approche fonctionnelle descendante et ses limites .................................................................................................4
2.3.2 Pourquoi utiliser l’approche s’appuyant sur les données ?.......................................................................................4
2.3.3 Concepts et formalisme objet.....................................................................................................................................4
2.3.3.1 Les classes et les instances ....................................................................................................................................4
2.3.3.2 Les attributs, champs et variables ..........................................................................................................................5
2.3.3.3 Les Méthodes, messages et comportements ..........................................................................................................5
2.3.3.3.1 Méthodes.........................................................................................................................................................5
2.3.3.3.2 Messages et activation d’objets : ....................................................................................................................6
2.3.3.3.3 L’interprétation des messages .........................................................................................................................6
2.3.3.4 L’héritage ..............................................................................................................................................................6
2.4 RAPPELS SUR LES ETAPES DU CYCLE DE DEVELOPPEMENT ...................................................................................................7
2.4.1 L'implantation d’un système à objets .........................................................................................................................7
2.4.1.1.1 L’identification des entités du domaine ..........................................................................................................7
2.4.1.1.2 La structuration du domaine ...........................................................................................................................7
2.4.1.1.3 L’identification des opérations........................................................................................................................8
2.4.1.1.4 La description des opérations..........................................................................................................................8
2.4.1.1.5 Le lancement des opérations ...........................................................................................................................8
2.4.2 L’exploitation et la maintenance ...............................................................................................................................8
2.5 ANALYSE ET CONCEPTION OO ............................................................................................................................................8
2.5.1 Philosophie Générale : une conception ascendante ..................................................................................................8
2.5.2 Modélisation d’un objet .............................................................................................................................................9
2.5.3 Les notions fondamentales de conception : méthode de conception ..........................................................................9
2.5.3.1 La notion de réification..........................................................................................................................................9
2.5.3.2 Autonomie et localité.............................................................................................................................................9
2.5.3.3 Composition et affinage.........................................................................................................................................9
2.5.4 Aperçu des méthodes d'analyse OO .........................................................................................................................11
2.6 LES LANGAGES A OBJETS..................................................................................................................................................11
2.6.1 Les sept propriétés des langages objets ...................................................................................................................11
2.6.2 Quelques Langages objets et leurs applications ......................................................................................................12
2.7 CONCLUSION .....................................................................................................................................................................13
3 LES OBJETS ET LE LANGAGE JAVA ....................................................................................................................................14
3.1 HISTORIQUE ET EVOLUTION...............................................................................................................................................14
3.2 INTRODUCTION .................................................................................................................................................................15
3.3 RAPPELS DES PRINCIPES DE LA PROGRAMMATION ORIENTEE OBJET : ................................................................................ 15
3.4 BASES DU LANGAGE JAVA .................................................................................................................................................16
3.5 IMPLEMENTATION DES CLASSES ET DES OBJETS EN JAVA ................................................................................................... 16
3.6 QUELQUES PROPRIETES TECHNIQUES DE JAVA...................................................................................................................23
3.7 SECURITE ET MACHINE VIRTUELLE JAVA..........................................................................................................................24
3.8 « ENVIRONNEMENTS » DE DEVELOPPEMENT......................................................................................................................25
3.9 MISE EN ŒUVRE D’UN PROGRAMME COMPORTANT PLUSIEURS CLASSES ............................................................................26
3.10 QUELQUES MOTS RESERVES, PRIMITIFS ET LITTERAUX JAVA .............................................................................................26
3.11 FRAMEWORKS ET API .......................................................................................................................................................26
3.12 PROGRAMMATION JAVA, COMPILATION, EXECUTION .........................................................................................................27
3.12.1 Premier programme « Bonjour » / « Hello World » ................................................................................................27
3.12.2 Outils qui d’automatisation du processus de construction. .....................................................................................28

Prof. Marcellin NKENLIFACK, mars 2013 i


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Sommaire
3.12.3 Exécution d'une applet Java ....................................................................................................................................28
3.13 STRUCTURES .....................................................................................................................................................................28
3.13.1 Les Littéraux ............................................................................................................................................................28
3.13.2 Exercices..................................................................................................................................................................29
4 Bibliothèques de Classes et Techniques de Programmation ....................................................................................................31
4.1 LES PAQUETAGES ..............................................................................................................................................................31
4.1.1 Paquetages standards :............................................................................................................................................31
4.1.2 Les paquetages pour créer des interfaces graphiques plus intéressantes................................................................31
4.1.3 Exemples de codes ...................................................................................................................................................32
4.1.3.1 application simple utilisant le package « SWING » ............................................................................................32
4.1.3.2 Exemple2 d’application (L’environnement Tortue) ............................................................................................33
4.2 RECAPITULATIF PLATEFORME JAVA (PAR CATEGORIE) : ....................................................................................................35
4.2.1 Les API standards (J2SE) ........................................................................................................................................35
4.2.2 Les API d’accès aux données...................................................................................................................................35
4.2.3 Les autres API (de la communauté open source).....................................................................................................35
4.3 LES EXCEPTIONS .........................................................................................................................................................36
4.4 PRESENTATION DE QUELQUES BIBLIOTHEQUES DE CLASSES JAVA ...................................................................................... 37
4.4.1 Introduction .............................................................................................................................................................37
4.4.2 Le paquet du langage (lang) ....................................................................................................................................37
4.4.2.1 La classe Object...................................................................................................................................................37
4.4.2.2 Classes d'enveloppe de type (Wrapper type) .......................................................................................................38
4.4.2.3 La classe Math .....................................................................................................................................................39
4.4.2.4 La classe String....................................................................................................................................................39
4.4.2.5 La classe StringBuffer .........................................................................................................................................39
4.4.2.6 La classe System..................................................................................................................................................40
4.4.3 Le paquet des utilitaires (util) ..................................................................................................................................40
4.4.3.1 L'interface Enumeration ......................................................................................................................................40
4.4.3.2 La classe Vector ..................................................................................................................................................41
4.4.4 Le paquet des entrée/sorties ( E/S - I/O ) .................................................................................................................41
4.4.4.1 Classes de flux d'entrée........................................................................................................................................41
4.4.4.2 Classes de flux de sortie ......................................................................................................................................42
4.4.4.3 Classes de fichiers ...............................................................................................................................................43
4.4.4.4 La classe StreamTokenizer ..................................................................................................................................43
4.4.5 Bibliothèque générique Java (JGL) .........................................................................................................................44
4.5 LES TABLEAUX EN JAVA ...................................................................................................................................................45
4.5.1 Déclaration et création ............................................................................................................................................45
4.5.2 Exemples : ...............................................................................................................................................................45
4.5.3 Tableaux à plusieurs indices : .................................................................................................................................46
4.6 IMPLANTATION PRATIQUE DES FLUX ET FICHIERS EN JAVA ................................................................................................47
4.6.1 Création séquentielle d’un fichier binaire ...............................................................................................................47
4.6.2 Liste séquentielle (d’éléments) d’un fichier binaire : ..............................................................................................47
4.6.3 Accès direct à un fichier binaire ..............................................................................................................................48
4.6.4 Les flux texte ............................................................................................................................................................49
4.6.4.1 Introduction .........................................................................................................................................................49
4.6.4.2 Création d’un fichier texte : .................................................................................................................................49
4.6.4.3 Lecture d’un fichier texte : ..................................................................................................................................50
4.6.5 Gestion globale des fichiers physiques (niveau système) : classe « File » .............................................................51
4.7 LES PACKAGES SWING ......................................................................................................................................................51
4.7.1 Présentation et utilisation ........................................................................................................................................52
4.7.2 Quel paquetage Swing utiliser ? ..............................................................................................................................52
4.7.3 Hiérarchie des classes : composants légers du package java swing .......................................................................54
4.7.4 Structure de l’interface graphique ...........................................................................................................................55
4.7.5 Illustration de SWING sur des exemples..................................................................................................................55
4.7.5.1 Exemple3 d’application (Simple Menu Déroulant → Projet):............................................................................55
4.7.5.2 Voici un exmple d’application illustrant l’utilisation de « Jbutton » de « Swing » .............................................59
4.7.5.3 Voici un exemple d’application illustrant l’utilisation de JEditor de Swing........................................................60
4.8 LE DEVELOPPEMENT D'INTERFACES GRAPHIQUES AVEC SWT ............................................................................................61
4.8.1 Présentation .............................................................................................................................................................61
4.8.2 Liste des packages de SWT de base .........................................................................................................................62
4.8.3 Le programme « HelloWorld » avec SWT ...............................................................................................................62
4.8.4 Quelques composants ..............................................................................................................................................63
4.9 TECHNIQUES DE THREAD ...................................................................................................................................................64
4.9.1 Généralités...............................................................................................................................................................64
4.9.2 Création d'un thread ................................................................................................................................................64

Prof. Marcellin NKENLIFACK, mars 2013 ii


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Sommaire
4.9.2.1 Sous-classes de la classe Thread..........................................................................................................................65
4.9.2.2 Implémentation de l'interface Runnable ..............................................................................................................66
4.9.3 L'API des threads.....................................................................................................................................................66
4.9.3.1 La classe Thread définit les constructeurs suivants: ............................................................................................66
4.9.3.2 Le cycle de vie d'un thread ..................................................................................................................................67
4.9.4 Protection de votre code par rapport aux threads ...................................................................................................67
4.9.4.1 Le mot clé synchronized ......................................................................................................................................68
4.9.4.2 Moniteurs.............................................................................................................................................................68
4.9.5 Exemple d’utilisation de « Threads » ......................................................................................................................68
4.10 LA SERIALISATION ............................................................................................................................................................70
4.10.1 Généralités...............................................................................................................................................................70
4.10.2 Sérialisation .............................................................................................................................................................70
4.10.2.1 L'interface Serializable ....................................................................................................................................70
4.10.2.2 Utilisation des flux de sortie ............................................................................................................................71
4.10.2.3 Utilisation des flux d'entrée .............................................................................................................................71
4.10.2.4 Ecriture et lecture des flux d'objets .................................................................................................................72
4.11 L'ACCES AUX BASES DE DONNEES AVEC JDBC ..................................................................................................................72
4.11.1 Architecture d’accès ................................................................................................................................................73
4.11.2 Les Pilotes JDBC de base ........................................................................................................................................73
4.11.3 Classes sollicitées pour la connexion et l’accès aux Données.................................................................................74
4.11.4 Exemple d’application simple de connexion à une BD élémentaire ........................................................................74
4.11.5 Accès aux données avec Java Via un pilote JDBC ..................................................................................................75
4.11.6 Requêtes avec jointures ...........................................................................................................................................77
4.11.7 Gestion des Images ..................................................................................................................................................77
4.11.8 Gestion des transactions ..........................................................................................................................................77
4.11.9 Mises à jour par lots (batch)....................................................................................................................................77
4.11.10 Exportation et Importation des données ..............................................................................................................77
5 programmation Réseau et Répartie ..........................................................................................................................................78
5.1 INTRODUCTION .................................................................................................................................................................78
5.2 PROGRAMMATION RÉSEAU ................................................................................................................................................ 78
5.2.1 Les Sockets (client serveur) .....................................................................................................................................78
5.2.2 Service en direction de plusieurs clients ..................................................................................................................78
5.2.3 Les Datagrams.........................................................................................................................................................78
5.2.4 Utiliser des URLs depuis / en direction d’une applet ..............................................................................................78
5.3 SERVLETS .........................................................................................................................................................................78
5.3.1 bases de servlets ......................................................................................................................................................78
5.3.2 Servlets et multithreading ........................................................................................................................................78
5.3.3 exécution de servlets ................................................................................................................................................78
5.4 JAVA SERVER PAGES.........................................................................................................................................................78
5.4.1 objets Implicites .......................................................................................................................................................78
5.4.2 principales directives JSP........................................................................................................................................78
5.4.3 Les scipts JSP ..........................................................................................................................................................78
5.4.4 Extraction des champs et valeurs ............................................................................................................................78
5.4.5 Propriétés de JSP ....................................................................................................................................................79
5.4.6 Manipulation de sessions JSP..................................................................................................................................79
5.4.7 Creation et modification de “cookies” ....................................................................................................................79
5.5 INVOCATION DE MÉTHODES À DISTANCE: RMI (REMOTE METHOD INVOCATION) .............................................................. 79
5.5.1 interfaces distantes ..................................................................................................................................................79
5.5.2 Implementation des interfaces distantes ..................................................................................................................79
5.5.3 Creation des “stubs” et “squelettes” ......................................................................................................................79
5.5.4 Utilisation des objets distants ..................................................................................................................................79
5.6 LE BUS LOGICIEL CORBA ................................................................................................................................................79
5.6.1 présentation de CORBA ...........................................................................................................................................79
5.6.2 Applets Java et CORBA ...........................................................................................................................................79
5.6.3 Comparaison ente CORBA et RMI ..........................................................................................................................79
5.7 ENTERPRISE JAVABEANS ..................................................................................................................................................79
5.7.1 Comparison entre JavaBeans et. EJBs ....................................................................................................................79
5.7.2 Specification des EJB ..............................................................................................................................................79
5.7.3 Composenta EJB......................................................................................................................................................79
5.7.4 Structure des composants EJB .................................................................................................................................79
5.7.5 Operations EJB........................................................................................................................................................80
5.7.6 Types d’EJBs ...........................................................................................................................................................80
5.7.7 Developper un EJB ..................................................................................................................................................80
5.8 SERVICES DISTRIBUES JINI.................................................................................................................................................80

Prof. Marcellin NKENLIFACK, mars 2013 iii


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Sommaire
5.8.1 Contexte et présentation de Jini...............................................................................................................................80
5.8.2 Fonctionnement de Jini............................................................................................................................................80
5.8.3 Divers processus Jini ...............................................................................................................................................80
5.8.4 Separation de l’interface et de l’implementation .....................................................................................................80
5.8.5 Abstracton dans les Systèmes répartis .....................................................................................................................80
5.9 QUELQUES EXERCISES ....................................................................................................................................................... 80
5.10 CONCLUSION .....................................................................................................................................................................80
6 Autres Concepts, Techniques et Outils .....................................................................................................................................81
6.1 INTRODUCTION .................................................................................................................................................................81
6.2 FICHIERS DE TYPE ARCHIVE JAVA ......................................................................................................................................81
6.3 UTILISATION DE L'INTERFACE DE CODE NATIF ...................................................................................................................81
6.3.1 Généralités et motivations .......................................................................................................................................81
6.3.2 Utilisation de la JNI.................................................................................................................................................82
6.3.3 Utilisation de l'outil javah .......................................................................................................................................82
6.3.4 Inter-échanges Java - C/C++ ..................................................................................................................................83
6.4 LA SECURITE DANS LE MONDE JAVA EN GENERAL .............................................................................................................83
6.4.1 Eléments de sécurité ................................................................................................................................................83
6.4.2 La "sandbox" java ...................................................................................................................................................83
6.4.3 La sécurité des applets java .....................................................................................................................................83
6.5 PROTECTION DE VOS CODES SOURCES : OBFUSCATION DE CODE ........................................................................................84
6.6 DEVELOPPEMENTS AVEC JME ........................................................................................................................................... 85
6.6.1 Les configurations ...................................................................................................................................................85
6.6.2 Les profils ................................................................................................................................................................85
6.6.3 Les Midlets...............................................................................................................................................................86
6.6.4 Conclusion ...............................................................................................................................................................86
7 ANNEXE : Quelques problèmes courants et astuces................................................................................................................87
7.1 COMMON COMPILER AND INTERPRETER PROBLEMS (AND THEIR SOLUTIONS) ...................................................................87
7.1.1 Compiler Problems ..................................................................................................................................................87
7.1.2 Interpreter Problems ...............................................................................................................................................87
7.2 COMMON APPLET PROBLEMS (AND THEIR SOLUTIONS) ....................................................................................................88
7.3 COMMON COMPONENT PROBLEMS (AND THEIR SOLUTIONS).............................................................................................88
7.4 COMMON LAYOUT PROBLEMS (AND THEIR SOLUTIONS) ...................................................................................................89
7.5 COMMON GRAPHICS PROBLEMS (AND THEIR SOLUTIONS) ................................................................................................89

Liste des figure :


FIGURE 1. EXEMPLE DE REPRESENTATION D'UN OBJET D'UNE CLASSE ....................................................................................... 2
FIGURE 2 UNE CLASSE ET SES ATTRIBUTS, PUIS DEUX INSTANCES DE LA CLASSE ..................................................................... 5
FIGURE 3 EXEMPLE D'HÉRITAGE (ATTRIBUTS HÉRITÉS)............................................................................................................ 6
FIGURE 4 EXEMPLE D’HERITAGE SIMPLE ET HERITAGE MULTIPLE............................................................................................. 7
FIGURE 5. EXEMPLE DE RELATION ENTRE 2 OBJETS .................................................................................................................. 9
FIGURE 6. UN EXEMPLE DE COMPOSITION ET AFFINAGE .......................................................................................................... 10
FIGURE 7. EXEMPLE DE CLASSE ET INSTANCES ....................................................................................................................... 20
FIGURE 8. ETAPES DE COMPILATION ET EXECUTION EN JAVA ................................................................................................. 25
FIGURE 9. ECRAN D’EXECUTION DE L’APPLICATION HELLOWORLD UTILISANT LES OBJETS « SWING ».................................. 33
FIGURE 10. RESULTAT EXECUTION DE L’APPLICATION ARBRE UTILISANT L’ENVIRONNEMENT TORTUE................................. 35
FIGURE 11. HIERARCHIE DES CLASSES DU PACKAGE "JAVA SWING" ....................................................................................... 54
FIGURE 12. HIERARCHIE DES CLASSES DU PACKAGE SWING (SUITE ET FIN) ............................................................................ 54
FIGURE 13. ECRAN : UTILISATION DES CLASSES SWING BUTTON .......................................................................................... 60
FIGURE 14. ECRAN : UTILISATION DES CLASSES SWING ET JEDITOR .................................................................................... 61
FIGURE 15. ARCHITECTURE DEUX TIERS (2/3) JDBC .............................................................................................................. 73
FIGURE 16. ARCHITECTURE TROIS TIERS (3/3) JDBC.............................................................................................................. 73

Liste des Tableaux :


TABLEAU 1 STRUCTURE D'UN MESSAGE EN OBJET ................................................................................................................... 6
TABLEAU 2 TYPES PRIMITIFS ET CLASSES ENVELOPPES CORRESPONDANTES .......................................................................... 38
TABLEAU 3. LISTE DES PACKAGES DE SWT ................................................................................................................... 62
TABLEAU 4. PRINCIPALES METHODES DE LA CLASSE CONTROL .............................................................................................. 63
TABLEAU 5. PRINCIPALES METHODES POUR OBTENIR DES DONNEES D'UNE BD (JDBC) ......................................................... 75
TABLEAU 6. LES PROFILES DÉFINIS (JME) ............................................................................................................................. 85

Prof. Marcellin NKENLIFACK, mars 2013 iv


IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Présentation du cours

1 PRESENTATION DU COURS

1.1 OBJECTIFS :
En première partie :
* Historique et définition des objectifs de la POO
* Les différents concepts de l’orienté objet
* Domaines d'application des méthodes OO
* Brève présentation de quelques méthodes d’analyse ou de modélisation OO
* Présentation des caractéristiques de quelques Langages OO et SGBDOO
En deuxième partie :
** Etude et programmation dans un langage OO comme JAVA
* Caractéristiques générales du langage Java
* Apprentissage et conception des objets, des classes, etc.
* Etude et compréhension de la programmation événementielle
* Techniques de réalisation des GUI (Interfaces Graphiques Utilisateurs)
* Manipulation des fichiers et flux
* Développement de processus (Threads)
* Accès aux Bases de données
** Projets pratiques : Conception et Développement d'Applications complètes (JAVA)

1.2 PRE-REQUIS :
• Langages de programmation professionnels : C, (C# : un atout)...
• Notions sur les structures de données abstraites

1.3 RECOMMANDATIONS SUR L’ORGANISATION ET LE TRAVAIL :


* L’étudiant doit suivre attentivement les exposés de cours et poser des questions pour s’assurer qu’il a bien compris.
* Ensuite, lire plusieurs fois les supports (éventuel) de cours fournis.
* Les exercices sont à faire progressivement selon le rythme indiqué.
* Quelques-uns des fichiers corrigés sont présentés au fur et à mesure. Ils doivent être tous implémentés, car pouvant servir de base
conceptuelle pour chaque étudiant.
* Ce support est complété par des fiches obligatoires de TD, TP et Projets
* Pour les projets, attention à une conception sans concertation. D’une part, il y a intérêt exploiter les acquis techniques (mécanismes
et « design patterns »). D’autre part, l’architecte logiciel doit transmettre et vérifier le respect des styles d’architectures.
.

NB : L’étudiant devra remettre à chaque TP, un rapport décrivant le travail effectué, les résultats obtenus et les difficultés et
suggestions éventuelles.

1.4 PETITE ETUDE ANECDOTIQUE SUR LA CONCEPTION MODULAIRE


Du code « Spaghetti » au code « Cannelloni » en passant par les « Raviolis » (tiré de [RoquesVallee01])
A la glorieuse époque du développement par fonctions, il était d’usage de tracer à la règle, en marge des listings, la succession des appels de fonctions.
Bien que le goto ait été déjà sévèrement proscrit pour le plus grand bonheur des relecteurs de code, il n’en était pas moins vrai qu’une dizaine d’appels de
fonctions imbriquées suffisait à faire oublier l’intention de départ. La succession et l’imbrication des appels de fonction donnaient lieu à une myriade de
traits en marge des listings qui n’étaient pas sans rappeler le plat de spaghetti, et l’effort du relecteur se résumait à la maxime suivante : « Essayez se
suivre visiblement les méandres d’un bout à l’autre d’un spaghetti, au sein d’une assiette bien garnie ».
L’arrivée des langages orientés objet suscita l’espoir de venir à bout du code spaghetti, en offrant la possibilité de regrouper par responsabilités toutes les
méthodes de réalisation d’un même objet du « monde réel ». A cette époque, l’idée d’organiser les objets n’était pas encore de mise, puisque ceux-ci
s’organisaient d’eux-mêmes comme dans le monde réel. Le code de chaque classe prise une à une pouvait être examiné et compris. Cependant, une fois
assemblées dans le système, les interactions multiples entre classes formaient un imbroglio peu intuitif. Cela évoquait terriblement le plat de raviolis, et le
problème de relecteur tenait en ces termes : « Extrayez un ravioli d’une assiette, et étudiez le pour comprendre sa forme et son contenu ; c’est jusqu’ici
facile ; Replacez-le dans l’assiette et étudiez ses relations avec les autres raviolis ; c’est beaucoup plus difficile. »
L’arrivée des pratiques issues des processus UP met plus l’accent sur l’organisation en couches et sur l’orientation composants. « Le cannelloni, bien que
plus gros, offre les mêmes facilités d’étude que le ravioli. Une fois dans l’assiette, le cannelloni est assemblé en couches et en partitions et il ne
communique pas avec n’importe quel autre cannelloni suivant sa position dans l’assiette ». On peut donc déclarer que le cannelloni constitue le modèle
d’organisation du logiciel approprié, à charge de trouver mieux dans les prochaines années…

Prof. Marcellin NKENLIFACK, mars 2013 1


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet

2 QUELQUES RAPPELS SUR L’APPROCHE ORIENTEE OBJET

2.1 INTRODUCTION
Deux types de motivations orientent actuellement les concepteurs dans le choix des méthodes de conception: la
possibilité de prendre en compte des applications et des systèmes de plus en plus complexes
[Gardarin97][Leray92][Zoller97] et le soucis de diminuer les coûts de réalisation et de maintenance. Avec l’ère des
nouvelles technologies, des réseaux informatiques et systèmes répartis, les applications ont atteint elles aussi un niveau de
complexité croissant et de ce fait, elles nécessitent à l’heure actuelle, des outils de programmation sophistiqués. On constate
que les applications dites technique, telles que la CAO, la cartographie, les systèmes de contrôle temps réel, le CoDesign…
représentent une activité croissante et nécessitent une plus grande participation des personnes aussi bien pour l'effort de
conception et validation que de maintenance et d'évolution.
Ces constats ont mis en évidence la nécessité de promouvoir l’abstraction de données, la modularité et la réutilisabilité
[Manhes98] des composants fabriqués.
Ainsi, beaucoup de méthodes ont vu le jour, chacune tentant à sa manière d’apporter une solution satisfaisante, parmi elles,
les méthodes objets (orientées objets) et leurs techniques d’analyse et de conception appropriées.

Pourquoi parler de Programmation Orientée Objets (POO) ?


La complexité et la taille des projets nécessitent des outils de programmation nombreux et perfectionnés pour mener
à bien les applications dans les meilleurs délais.
En fait, les langages à objets connaissent un succès grandissant, aussi bien dans le domaine de l’Intelligence Artificielle
(IA) que dans celui du Génie Logiciel ou des BD, car ils constituent sans doute la solution la plus souple et offre plus de
perspectives pour répondre à ces différents besoins.

2.2 CONCEPTS DE BASE


Un objet est une abstraction d'une donnée du monde réel caractérisée ainsi [Bouzegoub97] :
Objet = identité + état + comportement
L'identité d'un objet est représentée par un identifiant (object identifier ou OID) unique et invariant qui permet de
référencer l'objet indépendamment des autres objets. L'état d'un objet est une valeur qui peut être simple, par exemple, un
littéral, ou structurée, par exemple, une liste. Dans le dernier cas, l’état peut être composé de valeurs simples, de références
à d'autres objets, ou de valeurs elles-mêmes structurées. Le comportement d'un objet est défini par un ensemble
d'opérations applicables à l'objet et définies dans sa classe d'appartenance. En résumé, nous avons la définition suivante :
Objet: abstraction d'une donnée caractérisée par un identifiant unique et invariant, un état représenté par une
valeur simple ou structurée, et une classe d'appartenance.
L'identité et l'égalité de deux objets sont deux notions différentes. Deux objets o1 et o2 sont identiques si leurs identifiants
sont égaux (o1==o2). Deux objets o1 et o2 sont égaux si leurs états sont égaux (o1=o2). Donc nous avons
(o1==o2)⇒(o1=o2).
L’univers devient donc une structure composée d’ensemble d’objets déterminant chacun les clés de son comportement.
Les types d'objets seront des classes, et les objets (instances) seront considérés comme représentants de classes.

Exemple:
Objet (instance)
. Classe VOITURE .
-immatriculation
Démarrer () - marque
Rouler () -…
Stopper ()

Démarrer Rouler Stopper

Figure 1. Exemple de représentation d'un objet d'une classe

Les principes énoncés plus haut offrent des qualités pour mettre en œuvre des méthodes rigoureuses. Ainsi, on doit
retrouver dans une approche objet au moins 4 principes obligatoires: abstraction, encapsulation, modularité, hiérarchie ;
auxquels on peut ajouter 3 principes complémentaires : typage, simultanéité, persistance.

Prof. Marcellin NKENLIFACK, mars 2013 2


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
2.2.1 ABSTRACTION ( ≡ DEFINITION D’UNE CLASSE)
Elle fait ressortir les caractéristiques essentielles d’un objet (qui le distinguent de tous les autres) et donc procure des
frontières conceptuelles vigoureusement définies du point de vue de l’observateur (utilisateur).
On mettra en évidence 3 types d’abstractions :
- Abstraction d’action : objets procurant un ensemble généralisé d’opérations réalisant toutes le même nombre de
fonctions et le même genre.
- Abstraction de machine virtuelle : autonomie.
- Abstraction de coïncidence : objets n’ayant aucune relation entre eux.
C'est l’objet qui décide la manière d’effectuer les opérations. Il n’est pas besoin de connaître l’implémentation interne d’un
objet…

2.2.2 ENCAPSULATION
C’est le procédé de séparation des éléments d’une abstraction qui constituent sa structure et son fonctionnement.
Elle permet de dissocier l’interface conceptuelle de la mise en œuvre d’un objet (on cache l’implémentation des méthodes).
L’encapsulation suppose également lisibilité et compréhensibilité. Les possibilités de surcharge et la modularité renforcent
la lisibilité des codes. Mais, les détails d’implantation sont généralement cachés.

2.2.3 MODULARITE
La modularité est la propriété d’un système décomposé en ensemble de modules cohérents faiblement couplés. La
modularité suppose également souplesse et modifiabilité : les objets sont faciles à changer.

2.2.4 HIERARCHIE (HERITAGE)


C’est un « classement » ou ordonnancement des abstractions. En assurant la relation de généralisation, il facilite
aussi la modélisation des objets et la modularité du code. Il permet la réutilisation des attributs et opérations des classes
d'objets, et élimine les redondances.

2.2.5 LE TYPAGE
Le fait d’imposer la classe d’un objet de façon que les objets de types différents ne puissent pas être intervertis, ou
tout au plus ne puissent être intervertis que de façon restrictive.

2.2.6 SIMULTANEITE
Deux objets différents doivent pouvoir agir en même temps et à des endroits différents (soit sur la même machine,
soit sur des machines différentes,…).

2.2.7 PERSISTANCE
Ceci concerne la durée de vie d’un objet (important dans les BD, où les données sont disponibles pendant
longtemps).

2.3 L’APPROCHE PAR OBJETS


[Bouzegoub97, ObjetsWa, ObjetsWb, ObjetsWc, LOBJETW]
La conception d’un système doit toujours se poser une question fondamentale : « la structure de données doit-elle
être fondée sur les actions ou sur les données ? ». C’est dans la réponse à cette question, qui pose réellement le problème de
la continuité, que réside la différence entre les méthodes traditionnelles de conception et l’approche par objets.
Si le système est trop fortement basé sur les fonctions, il semble difficile de garantir l’évolution, sauf si les nouvelles
fonctions sont dérivées des anciennes. En revanche, si les nouvelles tâches changent radicalement, les architectures basées
sur les données sont alors plus adaptées.

Principes de la POO
Au fil des années, les techniques de programmation ont évolué vers une séparation entre les concepts manipulés dans les
programmes et leur représentation interne en machine, afin de mieux les structurer face à la complexité des problèmes
abordés.
Ainsi, la célèbre équation de NIKLAUS WIRTH résume ce principe :
Algorithmes + Structure de données = Programme
Les méthodes d’analyse associées à ce principe consistent alors à « diviser un problème pour mieux régner ». C’est ce que
l’on appelle la programmation dirigée par les traitements ou méthode fonctionnelle descendante. Toutefois, cette technique
atteint ses limites lorsque l’univers sur lequel opèrent les programmes évolue. La notion d’encapsulation permet alors de

Prof. Marcellin NKENLIFACK, mars 2013 3


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
pallier cet inconvénient : les données et les procédures qui les manipulent sont regroupées dans une même entité appelée
OBJET.
Un objet regroupe une partie statique (ensemble de données) et une partie dynamique (ensemble de procédures manipulant
ces données). L’objet est alors défini par son comportement et non par sa structure. C’est ce que l’on appelle la
programmation dirigée par les données. Ainsi, pour traiter une application, le programmeur commence par définir les types
d’objets appropriés et leurs opérations spécifiques. L’univers devient alors une structure composée d’un ensemble d’objets
qui déterminent chacun les clés de leur comportement.
Ces principes offrent des qualités pour mettre en œuvre des méthodes de programmation rigoureuses :
- Abstraction des données : l’objet décide de la manière d’effectuer les opérations (il n’est pas besoin de connaître
l’implémentation interne d’un objet…).
- Modularité/Modifiabilité : les objets sont faciles à changer.
- Réutilisabilité : l’intégration de bibliothèques d’objets permet de construire des objets de même type, puis des objets
plus spécifiques, etc.
Lisibilité/Compréhensibilité : l’encapsulation, la possibilité de surcharge et la modularité renforcent la lisibilité de
programmes. Les détails d’implantation sont cachés.

2.3.1 L’APPROCHE FONCTIONNELLE DESCENDANTE ET SES LIMITES


Les méthodes classiques de conception utilisent une approche par fonctions et non par objets. Ainsi, la méthode
descendante s’appuie sur l’idée que le logiciel doit s’obtenir par une décomposition pas à pas du problème en sous
problèmes. Cette décomposition descendante a des points forts. C’est une approche bien organisée, réfléchie, logique qui
favorise le développement ordonné des systèmes. Mais cette conception présente aussi différents problèmes. La méthode
prend difficilement en compte l’évolution des systèmes et ne facilite pas la réutilisabilité.
En fait, le problème principal réside en cette continuité des systèmes. En effet, la décomposition fonctionnelle est fondée
sur une structure initiale obtenue facilement ; si celle-ci doit être modifiée, changée ou améliorée à long terme, la
conception fonctionnelle devient alors difficile à gérer.
De plus, généralement, chaque structure de données doit être attachée à une ou plusieurs fonctions. Lorsque les données
jouent un rôle important, la structure perd alors son aspect à l’intérieur de la « structure du programme ». Celle-ci se trouve
dans ce cas, morcelée parmi les fonctions qui l’utilisent. L’approche fonctionnelle reste à utiliser pour des problèmes pas
« trop complexes » et dont la structure de données n’a pas à subir des changements cruciaux.

2.3.2 POURQUOI UTILISER L’APPROCHE S’APPUYANT SUR LES DONNEES ?


L’intérêt d’une architecture par les données permet de satisfaire la compatibilité (en utilisant les données comme
critère de décomposition), la réutilisabilité (afin de permettre l’utilisation de structures de données « non élémentaires ») et
l’extensibilité (afin de permettre une stabilité du système dans le temps).
Ainsi, BERTRAND MEYER définit la conception par objets comme étant « la méthode qui conduit à des architectures
logicielles fondées sur les objets que tout système ou sous-système manipule, plutôt que sur la fonction qu’il est censé
réaliser ». En fait, pour réaliser un système informatique selon une approche par objets, il ne faut pas selon lui,
« commencer par demander ce que fait le système, mais plutôt demander A QUOI il le fait ». En élaborant l’architecture
d’un système, le concepteur doit se poser les questions suivantes :
- Comment trouver des objets ?
- Comment décrire les objets ?
- Comment décrire les relations entre les objets ?
- Et comment réutiliser les objets pour structurer les programmes ?

2.3.3 CONCEPTS ET FORMALISME OBJET


Les représentations par objets structurés sont nées de la conjonction de plusieurs sources : les « schémas » issus des
travaux de BARLETT ; les « frames » de MINSKY ; et enfin les travaux de « scripts » issus des travaux de SCHANK et
ABELSON.
Ainsi, la représentation par objets repose sur 3 principes :
♦ un concept de « modélisation » par le biais des notions de classes et d’instances.
♦ un concept de « construction par affinage » par l’intermédiaire de la notion d’héritage.
♦ un concept « d’activation » à l’aide d’envoi de messages et de méthodes.

2.3.3.1 Les classes et les instances


Un objet est une entité informatique complète qui comprend :
- une partie statique représentant son état et les liens qui l’unissent à d’autres objets.

Prof. Marcellin NKENLIFACK, mars 2013 4


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
- Une partie dynamique représentant son comportement, c’est à dire l’ensemble des opérations qui lui sont applicables
ainsi que ses réactions aux événements du milieu dans lequel il se trouve.
Ainsi, plusieurs objets peuvent posséder une structure et des comportements communs. Ils sont alors regroupés à l’aide
d’un modèle général, que l’on appelle une classe. Une classe peut être considérée comme un moule à partir duquel sont
générés les objets. Les objets ainsi générés s’appellent instances.
Coder en objet revient alors à décrire des classes d’objets, à caractériser leur structure et leur comportement et à instancier
ces classes pour créer des objets.
Un exemple classique dans le domaine des objets, c’est celui de la manipulation d’un point. Un point peut être
caractérisé par: ses coordonnées et sa visibilité.
Ainsi, une représentation OO pourrait nous donner la figure ci-dessous :

CLASSE = CPOINT
Attributs X, Y : entiers
statiques Visible : booléen
Initialiser
Afficher
Méthodes Cacher
Positionner_En

P1
10,20 P2
Vrai 50,40
Deux instances de la classe CPOINT Faux

Figure 2 Une classe et ses attributs, puis Deux instances de la classe

Métaclasse :
Une classe métaclasse est une classe « génératrice d’objets » non terminaux (des classes), qui regroupe les propriétés
permettant l’utilisation d’une classe sous forme d’instance.

2.3.3.2 Les attributs, champs et variables


Toute instance « objet » est décrite à travers des attributs (dans le cas des langages de frames ou de schémas), ou des
champs (dans le cas du langage MERING), ou encore des variables (dans le cas du langage SMALLTALK). Ces attributs
peuvent représenter :
- des propriétés ; exemple : age, profession, taille, poids, …
- des relations directes ; exemple : liste des enfants, liste des permis, langues parlées, …

2.3.3.3 Les Méthodes, messages et comportements


2.3.3.3.1 Méthodes
La partie dynamique des objets est assurée par la notion de message. Envoyer un message à un objet, c’est lui dire
ce qu’il doit faire. Ainsi, le comportement des objets est décrit au sein même de la classe sous la terminologie de
<méthode>.

Par exemple, dans la classe CPOINT, les méthodes peuvent être définies de cette façon :
Méhode Initialiser (x1, y1 : entiers) ; Méhode Afficher ( )
X = x1 ; Visible = vrai ;
Y = y1 ; affiche_pixel(X,Y,couleur) ;
Fin Fin
Méhode Positionner_En(px1,py1:entiers);
Méhode Cacher ( ) Cacher ( ) ;
Visible = faux ; X = px1 ;
affiche_pixel(X,Y,couleur_fond) ; Y = py1 ;
Fin Afficher ( ) ;
Fin

Prof. Marcellin NKENLIFACK, mars 2013 5


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
Une méthode d’un objet peut accéder aux attributs propres à ce dernier, mais pas à ceux d’autres objets;
L’activation d’une méthode (pour la réalisation d’une action) est liée à la réception d’un message par un objet.
Ainsi, les objets communiquent entre eux à travers les messages qu’ils peuvent recevoir ou émettre.
2.3.3.3.2 Messages et activation d’objets :
La structure d’un message est la suivante :
SELECTEUR OBJET PARAMETRE
( nom méthode ) ( receveur ) ( paramètres effectifs de la méthode )

Tableau 1 Structure d'un message en objet

Les messages sont généralement associés aux classes d’utilisateurs autorisés à les manipuler, ce qui permet de mettre en
œuvre le concept de schéma à travers les méthodes.
Pour activer un objet afin qu’il exécute l’une de ses opérations, héritée ou propre, il suffit de lui envoyer un message lui
demandant de réaliser cette opération identifiée par un « sélecteur » qu’il reconnaîtra et auquel il réagira par le
comportement associé.
Il existe six principaux modes de transmission de messages :
- Transmission directe avec retour (le plus utilisé).
- Transmission directe avec suite.
- Transmission avec retour immédiat.
- Transmission indirecte avec retour différé (boite aux lettres)
- Transmission anonyme sans retour (centralisation)
- Transmission anonyme avec retour (boite aux lettres + centralisation)
2.3.3.3.3 L’interprétation des messages
La notion de message diffère quelque peu de la notion de procédure d’un langage classique. Par exemple, si l’on
dispose d’objets graphiques (boutons, icônes ou fenêtres…), le même intitulé de message peut être envoyé à deux objets
différents, car chaque objet implémente sa propre méthode de visualisation. C’est ce que l’on appelle la liaison
dynamique de message. La méthode qui doit répondre au message est recherchée au moment de l’exécution.

2.3.3.4 L’héritage
Ce concept permet de définir des classifications, de modéliser «des mondes réels» et de procéder par affinage
successif de classes prédéfinies.
Une classe peut engendrer une autre classe de telle sorte que la sous-classe possède virtuellement les champs et les
méthodes de la classe mère. Tout se passe comme si toute la classe mère était recopiée (copie virtuelle non monotone)
dans la sous classe.
L’héritage favorise le partage de connaissances (les propriétés des objets) entre objets.
Exemple : Les classes HOMME et FEMME héritent de la classe PERSONNE.
Une instance objet d’une classe hérite automatiquement des propriétés statiques (données) et dynamiques
(comportements) de sa (ses) classe (s) mère (s).
En plus des champs et méthodes héritées, une classe est définie par des propriétés qui lui sont spécifiques.
Exemple d’héritage: on peut penser qu’un cercle, en plus de ses propres particularités, possède les mêmes
caractéristiques que celles d’un point. On dira alors qu’un cercle est_un point ; la sou-classe CCERCLE héritant des
caractéristiques de la classe CPOINT créée plus haut dans ce chapitre.

CLASSE = CPOINT CLASSE = CCERCLE


X, Y : entiers
Visible : booléen
Est_un Ceci nous produit en fait la classe suivante, Rayon : entier
en considérant la notion d’héritage :
certains attributs sont hérités, d’autres sont
Initialiser
propres. Afficher
CLASSE = CCERCLE Cacher
Rayon : entier Etendre
Etendre Positionner_En

Figure 3 Exemple d'héritage (attributs hérités)

Prof. Marcellin NKENLIFACK, mars 2013 6


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet

L'héritage peut être simple ou multiple

POINT
TRIANGLE

TRIANGLE TRIANGLE
CERCLE
RECTANGLE ISOCELLE

ELLIPSE
TRIANGLE
RECTANGE-ISOCELLE

Figure 4 Exemple d’héritage simple et héritage multiple

Grâce à la réutilisabilité, l’intégration de bibliothèques d’objets permet de construire des objets de même type, des
objets plus spécifiques, etc.

2.4 RAPPELS SUR LES ETAPES DU CYCLE DE DEVELOPPEMENT


Tout système, qu’il soit temps réel ou non, passe par les étapes suivantes :
- Planification
- Analyse des besoins
- Spécification formelle (conceptuelle)
- Spécification technique (logique)
- Implantation (physique)
- Intégration et test
- Validation
- Maintenance et évolution
De plus amples détails sur ces étapes peuvent être obtenus dans [Gaudel96][Printz-H3208][Otter-H4028][OutilsW].

2.4.1 L'IMPLANTATION D’UN SYSTEME A OBJETS


Cela consiste en différentes phases :
- Conception du système : ou comment faire ? On effectue une conception détaillée de chaque composant du système.
- Construction : c'est la construction des différentes parties du système :
* partie logicielle (codage, test unitaire et intégration du logiciel).
* partie matérielle (simulation, fabrication du prototype, test et mesure).
- Intégration : c'est l'unification de toutes les parties éventuelles.
- Validation : vérification de la conformité du système réalisé avec le besoin exprimé au début.
Selon Jacques FERBER, un cycle de conception orienté objet s’effectue en cinq étapes : l’identification des entités
du domaine, la structuration de ce dernier en analysant les propriétés des entités et leurs relations, l’identification des
opérations que doivent effectuer ces entités, la description précise des opérations et enfin le lancement du programme.
2.4.1.1.1 L’identification des entités du domaine
Cette étape est la plus importante du cycle, car c’est à ce moment, que le concepteur détermine les classes de base
(correspondant aux principaux concepts du domaine), qu’il les enrichit, puis donne une liste exhaustive des objets, qu’il
représente « schématiquement ».
2.4.1.1.2 La structuration du domaine
Une fois les classes définies, le concepteur doit alors les organiser et les relier par des relations de type
méronomique ou taxonomique. Dans un premier temps, il fait apparaître les relations de type taxonomique, puis dans
un deuxième temps, il s’intéresse aux relations de type méronomique, qui peuvent être définies à l’intérieur d’une même
hiérarchie ou relier des hiérarchies différentes.
Note : Dans une hiérarchie « taxonomique », si l’on considère l’entité mère comme un ensemble, les entités filles d’un
même niveau de hiérarchie constituent une ″partition″ de l’entité mère. Le principe d’héritage peut s’appliquer à ce
genre de relation, car les entités filles sont des sous-ensembles de même nature de l’entité mère.

Prof. Marcellin NKENLIFACK, mars 2013 7


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
Dans une « méronomie », la hiérarchie est construite par mise en relation d’entités. Les descendants n’héritent pas
nécessairement des propriétés de l’entité mère. Le principe de lien de composition peut s’appliquer ici, car les entités
filles sont des composantes (de nature différente) de l’entité mère.
2.4.1.1.3 L’identification des opérations
Dans un premier temps, le concepteur analyse les aspects dynamiques : il identifie les opérations qu’il souhaite
effectuer sur les objets, puis les implémente sous forme de méthodes. Il s’intéresse alors à l’ensemble des messages sans
distinction apparente, puis il les individualise en tenant compte de l’interaction entre les objets. Généralement (mais pas
toujours), les opérations remontent vers les classes supérieures.
2.4.1.1.4 La description des opérations
Cette étape consiste à coder dans le langage choisi les classes, les objets et les méthodes. Très souvent, des classes et
des méthodes annexes à la programmation, viennent se greffer.
2.4.1.1.5 Le lancement des opérations
Cette dernière étape consiste à créer les instances initiales, les activer (message) pour démarrer le processus. Le
programme se déroule ensuite par envoi de messages. C’est à ce niveau qu’intervient la mise au point.

2.4.2 L’EXPLOITATION ET LA MAINTENANCE


L'exploitation est la mise en œuvre opérationnelle du système et son utilisation. Tandis que la maintenance, elle
concerne les trois aspects suivants :
• Correctif : corriger les fautes éventuelles du système.
• Perfectif : amélioration du système.
• Adaptatif : adaptation du système pour qu'il puisse répondre à de nouveaux besoins.

2.5 ANALYSE ET CONCEPTION OO


La modélisation par objets est une démarche qui s’avère relativement naturelle une fois utilisée. La philosophie
générale de conception est ascendante. Sur le plan historique, tous les concepts généraux et techniques initiales de
modélisation orientée objets sont présentés en détail par les auteurs [Bouzegoub97] [Gaudel96] [Rollan-H3248]
[CastellaniW] [LOBJETW].

2.5.1 PHILOSOPHIE GENERALE : UNE CONCEPTION ASCENDANTE


Le « concepteur descendant » se concentre sur son problème qu’il essaie de diviser en sous problèmes, alors que le
« concepteur ascendant » essaie autant que faire se peut, d’utiliser des entités déjà existantes et éventuellement d’en
créer...
On se demandait jusque-là « comment trouver des objet ? »
En fait, le problème n’est pas de trouver des objets mais des classes et malheureusement, il n’existe pas de réponse
universelle à cette question. Seul le talent et l’expérience permettent de concevoir avec « succès » des systèmes par
objets. Nous pouvons toutefois donner quelques principes généraux :
♦ Une première approche consisterait à analyser des systèmes existants, en se penchant sur la création des classes. Se
poser la question de savoir si les classes sont autonomes, cohérentes, « pures », etc. Ainsi, l’amélioration des
conceptions existantes permet d’analyser et de prendre du recul sur ces techniques ; c’est « l’apprentissage par
expérience ».
♦ Une seconde approche qui permettrait également de trouver efficacement des classes consisterait à construire un
logiciel comme une modélisation opérationnelle et se servir des classes du monde modélisé comme base pour définir les
classes du système logiciel. Car, de nombreuses classes représentent facilement des objets du monde réel ou abstrait :
missiles, radars, livres et auteurs, figures et polygones, fenêtres et souris, etc.
♦ Comme troisième approche, beaucoup de concepteurs indiquent que la méthode pour trouver des classes est de se
pencher sur le dossier des spécifications et de souligner les noms. Par exemple si l’on trouve l’information suivante :
« le régulateur doit indiquer la température et réguler celle-ci », le concepteur d’une approche fonctionnelle aura besoin
d’une fonction de régulation et d’indication de température, alors que le concepteur d’une approche par objets aura
besoin des classes régulateur et température. Cette technique, un peu simpliste, du fait de la surabondance de classes
qu’elle peut engendrer, reste néanmoins un point de départ.
♦ Une autre approche qui permettrait de trouver des classes consisterait à regarder simplement ce qui est disponible, car
dans les environnements objets, il existe souvent bon nombre de classes prédéfinies et qui permettent de générer
d’importantes abstractions.

Prof. Marcellin NKENLIFACK, mars 2013 8


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
2.5.2 MODELISATION D’UN OBJET
Un objet a un état, un comportement, une identité unique.
♦ L’état d’un objet : englobe toutes les propriétés statiques et « dynamique ».
♦ Un comportement : c’est la façon dont un objet agit et réagit (changement d’états et transmission de messages).
On distingue les opérations, méthodes et fonction agissant comme modificateur (->objet, sélecteur, interpréteur).

Relations entre objets (échanges)


Si un objet veut faire appel à un objet d’une autre classe ou à un de ses services, on peut avoir la représentation :

CLIENT SERVEUR
L’objet client - > demande le service
L’objet serveur - > rend le service
L’objet agent - > gère des échanges entre un client et
un serveur
AGENT

Figure 5. Exemple de relation entre 2 objets

2.5.3 LES NOTIONS FONDAMENTALES DE CONCEPTION : METHODE DE CONCEPTION


Dans un processus de conception objet, la principale difficulté réside plus dans le mode de pensée «objet» que dans
le fait de disposer ou non de méthode. C’est donc au mode de pensée lui-même qu’il est important de se consacrer.
Selon J. FERBER, la conception par objets repose sur trois principes : la notion de réification (comment faire des
classes objets), l’autonomie et la localité (comment penser objets), la composition et l’affinage (comment structurer).

2.5.3.1 La notion de réification


Les conceptions traditionnelles s’intéressent principalement aux traitements alors que les conceptions par objets se
focalisent sur ce qui doit être géré. Ainsi, Jacques FERBER [wwwFerber07] définit la réification comme « l’opération
essentielle du paradigme objet par lequel quelque chose (physique, relation, événement) est représenté
"informatiquement" sous la forme d’objets ». Aussi, « concevoir par objets c’est savoir de quoi l’on parle ».

2.5.3.2 Autonomie et localité


Créer un programme selon une conception par objets c’est décomposer celui-ci en entités indépendantes possédant
chacune sa mémoire locale et les opérations qu’elle doit effectuer. Ainsi, chacune de ces entités est considérée comme
une sorte de «brique» de base nécessaire à la conception d’un objet plus complexe. Le problème réside alors dans le fait
que, si les concepts de base ne sont pas difficiles à trouver, leur mise en œuvre nécessite une véritable conversion de
pensée. C’est ce que l’on appelle l’autonomie et la localité, car les objets sont considérés comme des entités à part
entière et leur comportement est défini au sein même de l’objet.

2.5.3.3 Composition et affinage


Pour concevoir un système par objets formels, un concepteur doit savoir utiliser ce qui a déjà été écrit. Ainsi, grâce
aux classes et à l’héritage, celui-ci ne décrira que la différence nécessaire à la réalisation de son système. C’est ce que
l’on appelle la composition ou l’art de savoir constituer des entités à part entière. L'affinage décrit quant à lui, un
système en termes de «systèmes» déjà existants : on définit au départ, les unités les plus spécifiques et au fur et à
mesure, on remonte, grâce à l’héritage, dans la hiérarchie afin de généraliser les classes.

Prof. Marcellin NKENLIFACK, mars 2013 9


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet

Par exemple, supposons que l’on veuille constituer une représentation par objets d’un département
informatique. Si l’on s’intéresse aux «pièces» qui composent ce département, on peut dire, que l’on retrouve des
«salles de cours», des «salles de TP», des amphithéâtres, des bureaux, etc. On aura alors une représentation semblable à
celle ci-après.

CSALLE-DE-COURS
CSALLE-MACHINE
Tables
Tables
Chaises
Chaises
Capacité d’accueil
Capacité d’accueil
Type de tableau
Type de tableau

Nombre d’onduleurs
Afficher Type d’imprimante
… …

Afficher

En mettant certains champs en commun, on obtient la représentation ci-dessous:

. CSALLE .
Tables
Chaises
Capacité d’accueil
Type de tableau

Afficher

Est_un Est_un

CSALLE-DE-COURS CSALLEMACHINE
Rétroprojecteur Nombre d’onduleurs
… Type d’imprimante

Afficher

Afficher

Figure 6. Un exemple de composition et affinage

Pour terminer ce paragraphe, nous pouvons donner quelques recommandations, qui s’avèrent nécessaires si l’on
souhaite concevoir un système par objets :
♦ « Savoir revenir aux étapes précédentes », car il arrive rarement que les classes principales soient trouvées avec
exactitude, dès la première étape du processus, surtout qu’à côté des classes principales, des classes auxiliaires dues à la
programmation, viennent se greffer. Ces classes doivent être introduites naturellement en revenant à la première étape.
♦ « Prototyper rapidement avant de passer à une spécification complète », car il faut passer très rapidement à une
première ébauche du logiciel, qui permettra de spécifier le logiciel. Mais attention à une programmation sans
spécification.
♦ « Penser abstrait », car la conception par objets permet de définir des modèles du monde réel par abstraction des
classes et des opérations indépendantes de la nature des objets manipulés.
♦ Et enfin, « penser local », en ne cherchant pas à structurer globalement l’ensemble du système, mais en définissant
des opérations de portée locale.

Prof. Marcellin NKENLIFACK, mars 2013 10


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
2.5.4 APERÇU DES MÉTHODES D'ANALYSE OO
[Bouzegoub97, Rollan-H3248]
La pratique pousse les ingénieurs à passer directement des besoins informels des utilisateurs vers une solution technique
programmée. Les arguments développés par les vendeurs d'outils de développement rapides font croire à de nombreux
responsables que l'on peut se passer du temps de réflexion nécessaire à l'analyse et la spécification. L'absence de
schéma de synthèse, de spécification formelle, de documentation et de règles rend difficile toute opération de
modification, d'évolution ou de réutilisation. L'approche objet apporte les concepts nécessaires pour développer les
techniques et les outils de modélisation appropriés.
Les méthodes d'analyse objet classiques sont très souvent semi-formelles et liées à la mise sur pied de systèmes
d'informations (SI). Bien sûr, la contribution de l'objet est importante ici: décrire une grande partie de la dynamique du
SI comme un ensemble d'opérations attachées aux objets composant ce système. Ceci donne une meilleure
compréhension de la sémantique des objets et permet une meilleure modularité et réutilisabilité des composants du
système. Comme exemples de méthodes de cette catégorie, on peut citer OOD [Booch91], HOOD [Delatte93], OMT
[Rumbaugh91], OOSE [Jacobson92], OOA [Shlaer92], FUSION [Coleman94], OOA/OOD [Coad91a, Coad91b], OOM
[Bouzeghoub94].
Les modèles formels constituent les pierres angulaires des méthodes de conception et de développement orientées
objets. Le choix du modèle donne des indications plus objectives sur les capacités de modélisation de la méthode, sur sa
facilité d'utilisation et sur ses chances d'être supportées par les outils du génie logiciels. La plupart des méthodes de
conception utilisent une hiérarchie de modèles décrivant successivement le niveau conceptuel, le niveau logique et le
niveau physique. On peut répartir les méthodes en deux catégories selon qu'elles utilisent des modèles spécifiques ou
des modèles classiques avec d'éventuelles extensions (relationnel ou entité-association). On retrouve dans la première
catégorie les méthodes OOD et HOOD, et dans la seconde catégorie les méthodes OOA/OOD, OMT et OOM. En fait,
dans la première catégorie de méthodes, l'accent est plus mis sur les interactions entre objets ou la structuration interne
d'un objet. Ce qui est un peu l'inverse dans la seconde catégorie ou les objets désignent des entités (BD). La méthode
OOSE combine les deux approches en proposant des objets entités (persistants) et des objets contrôles (programmes).
On peut considérer globalement que OOD et HOOD sont plus des méthodes de programmation que des méthodes de
conception. Elles sont destinées principalement aux applications développées en ADA ou en C++. OOA, OMT et
FUSION ont la même philosophie; elles s'appuient sur trois niveaux: statique, dynamique et fonctionnel. Mais OMT est
plus riche en concepts et possède une démarche plus adaptée aux applications complexes. Le processus de FUSION est
plus complet; il permet d'aller plus facilement de la spécification au code. Mais FUSION et OOA n'intègrent réellement
le concept de l'objet qu'au niveau logique. Par son modèle statique, OOA est plus une méthode relationnelle qu'une
méthode objet. OOA/OOD est une méthode basée sur un seul modèle, elle intègre pleinement les concepts objets mais
son cycle de développement est très peu formalisé, il demeure intuitif, y compris au niveau logique. OOSE est une
méthode originale, en ce sens que c'est une des seules qui intègre complètement la conception des interfaces homme-
machine. Sa philosophie, proche de Smalltalk, la rapproche davantage de l'objet que certaines méthodes. OOM est un
exemple de méthode classique qui a évolué vers l'objet. Son modèle dynamique se décrit à l'aide de règles actives qui
s'implémentent sous forme de «triggers». Son modèle fonctionnel est basé sur les réseaux de Pétri et de ce fait permet
une simulation du fonctionnement de ses modèles et un meilleur contrôle au niveau logique.
On constate qu'il existe un grand nombre de méthodes objets. C’est pourquoi on est rapidement passé à l’unification.
C'est le cas de la méthode FUSION. Un projet intéressant de standardisation des notations issues de l'unification des
méthodes, c'est la notation UML (Unified Modeling Language), initiée par Booch, Rumbaugh et Jacobson, et
standardisée depuis plusieurs années par l'OMG. Le projet UML a vite dépassé le cadre de la fusion des trois méthodes
OOD, OMT et OOSE, et a intégré implicitement ou explicitement de nombreux concepts et notations des autres
méthodes objets.
La plupart des méthodes possèdent des outils logiciels qui aident dans leur mise en œuvre. Cependant, ces outils
semblent encore en deçà des promesses de la technologie objet. La plupart d'entre eux sont principalement constitués
d'un dictionnaire de données, d'éditeurs graphiques, et, dans le meilleur des cas, d'outils de contrôle des modèles et de
génération des squelettes de classes (code) de l'application.

2.6 LES LANGAGES A OBJETS


2.6.1 LES SEPT PROPRIETES DES LANGAGES OBJETS
[Bouzegoub97, Delannoy 01]
Il est utile de distinguer différents critères permettant de qualifier un langage objet, car le terme « objet » est souvent
utilisé à tort et à travers. D’après B. MEYER, les systèmes qui possèdent tous ces critères peuvent être nommés
«langages objets».
• Structure modulaire fondée sur les objets
Ce premier critère part du principe essentiel de la définition par objets : « les données fournissent le principal critère de
structuration ». Ainsi, les systèmes sont organisés en modules fondés sur leurs structures de données.

Prof. Marcellin NKENLIFACK, mars 2013 11


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet
• Abstraction de données
Ce deuxième critère permet de décrire les objets comme des Types de Données Abstraits (TDA). Généralement, la
plupart des langages de programmation atteignent ce niveau.
• Gestion automatique de la mémoire (allocation-désallocation)
Ce troisième critère est lié à l’implémentation des objets à savoir comment ceux-ci sont gérés au sein de la machine. C’est
pourquoi, il est important que dans ces langages, les objets non utilisés par le système soient désalloués sans l’intervention du
programmeur. Généralement, peu de langages appliquent ce principe.
• Classes
Ce quatrième critère permet de définir la notion principale de classe et de distinguer réellement les langages objets du reste du
monde : « tout type est un module et tout module de haut niveau est un type ».
• Héritage
Ce cinquième critère découle naturellement du critère précédent : « une classe peut être définie comme une extension ou une
restriction d’une autre classe ». La nouvelle classe ainsi créée devient « héritière » de l’autre. Ces techniques ouvrent la
possibilité du polymorphisme.
• Polymorphisme et liaison dynamique
Ce critère permet de définir la notion suivante : « une entité de programme doit pouvoir faire référence à des objets de
plusieurs classes, et une opération doit pouvoir avoir des versions différentes dans les classes différentes ».
• Héritage multiple
Dans ce dernier critère qui permet d’introduire la notion d’héritage multiple, « il doit être possible de déclarer qu’une classe
hérite de plus d’une classe, et plus d’une fois de la même classe ».

2.6.2 QUELQUES LANGAGES OBJETS ET LEURS APPLICATIONS


[Bouzegoub97, ObjetsWc, Delannoy01]
- SIMULA (1967) : il fut historiquement le premier langage à objets [Bouzegoub97]. Ce langage est adapté pour simuler
des systèmes parallèles.
- SMALLTALK (1976) : est un des premiers langages à objets de référence à environnement graphique, tourné vers la
communication homme-machine. Il excelle dans le prototypage des applications, les systèmes interactifs et la
programmation des simulations.
- ADA : est un langage d'usage général destiné au temps réel. Ce n'est pas à proprement parlé un langage à objets, mais il
intégrait dès sa version 83 la notion de type abstrait.
- C++ (1982) : est un langage à objets puissant, compatible avec le langage C ; il introduit notamment les opérateurs de
fonctions et de gestion mémoire définis par l’utilisateur.
- Object Pascal : est une extension du Pascal développée au début des années 80 par Apple pour Macintosh. Mais par la
suite, plusieurs versions ont vu le jour.
- EIFFEL : langage écrit en C, purement orienté objet, il a été conçu pour les applications scientifiques et la gestion.
- Ojective C : est une extension du C par le biais d'un pré-processeur qui importe en C un modèle inspiré de Smalltalk 80.
Ce langage a été utilisé pour écrire le système interactif des machines Next de Steve Jobs.
- ACT1, ACT2, PLASMA, MERING : sont des langages dits d’acteurs, qui mettent plus l’accent sur le parallélisme et le
contrôle décentralisé. Destinés aux ordinateurs multiprocesseurs.
- LOOPS, SNARK, KOOL sont destinés à des applications de l’IA (Intelligence Artificielle - Systèmes experts).
- FORMES : est un langage conçu pour la synthèse musicale.
- ROSS est idéal pour les applications de simulation.
- CEYX est adapté aux applications nécessitant un grand nombre d’objets.
- OOVHDL est un nouveau langage objet dont on parle de plus en plus, langage Hardware adapté à la description des
systèmes matériels en général, et des circuits électronique (circuits intégrés) en particulier. Une description complète du
langage peut être obtenue à partir de [Ashenden98W, Ashenden99, AshRad99, Nebel98, Nebel99].
- JAVA : est un langage objet adapté à la programmation de composants pour des applications en réseau et client-serveur,
notamment autour du Worl Wide Web, et des composants mobiles.
- Python : langage interprété, multi-paradigme, et multi-plateformes, favorisant la programmation impérative structurée et
orientée objet. Il est doté d'un typage dynamique fort, d'une gestion automatique de la mémoire par ramasse-miettes et d'un
système de gestion d'exceptions ; il est ainsi similaire à Perl, Ruby, Scheme, Smalltalk et Tcl.
- Ruby : langage de programmation libre (open source). Il est interprété, orienté objet et multi-paradigme. Le langage a été
standardisé au Japon en 2011, (JIS X 3017:2011)1, et en 2012 par l'Organisation internationale de normalisation (ISO
30170:2012).

Prof. Marcellin NKENLIFACK, mars 2013 12


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Approche Objet

2.7 CONCLUSION
L'idée majeure qui préside dans le concept objet consiste à conserver la même philosophie depuis l'analyse des besoins à
partir du monde réel, la spécification jusqu'à sa réalisation, en l'occurrence celle des objets.
Pour conclure ce chapitre, nous pouvons donner quelques recommandations, qui s’avèrent nécessaires si l’on souhaite
concevoir un système par objets :
♦ « Savoir revenir aux étapes précédentes », car il arrive rarement que les classes principales soient trouvées avec
exactitude, des la première étape du processus, surtout qu’à coté des classes principales, des classes auxiliaires dues à la
programmation, viennent se greffer. Ces classes doivent être introduites naturellement en revenant à la première étape.
♦ « Prototyper rapidement avant de passer à une spécification complète », car il faut passer très rapidement à une
première ébauche du logiciel, qui permettra de spécifier le logiciel. Mais attention à une programmation sans spécification.
♦ « Penser abstrait », car la conception par objets permet de définir des modèles du monde réel par abstraction des
classes et des opérations indépendantes de la nature des objets manipulés.
♦ Et enfin, « penser local », en ne cherchant pas à structurer globalement l’ensemble du système, mais en définissant
des opérations de portée locale.

Prof. Marcellin NKENLIFACK, mars 2013 13


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java

3 LES OBJETS ET LE LANGAGE JAVA

3.1 HISTORIQUE ET EVOLUTION


[wwwJavaWiki] [Delannoy 01]
Java est une technologie composée d'un langage de programmation orienté objets et d'un environnement
d'exécution. Préalablement nommé Oak, il a été créé par James Gosling et Patrick Naughton chez Sun Microsystems
avec le soutien de Bill Joy. Les premières réflexions conceptuelles de début remontent pratiquement à 1991. A cette
époque, des ingénieurs de chez Sun Microsystems Inc. ont cherché à concevoir un langage applicable à de petits
appareils électriques (on parle de code embarqué). Pour ce faire, ils se sont fondés sur une syntaxe très proche de
celle de C++, en reprenant le concept de « machine virtuelle » déjà exploité auparavant par le Pascal UCSD. L’idée
consistait à traduire d’abord un programme source, non pas directement en langage machine, mais dans un pseudo
langage universel, disposant des fonctionnalités communes à toutes les machines. Ce code intermédiaire, dont on dit dit
qu’il est formé de byte codes, se trouve ainsi compact et portable sur n’importe quelle machine ; il suffit simplement
que cette dernière dispose d’un programme approprié (appelé machine virtuelle permettant de l’interpréter dans le
langage de la machine concernée).
Puis, ce projet de langage pour code embarqué a été réorienté (à l’époque) et ses concepts ont été repris dans la
réalisation du logiciel HotJava, un navigateur Web écrit par SUN en « Java », et capable d’exécuter des « applets »
écrites justement en byte codes. En effet, de juin à juillet 1994, après trois jours de remue-méninge avec John Gage,
James Gosling, Joy, Naughton, Wayne Rosing et Eric Schmidt, l'équipe recentra la plateforme sur le Web. Ils
pensaient qu'avec l'avènement du navigateur Mosaic, Internet était le lieu où allait se développer le même genre d'outil
interactif que celui qu'ils avaient envisagé pour l'industrie du câble. Naughton développa comme prototype un petit
navigateur Web, WebRunner qui deviendra par la suite HotJava. La même année le langage fut renommé Java après
qu'on eut découvert que le nom Oak était déjà utilisé par un fabricant de carte video.
En octobre 1994, HotJava et la plateforme Java furent présentés par « Sun Executives ». Java 1.0a fut disponible en
téléchargement en 1994 mais la première version publique de Java (y compris le navigateur HotJava) fut présentée le 23
mai 1995 à la conférence SunWorld. L'annonce fut effectuée par John Gage, le directeur scientifique de Sun
Microsystems. Son annonce fut accompagnée de l'annonce surprise de Marc Andressen, vice-président de l'exécutif de
Netscape que Netscape allait inclure le support de Java dans ses navigateurs. Le 9 janvier 1996, le groupe Javasoft fut
constitué par Sun Microsystems pour développer cette technologie. Deux semaines plus tard, la première version
officielle de Java était disponible.
Par la suite, l’exemple de HotJava a été suivi par les autres navigateurs Web, ce qui a contribué à l’essor du langage qui
a considérablement évolué depuis cette date, sous forme de versions successives.
L'évolution de Java est dirigée initialement par le JCP (Java Community Process) qui utilise les JSR (Java
Spécifications Requests) pour proposer des ajouts et des changements sur la plateforme Java.
- JDK 1.0a : 1994
- JDK 1.0, 1.01, 1.02 : 1996
- JDK 1.1 : 1997
- JDK 1.2 [J2SE] : 1998 (baptisée Java 2 Platform, Standard Edition)
- JDK 1.3 [J2SE] : 2000
- JDK 1.4 [J2SE] : 2002 ( / nom de code : Merlin )
- JDK 1.5 [J2SE] : 2004 ( dite Java 5.0 / nom de code : Tiger )
- JDK 1.5.1 [JSE] : 2004 (/ nom de code : Dragonfly )
- JDK 1.6 [JSE] : 2006 ( dite Java SE 6 / nom de code : Mustang )
- JDK 1.7 [JSE]: 2008 ( dite Java SE 7 / nom de code : Dolphin )
Java permet de développer des applications autonomes mais aussi, et surtout, des applications client-serveur. Côté
client, les applets sont à l'origine de la notoriété du langage. C'est surtout côté serveur que Java s'est imposé dans le
milieu de l'entreprise grâce aux servlets, le pendant serveur des applets, et plus récemment les JSP (Java Server Pages)
qui peuvent se substituer à PHP et ASP. Les applications Java peuvent être exécutées sur tous les systèmes
d'exploitation pour lesquels a été développée une plateforme Java, dont le nom technique est JRE (Java Runtime
Environment - Environnement d'exécution Java). Cette dernière est constituée d'une JVM (Java Virtual Machine -
Machine Virtuelle Java), le programme qui interprète le code Java et le convertit en code natif. Mais le JRE est surtout
constitué d'une bibliothèque standard à partir de laquelle doivent être développés tous les programmes en Java. C'est la
garantie de portabilité qui a fait la réussite de Java dans les architectures client-serveur en facilitant la migration entre
serveurs, très difficile pour les gros systèmes.
A Propos de l’appelation « Java »
- Oak ("Chêne") est le nom donné à Java dans un premier temps mais celui-ci était déjà utilisé.
- Java en l'honneur du nom argotique (en Amérique du Nord) du breuvage le plus consommé par les développeurs,
c'est-à-dire le café, dont une partie de la production vient de l'île de Java.

Prof. Marcellin NKENLIFACK, mars 2013 14


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
On remarque qu'en décalant d'une lettre chaque consonne on obtient kawa qui est aussi un nom argotique pour café!
Le nom Java fut inventé dans un petit bar fréquenté par quelques membres de l'équipe. Il n'est pas clair de savoir si oui
ou non le nom est un acronyme, bien que certains prétendent qu'il signifie James Gosling, Arthur Van Hoff et Andy
Bechtolsheim ou tout simplement Just Another Vague Acronym (littéralement juste un autre vague acronyme). La
croyance selon laquelle Java doit son nom aux produits vendus dans le bar est le fait que le code sur 4 octets des fichiers
de classe est en hexadécimal 0xCAFEBABE. Certaines personnes prétendent également que le nom de Java vient du fait
que le programme était destiné à pouvoir tourner sur des systèmes embarqués, comme des cafetières (Java signifie café
en argot américain).

3.2 INTRODUCTION
Définition initiale de Sun Microsystems: "Java est un langage simple, orienté objet, distribué, robuste, sûr,
indépendant des architectures matérielles, portable, de haute performance, multithread et dynamique".
Lors de la création du langage Java, il avait été décidé que ce langage devait répondre à 5 objectifs :
- utiliser une méthodologie orientée objet,
- permettre à un même programme d'être exécuté sur plusieurs systèmes d'exploitation différents,
- pouvoir utiliser de manière native les réseaux informatiques,
- pouvoir exécuter du code distant de manière sûre,
- être facile à utiliser et posséder les points forts des langages de programmation objet comme le C++.
Le langage JAVA est donc un langage Orienté Objet devenu incontournable pour tout développement important
(notamment sur Internet/Intranet/Extranet). Il permet de développer des applications capables de s’exécuter sur
n’importe quelle plateforme (Windows 95/98/NT/2000/XP/2003/Vista/2008/2012, Unix, Mac-OS, OS400, Amiga-OS,
Next, ...) dotée d’une Machine Virtuelle Java (MVJ).
Plusieurs types de programmes peuvent être générés par JAVA :
• Les Applets (prononcer « Appelletes ») prévues pour fonctionner à l’intérieur d’une page Web, dans un logiciel
de Navigation ;
• Les Applications qui sont des programmes autonomes n’ayant besoin que de la MVJ ;
• Les servlets qui tournent sur les serveurs (en environnement client-serveur) ;
• Les midlets pour des petits systèmes ou équipements.
Java se décline en plusieurs types d’environnements de réalisation :
• JSE (Java Standard Edition)
• JME (Java Mobile Edition) : version allégée de JSE, adaptée en général aux appareils de « faible puissance ».
• JEE (Java Enterprise Edition)
Le langage est pratiquement stable depuis le JDK 1.0 ; les bibliothèques de classes fournies se sont agrandies et ont
changé en partie. À partir de la version 1.2, le JDK a été renommé en J2SDK (Java 2 Software Development Kit / kit de
développement de logiciels Java 2) et on appelle souvent ces versions Java 2.
Du fait de l'accroissement des bibliothèques et des changements entre versions, la compatibilité est assurée dans un seul
sens : les programmes Java compilés avec une version antérieure du JDK (par exemple 1.2) continueront à fonctionner
avec un JRE plus récent (par exemple 1.9), mais le contraire n'est pas vrai.

Java est habituellement compilé vers une machine virtuelle standardisée, sous forme de bytecode. Cette machine peut
fonctionner avec un interpréteur, un compilateur just-in-time (à la volée), ou, le plus couramment, avec un mélange des
deux. Il existe des variantes de ce schéma :
• permettant de compiler le langage Java nativement, c’est-à-dire de produire un exécutable capable de
fonctionner hors de l'environnement Java, et même de produire un exécutable capable de fonctionner dans
l'environnement CLR de Microsoft .NET, grâce à la variante J# de Java, créée par Microsoft.
• permettant de produire un exécutable Java à partir d'autres langages, comme Python à l'aide du
compilateur Jython, ou encore Groovy.

Version interprétée
Il existe plusieurs versions interprétées de Java (langages de scripts s'exécutant sur une JVM): beanshell et Groovy
sont standardisés au sein du JCP (Java Community Process). Jython, JRuby et d'autres langages de scripts proposent
des langages sur ce même principe. L'interpréteur de ces langages peut être embarqué dans une application Java pour la
rendre scriptable. A noter qu'à partir de Java 6, le moteur Rhino (JavaScript) est embarqué dans la JRE.

3.3 RAPPELS DES PRINCIPES DE LA PROGRAMMATION ORIENTEE OBJET :


Au fur et à mesure que la complexité des programmes s’est accrue, il est apparu de plus en plus manifeste que la
clef d’une bonne conception était la possibilité de réutiliser des éléments du programme. De ce point de vue, l’approche
fonctionnelle a fini par atteindre une limite. La décomposition des fonctions ne s’avère pas suffisamment structurante

Prof. Marcellin NKENLIFACK, mars 2013 15


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
pour appréhender les énormes programmes de plusieurs millions de lignes de code qui se développent de plus en plus
fréquemment à travers le monde.
Pour concevoir dans la perspective orientée objet, on commence par identifier les structures pertinentes pour la
réalisation du programme. Puis, idéalement, on identifie l’ensemble des traitements qui s’appliquent naturellement à ces
structures, indépendamment de toute visée applicative.
C’est seulement à ce stade que l’on construit l’ensemble des traitements constituant le programme sur la base de ces
traitements « naturels ».
Un programme est alors vu comme un ensemble de traitements qui s’appliquent sur certains objets et
déclenchent d’autres traitements sur d’autres objets.
La programmation orientée objet existe depuis 1967 (Simula). Cependant, elle n'est vraiment devenue un des
paradigmes de la programmation qu'au milieu des années 1980.
La principale différence entre la programmation structurée traditionnelle et la programmation orientée objet est
que cette dernière met dans une même structure les données et les opérations qui leurs sont associées. En
programmation traditionnelle, les données et les opérations associées sont séparées, et cette méthodologie nécessite
l'envoi des structures de données aux procédures et fonctions qui les utilisent. La programmation orientée objet résout
de nombreux problèmes inhérents à cette conception en mettant dans une même entité les attributs et les opérations.
Cela est plus proche du monde réel, dans lequel tous les objets disposent d'attributs auxquels sont associées des
activités.
Java est un pur langage orienté objet, ce qui signifie que le niveau le plus externe de la structure des données est l'objet.
Dans Java, il n'y a pas de constantes, variables ou fonctions autonomes, car l'accès se fait toujours par des classes et des
objets. Il s'agit là d'une des « fonctions » les plus sympathiques de Java par rapport à d'autres langages orientés objet
hybrides qui gardent des aspects de langages structurés et ajoutent des extensions d'objets. Par exemple, C++ et Object
Pascal sont des langages objet, mais permettent toujours d'écrire des programmes structurés, ce qui diminue l'efficacité
des extensions orientées objets.

3.4 BASES DU LANGAGE JAVA


Les identificateurs servent à identifier des variables, des méthodes et des classes de façon unique. Ils doivent
commencer par un trait de soulignement, un signe dollar ou une lettre. Ils peuvent inclure des chiffres et différencient
les minuscules et les majuscules.
Les littéraux représentent des valeurs constantes. Ils peuvent être utilisés dans des expressions et des affectations de
variables.
Les séquences d'échappement représentent des caractères de contrôle spéciaux et des caractères non imprimables.
Les blocs de code permettent de regrouper des instructions reliées les unes aux autres.
Une expression est une entité qui a une certaine valeur. Les expressions peuvent combiner des identificateurs, des mots
clés, des opérateurs et des symboles.
Les opérateurs de Java couvrent les types suivants : arithmétique, logique, de comparaison, d'affectation et au niveau
bits. Certains opérateurs sont unaires et d'autres sont binaires.
Java a aussi emprunté à C/C++ un opérateur ternaire ( ?: ).
Java prend en charge des types de données primitifs (types numérique, booléen et caractère), ainsi que des types de
données composites (tableaux et chaînes). Les types de données de Java sont différents de ceux de C/C++, car Java
n'utilise pas de tableaux de caractères pour représenter les chaînes et ne représente pas les valeurs booléennes par des 0
et des 1. En outre, les types nombre entier de Java sont toujours signés ; dans C/C++, ils sont signés par défaut.
Dans Java, il y a trois structures de boucle : la structure while, la structure do et la boucle for. La boucle for est la plus
souple des structures de boucle de Java.
Dans Java, il y a deux instructions conditionnelles: if et switch.

3.5 IMPLEMENTATION DES CLASSES ET DES OBJETS EN JAVA


[wwwJavaMem]
• Une Classe est une collection de données (attributs ou champs) et de méthodes (traitements) qui agissent sur ces
données. (Exemple de classe : la classe « ANIMAL »).
• Un Objet est une instance particulière d’une classe (les objets «Chat» et « Poule » sont des instances particulières de
la classe « ANIMAL»).
• Un objet est déclaré comme n'importe quelle autre variable et il est instancié par le mot clé « new ».
• Dans une classe, n'importe quel type (primitif et objet) peut figurer.
• Les champs d’un objet (variables/attributs et méthodes) sont accessibles par la notation pointée sur cet objet,
unObjet.saVariable, unObjet.saMéthode( )
• Cycle de vie des objets :

Prof. Marcellin NKENLIFACK, mars 2013 16


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
On appelle cycle de vie d’un objet, l’ensemble des états par lesquels il passe au cours de l’exécution d’un
programme. En règle générale, les étapes de la vie d’un objet sont sa construction, son initialisation, parfois sa
modification ou sa copie, puis sa destruction et son élimination de la mémoire.

• Initialisation
Lorsqu’un objet est créé, tous ses champs sont initialisés à une valeur nulle (false pour un booléen, null pour une
référence d’objet et 0 pour une valeur). Le constructeur est alors invoqué. Son travail se fait en trois phases.
1. Invocation éventuelle du constructeur de la classe mère ;
2. Initialisation des champs en utilisant la valeur d’initialisation spécifiée lors de leur déclaration ;
3. Exécution du corps du constructeur.
Il est vivement recommandé d’initialiser explicitement toutes les variables dès leur déclaration, plutôt que de les
déclarer d’abord et de ne les initialiser qu’ensuite.
Si vous cherchez à les utiliser entre le moment où elles sont déclarées et le moment où elles sont utilisées, vous risquez
des mauvaises surprises lors de l’exécution.
Heureusement, le compilateur JAVA signale la plupart de ces tentatives d’utilisation illicites de variables non
initialisées.

• On distingue en général 4 types de méthodes : les constructeurs (constructor), les méthodes d’accès (ou
accessor ; forme getXXX) et les méthodes d’altération (ou mutator ; forme setXXX) et les destructeurs.
Notez qu’il est toujours prudent de prévoir une méthode d’accès pour chacun des champs privés d’un objet. En effet il
ne faut pas oublier qu’il doit toujours être possible de modifier l’implémentation d’une classe de manière transparente
pour son utilisateur.
En général, les attributs d’une classe sont déclarés privés ou protégés, ce qui signifie que seuls des objets de la classe ou
de ses sous-classes peuvent les lire et les modifier. Pour accéder à ces attributs de l’extérieur, on ajoute à la classe des
méthodes spécialement conçues à cet effet, que l’on appelle « accesseurs » – et parfois « modifieurs » quand il s’agit
de modifier la valeur.
• Les méthodes d'accès "get" et "set" servent à encapsuler la représentation des données internes dans la fiche des
variables membre privées.
• Un constructeur n’est rien d’autre qu’une méthode sans valeur de retour portant le même nom que la classe. La
notion de constructeur permet d’automatiser le mécanisme d’initialisation d’un objet. Un constructeur est une
méthode spéciale qui affecte toutes les ressources de la classe.
La création d’un objet entraîne toujours par ordre chronologique les opérations suivantes :
- initialisation par défaut (implicite) de tous les champs de l’objet ;
- initialisations explicites lors de la déclaration de champs ;
- exécution des instructions du corps du constructeur.
• Les variables d’instances (non-static) sont propres à chaque objet, instance d’une classe.
• Les variables de classe (static) sont associées à la classe. Il n’y a qu’une seule copie de cette variable sans égards
aux nombres d’instances de cette classe. Il s’agit en fait d’une donnée globale partagée par toutes les instances d’une
même classe.
• Les méthodes de classe (static) ne sont pas accompagnées d’un argument implicite this et ne peuvent utiliser les
méthodes et variables d’instances de la classe.
Pour appeler une méthode statique d’une classe, on utilise en général le nom de la classe plutôt qu’une de ses
instances. Cela évite d’avoir à appeler le constructeur de la classe et de construire une instance. L’intérêt des
méthodes statiques est en effet de pouvoir être appelées alors qu’on ne dispose pas d’un objet de la classe dans
laquelle elle est définie.
• Les méthodes d’instance d’une classe sont accompagnées d’un argument implicite this qui identifie l’objet sur
lequel elles opèrent.
• Les objets sont créés avec le mot réservé new, qui invoque un constructeur de classe (méthode) avec éventuellement
une liste d’arguments. Ils peuvent être détruits avec la méthode dispose().
• En général, les objets ne sont pas explicitement détruits. Le « Ramasse-miettes » (« Garbage collector ») de Java
détruit automatiquement les objets qui ne sont pas utilisés.
• La zone du « tas », « garbage collectée » : La zone du tas est l’endroit ou « vivent » les objets d’un programme
JAVA. À chaque création d’objet par l’opérateur new, la mémoire consommée par cet objet est allouée dans cette
zone du tas. Le langage JAVA ne permet pas de libérer explicitement ou de dés-allouer directement cette mémoire.
Par contre, l’environnement d’exécution conserve les références vers chaque objet sur le tas et libère
automatiquement la mémoire occupée par les objets qui ne sont plus référencés. Ce processus est appelé «
ramassage des déchets ».
• Un finaliseur est une méthode automatiquement appelée par le Garbage collector juste avant la destruction d'un
objet.

Prof. Marcellin NKENLIFACK, mars 2013 17


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
• Chaque classe est normalement dotée de méthodes servant de constructeur (exécutée à la création de chaque
objet instance) et éventuellement d’un destructeur.
• Si la première ligne d’une méthode constructrice n’invoque pas un autre constructeur avec un this(), ou un
constructeur de la superclasse avec super(), Java automatiquement insert un appel au constructeur de la superclasse
qui ne prend pas d’argument.
• Le mot clé this fait référence à la classe actuelle. Il permet qu’un objet puisse connaître sa référence sur lui-même.
Cela permet à l’objet de transmettre sa référence à un autre objet, par exemple pour s’abonner à un service qu’il
fournit.
• Le mot clé super permet de désigner l’objet père de l’objet courant, pour appeler une méthode d’un objet de la
classe mère lorsqu’elle n’a pas la même définition au niveau de la sous-classe. Il peut servir à référencer une
variable membre d'une classe parent ou à appeler le constructeur d'une classe parent. On peut par exemple réaliser
l’appel suivant :
public class B extends A
{
public String decritMere()
{
return super.toString();
}
}

• Si une classe ne définit pas de constructeur, Java procure un constructeur par défaut qui se contente
d’allouer un emplacement mémoire.
• L'héritage est implémenté en utilisant le mot clé extends.
• Une classe peut hériter de méthodes et de variables non préfixées par private, d’une autre classe en se définissant
comme sous-classe de cette classe à l’aide de la clause extends.
• Jav.lang.Object est la super classe par défaut, c’est la classe racine, elle n’a pas de super classe.
La classe Object sert à définir l’objet le plus générique qui soit. Toute classe peut être conçue comme héritant de la
classe Object. La classe Object dispose de quelques méthodes qu’on peut soit utiliser telles quelles soit redéfinir.
Quelques méthodes de la classe Object :
public boolean equals(Object obj)
Teste l’égalité des valeurs de l’objet receveur et de l’objet passé en paramètre.
public int hashCode()
Retourne le code de hachage de cet objet, pour le ranger dans une Hashtable.
public Object clone() throws CloneNotSupportedException
Permet d’effectuer une copie superficielle des objets. Cependant, il existe une interface destinée à faciliter la gestion du
clonage (copie profonde) des objets. Il s’agit de l’interface cloneable qu’on peut implémenter, puis redéfinir la méthode
clone.
public final Class getClass()
Retourne un objet de type Class qui représente la classe de cet objet et contient notamment le nom de la classe,
accessible par getName().
public void finalize() throws Throwable
Finalise l’objet lors de l’appel du garbage collector.
Parmi ces méthodes, on peut citer quelques-unes qui sont importantes : « toString » et « equals ». La méthode
toString fournit une chaîne (nom de la classe + adresse de l’objet en hexadécimal précédé de @) tandis que la
méthode equals compare les adresses des deux objets concernés.
• La redéfinition est le fait de redéfinir une méthode héritée de sa superclasse. Il s’agit en fait de donner à une classe
spécifique une méthode qui porte le même nom et possède la même signature qu’une méthode d’un objet de la
classe générique dont elle hérite, mais dont le code est différent de cette méthode plus générique. Dans le cas où la
méthode plus générique est abstraite, on ne parle pas de redéfinition mais d’instanciation.
• La surcharge (ou surdéfinition = overload) des méthodes est le fait de déclarer plusieurs méthodes de même nom,
mais qui se différencient par leur signature (type de retour ou liste des arguments). La sur-définition est possible
dans une même classe ou dans des classes dérivées. Cette notion de polymorphisme permet de manipuler des objets
sans connaître (tout à fait) le type (classe, sous-classes ou sur-classes). Ce concept vient compléter l’héritage.
• Le polymorphisme offre la possibilité à deux objets distincts, mais reliés, de recevoir le même message et d'y réagir
presque différemment.
En plus, avec le polymorphisme un objet d’une classe peut être manipulé comme s’il appartenait à une autre
classe. En JAVA, le moyen de réaliser cela consiste à « caster » une classe en une autre. On parle aussi de
conversion de type. On ne peut « caster » que d’un type de base dans un autre, ou alors d’une classe vers une autre
classe plus générique ou plus spécifique. Toute autre tentative de « cast » est acceptée à la compilation mais lève
l’exception ClassCastException lors de l’exécution.
• Les règles du polymorphisme en Java :

Prof. Marcellin NKENLIFACK, mars 2013 18


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
→ Compatibilité. il existe une conversion implicite d’une référence à un objet de classe T en une référence à un objet
d’une classe ascendante de T (elle peut intervenir aussi bien dans les affectations que dans les arguments effectifs).
→ Ligature dynamique. Dans un appel de la forme X.f (…) où X est supposé de la classe T, le choix de f est
déterminé ainsi :
- à la compilation : on détermine dans la classe T ou ses ascendantes la signature de la meilleure méthode f convenant
à l’appel, ce qui définit du même coup le type de la valeur de retour.
- à l’exécution : on recherche la méthode f de signature et type de retour voulus, à partir de la classe correspondant
au type effectif de l’objet référencé par X (il est obligatoirement de type T ou descendant) ; si cette classe ne
comporte pas de méthode appropriée, on remonte dans la hiérarchie jusqu’à ce qu’on en trouve une (au pire,
remonter jusqu’à T).
• La liaison dynamique permet l’invocation de la bonne méthode, même si l’objet est instance d’une classe ayant
redéfinie cette méthode.
• Le mot clé final permet d’indiquer qu’un élément ne sera pas modifié. Dans le cas d’une variable, final
indique que la variable est une constante. En règle générale, les constantes sont aussi déclarées statiques, pour
gagner de la place en mémoire.
• Une classe déclarée final ne peut pas être redéfinie dans une classe dérivée.
• Les méthodes définies comme static, private, final ne peuvent être redéfinies, et ne sont pas sujettes à la liaison
dynamique. Cela permet au compilateur d’optimiser leur écriture et leur exécution.
• On peut invoquer une méthode d’une classe de base à l’aide du mot réservé super ; Alors que cette dernière est
redéfinie dans la classe dérivée.
• On peut se référer explicitement à une variable masquée avec le mot réservé super.
• Les données et les méthodes peuvent être cachées ou encapsulées à l’intérieur d’une classe en spécifiant les
modificateurs private, private protected, ou protected. Les données ou méthodes déclarées public sont visibles
partout. Si aucun modificateur n’est utilisé, les données ou méthodes sont visibles seulement à l’intérieur du
package.
* Description exhaustive de quelques « modificateur » d'accès et leurs rôles
- public
- public = la variable ou la méthode (ou le constructeur) ou la classe est accessible partout
- variable d'instance : rarement public sauf si final.
- private
- les variables ou les méthodes (ou constructeurs) ne sont accessibles que par les membres internes de la classe
- protected
- protected = les variables ou les méthodes (ou constructeurs) ne sont accessibles que par les membres internes
de la classe, de ses sous-classes et des classes du même package.
- classe protected = accessible que par ses sous-classes et des classes du même package.
- private protected
- les variables ou les méthodes ne sont accessibles que par les membres internes de la classe, de ses sous-
classes.
- abstract :
- une méthode abstraite ne contient pas de corps, mais doit être implémentée dans les sous-classes,
- une classe est abstraite si elle contient au moins une méthode abstraite ; elle ne peut pas être instanciée, mais
ses sous-classes non abstraites le peuvent. Il faut noter qu’une interface est par défaut abstraite.
Par exemple, bien que toutes les formes fermées en deux dimensions aient une surface, on peut ne pas désirer
calculer cette surface pour une forme quelconque. Par contre, on sait calculer la surface d’un rectangle, un
triangle ou un cercle.
Une classe abstraite ne permet pas d’instancier des objets.
- native
- méthode écrite en un autre langage ( C ) dans un fichier externe.
- synchronized
- variable à accès en exclusion mutuelle pour les threads.
- transcient
Java introduit le mot clé transient qui précise que l'attribut qu'il qualifie ne doit pas être inclus dans un processus de
sérialisation et donc de désérialisation.
private transient String codeSecret;
En effet, le contenu des attributs est visible dans le flux dans lequel est sérialisé l'objet. Il est ainsi possible pour toute
personne ayant accès au flux de voir le contenu de chaque attribut même si ceux si sont private. Ceci peut poser des
problèmes de sécurité surtout si les données sont sensibles.
• Une interface ne peut pas contenir de code ni de variable membre non constante. Une interface est comme une
classe abstraite n’implantant aucune méthode et aucun champ, hormis les constantes (static final). Déclarer une

Prof. Marcellin NKENLIFACK, mars 2013 19


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
interface crée l’équivalent d’un nouveau type de donnée. En effet, une interface ne définit que les en-tête d’un certain
nombre de méthodes ainsi que des constantes
En JAVA, une interface est une entité spécifique du langage. Il y a deux façons de considérer une interface :
- On peut la voir comme une classe complètement abstraite, dont toutes les méthodes sont abstraites. On dit qu’une
classe hérite d’une autre classe, mais qu’elle implémente une interface.
- On peut aussi la voir comme une spécification de toutes les méthodes que toute classe qui veut implémenter cette
interface doit contenir.
C’est la seconde vue qui domine en JAVA.
• Avec l'instruction import, il devient inutile de qualifier complètement les noms des classes (NomComplet /
Chemin).
• Une classe implante une interface avec la clause implements, et doit redéfinir les méthodes abstraites de l’interface.
Une classe peut implémenter plusieurs interfaces (astuce d’héritage multiple en Java).
• Les « classe enveloppes » sont destinée à manipuler des valeurs d’un type primitif en les encapsulant dans une
classe. Cela permet de disposer de méthodes et de compenser le fait que les types primitifs ne soient pas des classes. Il
s’agit des classes Boolean, Byte Character, Short, Integer, Long, Float, Double, etc. Toutes ces classes disposent d’un
constructeur recevant un argument d’un type primitif.
• Les champs d’un objet (variables et méthodes) sont accessibles par la notation pointée sur cet objet.
Exemple: Rect1.Surface( );

- Largeur CLASSES
- Hauteur - Rayon
Surface ( ) Surface ( )
Périmetre ( ) Perimetre ( )

INSTANCES
Disq1
Rect 1 (Objets)
Rect 3 Disq2 Disq3
Rect 2
Rectangle Disque

Figure 7. Exemple de classe et instances

Exemples de définition des classes « Rectangle » et « Disque »


Class rectangle
{
double largeur, hauteur; //données
Rectangle (double initL, double initH) //constructeur
{
largeur = initL;
hauteur = initH;
}
double surface () {return largeur*hauteur; } //Méthode
}
Class Disque
{
double rayon;
static final double pi = 3.14159;
Disque (initR) {rayon = initR; }
double surface () {return (pi*rayon*rayon); }
}
Le type du résultat, le nom de la méthode et le type des paramètres forment ce
qu’on appelle la « signature de la méthode ».
• Les « classes anonymes » permettent de définir ponctuellement une classe sans lui donner un nom.
Il est possible de créer un objet d’une classe dérivée de la classe A, en utilisant une syntaxe de cette forme :
A a ;
a = new A();
{
// champs et méthodes qu’on introduit dans la classe anonyme
// dérivée de A

Prof. Marcellin NKENLIFACK, mars 2013 20


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
} ;
tout se passe comme si l’on avait procédé ainsi :
A a ;
class A1 extend A
{
// champs et méthodes spécifiques à A1
} ;
… … …
a = new A1() ;
Cependant, contrairement au premier cas, il serait possible dans ce dernier cas de définir des références de type A1.
• Bien que l’encapsulation des données ne soit pas obligatoire en Java, il est vivement conseillé d’y recourir
systématiquement en déclarant tous les champs privés.

• Passage de paramètres
En JAVA, le passage de paramètres s’effectue par valeur (la transmission d’un argument à une méthode et celle de son
résultat ont toujours lieu par valeur). Cela signifie que, lors de l’appel d’une méthode, JAVA effectue une copie de la
variable provenant de la méthode appelante et passée en paramètre. C’est sur la copie que travaille la méthode appelée. La
portée de cette copie est limitée à la méthode dans laquelle elle est passée en paramètres.
Par conséquent, si la valeur de la variable est modifiée dans la méthode appelée, cette modification n’est pas répercutée
dans la méthode appelante, à moins que la variable ne soit renvoyée en valeur de retour et affectée explicitement à la
variable de la méthode appelante.
Pour le cas des objets transmis en argument : une méthode d’un objet A est autorisée à accéder aux champs privés d’un
autre objet B de la même classe. On dit que en Java « l’unité d’encapsulation est la classe et non l’objet ». Bien entendu
lorsqu’une méthode d’une classe T1 reçoit en argument un objet de classe T2, différente de T1, elle n’a pas accès aux
champs ou méthodes privées de cet objet.
• Autoréférence par le mot-clé « this » : il permet de faire référence à un objet dans sa globalité (et non plus à
chacun de ses champs). Cas par exemple ou l’on souhaite transmettre un objet en argument d’une autre méthode. Pour
l’appel d’un constructeur au sein d’un autre constructeur, on peut aussi faire appel au mot-clé this que l’on utilise cette
fois comme un nom de méthode ; d’une manière générale, l’appel this (…) doit obligatoirement être la première
instruction du constructeur.
• La récursivité des méthodes : elle est autorisée par Java. Elle peut être directe (une méthode comporte dans sa
définition au moins un appel à elle-même) ou croisée (l’appel d’une méthode entraine l’appel d’une autre méthode qui à
son tour appelle la méthode initiale).
• Les classes internes : elles ont une définition située à l’intérieur de la définition d’une autre classe. Malgré certaines
ressemblances avec la notion d’objet membre, elle ne doit surtout pas être confondue avec elle, même si elle peut être
utilisée dans ce contexte.
Class E // définition d’une classe,usuelle (dite alors externe)
{… … … // méthodes et données de la classe E
Class I // définition d’une classe interne à la classe E
{… … // méthodes et données de la classe I
}
… … … // autres méthodes et données de la classe E
}

Une classe interne peut être déclarée static pour pouvoir la rendre autonome.
Une classe interne peut être locale même à une (à l’intérieur d’une) procédure.

• Fonctions et classes amies


Il est parfois nécessaire d'avoir des fonctions qui, malgré les restrictions définies, ont un accès illimité aux champs
d'une classe. En général, l'emploi de telles fonctions traduit un manque d'analyse dans la hiérarchie des classes, mais pas
toujours. Elles restent donc nécessaires malgré tout. De telles fonctions sont appelées des fonctions amies. Pour qu'une
fonction soit amie d'une classe, il faut qu'elle soit déclarée dans la classe avec le mot clé friend. Il est également possible de
faire une classe amie d'une autre classe, mais dans ce cas, cette classe devrait (peut-être) être une classe fille. L'utilisation
des classes amies peut traduire un défaut de conception.

• Constructeurs de copie
Examinons le code suivant :
Voiture mavoiture = new Voiture();
Voiture autre = mavoiture;
La seconde instruction consiste à créer une nouvelle référence, nommée autre, à laquelle est affectée la valeur de
la référence mavoiture.

Prof. Marcellin NKENLIFACK, mars 2013 21


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
Il apparaît que mavoiture et autre sont des références sur le même objet de type Voiture. Par conséquent,
si l’on applique à autre des méthodes qui modifient les valeurs de certains de ses attributs alors, sans que ce soit
explicite, on modifie aussi les valeurs des attributs de mavoiture puisque, en fait, c’est le même objet.
Si, au lieu de disposer de deux références sur le même objet, on souhaite disposer de deux objets identiques, mais
stockés dans deux emplacements mémoire distincts, l’instruction Voiture autre = mavoiture ; ne suffit pas.
Il faut appeler ce qu’on appelle un constructeur de copie.
Exemple : soit la classe Voiture simplifiée ci-après :
class Voiture
{
byte nbPortes;
long cylindree;
Voiture(Voiture v)
{
nbPortes = v.nbPortes;
cylindree = v.cylindree;
}
}
La méthode proposée est un constructeur de copie. On l’appelle avec l’instruction
Voiture autre = new Voiture(mavoiture);
Mais il faut bien avoir à l’esprit le fait que, lorsque les attributs sont eux-mêmes des objets, le problème se reproduit.
Pour éviter cela, pour chacun des attributs, il est indispensable d’appeler le constructeur de copie de l’attribut.
Une règle d’or, lorsqu’on programme en JAVA, est de créer des constructeurs de copie pour toutes les classes que l’on
manipule et de s’assurer que le constructeur de copie de chaque classe englobante appelle bien les constructeurs de copie de
tous ses attributs.
public class Voiture
{
byte nbPortes;
long cylindree;
Carrosserie maCarros;
/*** Constructeur de copie de Voiture */
Voiture(Voiture v)
{
maCarros = new Carrosserie(v.maCarros);
nbPortes = v.nbPortes;
cylindree = v.cylindree;
}
}

• Les clones
Plutôt que d’utiliser un constructeur de copie comme nous venons de le présenter, un usage répandu en JAVA consiste à
utiliser une méthode clone() qui se présente de la manière suivante :
public class Voiture
{
protected byte nbPortes;
protected long cylindree;
protected Carrosserie maCarros;
/*** Constructeur de Voiture */
public Voiture(byte nbp, long cyl, Carrosserie car)
{
maCarros = car;
nbPortes = nbp;
cylindree = cyl;
}
/*** méthode de clonage : @retourn un clone de type Voiture */
public Voiture clone()
{
Voiture retour = new Voiture(nbPortes, cylindree,
new Carrosserie(maCarros));
return retour;
}
}
On l’appelle avec l’instruction : Voiture copie = mavoiture.clone();
Cet usage est encouragé en JAVA.
La notion de clone permet d’effectuer explicitement la recopie de tous les champs d’un objet dans un autre
objet de même type. Toutefois, si les données sont convenablement encapsulées, il n’est pas possible d’y
accéder directement.
• L’avantage du langage à objets est que le code est réutilisable. Grâce à l’héritage, on peut étendre une classe sans
avoir à la réécrire complètement (et même sans connaître les détails de son implémentation), alors que l’utilisation d’un
langage classique nous obligerait à modifier le code source (donc à bien le comprendre).

Prof. Marcellin NKENLIFACK, mars 2013 22


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
• Synchronisation de processus et Relation d’exclusion mutuelle : Moniteurs
Les threads JAVA implantent un mécanisme de « moniteurs » protégeant l’accès aux objets « synchronisés ».
L’exclusion mutuelle s’effectue sur l’appel des méthodes déclarées synchronized dans la définition de la classe de
l’objet que l’on veut protéger.

• La réflexivité
Ceci concerne le fait qu’un objet puisse consulter la structure de la classe à laquelle il est rattaché.
La réflexivité se traduit en JAVA par un ensemble de mécanismes qui augmentent considérablement la puissance du
langage. Un objet peut par exemple s’auto-interroger pour savoir quel est son type, il peut se demander s’il hérite d’un type
particulier, il peut récupérer le nom de sa classe dans une chaîne de caractères ou encore sauvegarder son état complet dans
une autre chaîne de caractères.
L’ensemble de ces mécanismes est assez disparate. Vous pouvez utiliser :
– instanceof : opérateur qui vérifie si un objet est d’un type donné ou de l’une des sous-classes de ce type ;
– getClass() : méthode de la classe Object qui renvoie le type de l’objet (sous la forme d’un objet, instance de la classe
« Class », dans laquelle toute classe est décrite réflexivement). La classe Class possède notamment une méthode
getName() qui renvoie le nom de la classe et s’avère bien utile ;
– Serializable : interface qui permet la persistance ;
Les variables d’environnement doivent être correctement initialisées :
• JAVA_HOME répertoire de base du JDK.
• PATH répertoire contenant le compilateur et l’interprétateur (par exemple : $JAVA_HOME/bin).
• CLASSPATH répertoire contenant les classes (par exemple : $JAVA_HOME/lib).
Le classpath est une variable d’environnement qui permet de spécifier l’ensemble des chemins dans lesquels JAVA
doit aller chercher les classes susceptibles d’être nécessaires à l’exécution d’un code.
Sous UNIX et tous les systèmes d’exploitation apparentés, en csh et tcsh, on positionne le classpath à l’aide de la
commande : setenv CLASSPATH chemin1:chemin2:... :cheminN.
En bash, on écrit : export CLASSPATH=chemin1:ch2:... :cheminN.

• Les interfaces graphiques et le modèle MVC


L’un des éléments qui contribuent le plus massivement au succès de Java, c’est la facilité de mise au point
d’interfaces graphiques.
Le modèle MVC est un « design pattern » issu de Smalltalk-80. MVC signifie Model View Controller. Il s’agit d’une
façon d’organiser les différents composants d’un logiciel de façon à faciliter la réutilisation et éviter des problèmes de
conception et d’implémentation. Ce modèle est très générique et ne s’applique pas qu’aux interfaces graphiques, même si
c’est pour la conception d’interfaces graphiques qu’il est le plus utile.
Comme son nom l’indique, ce modèle contient trois composants :
1. Model : la partie « modèle » correspond au coeur de l’application. Elle contient les données que le programme
manipule et gère les changements d’états induits par les opérations sur ces données.
2. View : la partie « vue » correspond à l’interface en sortie présentée à l’utilisateur pour lui donner connaissance
de l’état de la partie « modèle ».
3. Controller : la partie « contrôleur » correspond à l’interface en entrée présentée à l’utilisateur pour interagir
avec la partie « modèle ».
À une même partie « modèle » peuvent être associées plusieurs vues, destinées à plusieurs utilisateurs ou à un seul. À
chaque fois que l’état de la partie « modèle » change, il faut informer du changement chacune des vues concernées par la
modification, afin que celles-ci mettent à jour l’information présentée aux utilisateurs.
De même, chaque action de l’utilisateur doit être transmise par un contrôleur à la partie « modèle » pour donner lieu à une
action sur les données.
La façon la plus propre de gérer ces interactions entre vues, modèle et contrôleur est de notifier tout changement qui
concerne l’un ou l’autre des éléments sous la forme d’un événement. Les différents composants s’abonnent à des sources
d’événements et se voient notifier ceux-ci lorsqu’ils se produisent.

• Sérialisation
On appelle « sérialisation » le processus consistant à écrire le contenu d’un objet dans un fichier pour pouvoir le
recharger lors d’une exécution ultérieure dans l’état où il était au moment de sa sauvegarde.
Pour qu’on puisse appliquer la sérialisation à ses objets, une classe doit implémenter l’interface Serializable. Il faut
aussi que tous ses attributs implémentent l’interface Serializable de même que les attributs de ces attributs, etc.
Ceci est une solution pour sauvegarder un ensemble (ou tous les) objets de notre programme.

3.6 QUELQUES PROPRIETES TECHNIQUES DE JAVA


On peut noter que Java est multiprocesseur (multi-threads). Il utilise le moniteur comme mécanisme d’exclusion
mutuelle et les signaux pour la synchronisation.

Prof. Marcellin NKENLIFACK, mars 2013 23


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
JAVA est un langage à typage fort, et toutes les fonctionnalités et le manque de rigueur (pouvant induire le programmeur
en erreur) que l’on trouve dans C++ ont été supprimées. La MVJ est chargée de gérer l’allocation et la désallocation de la
mémoire (pointeurs), ce qui évite également beaucoup d’erreurs.
En JAVA un programme est structuré intégralement sous la forme d’un ensemble de classes. Il n’y a aucune variable
globale qui soit externe à une classe.
Le code source de chaque classe se trouve stocké dans un fichier qui a pour nom le « nom de la classe » suivi de
l’extension « .java ». En principe, ce fichier ne doit contenir que cette classe. En pratique, il est toléré de regrouper
plusieurs classes dans le même fichier, mais ce n’est pas conseillé.
En particulier, mettre une classe par fichier permet de retrouver le code d’une classe plus rapidement au sein d’un
répertoire. Le compilateur émet des messages d’alerte si cette convention n’est pas respectée.

3.7 SECURITE ET MACHINE VIRTUELLE JAVA


En ce qui concerne l’exécution sécurisée de code distant, la plate-forme Java fut l'un des premiers systèmes à offrir
le support de l'exécution du code à partir de sources distantes. Une applet peut fonctionner dans le navigateur Web d'un
utilisateur, exécutant du code téléchargé d'un serveur HTTP. Le code d'une applet fonctionne dans un espace très restrictif,
ce qui protège l'utilisateur des codes erronés ou mal intentionnés. Cet espace est délimité par un objet appelé gestionnaire
de sécurité. Un tel objet existe aussi pour du code local, mais il est alors par défaut inactif. Le gestionnaire de sécurité
(classe SecurityManager) permet de définir un certain nombre d'autorisations d'utilisation des ressources du système local
(système de fichiers, réseau, propriétés système,...). Une autorisation définit :
- un code accesseur (typiquement, une applet - éventuellement signée - envoyée depuis un serveur web);
- une ressource locale concernée (par exemple un répertoire);
- un ensemble de droits (par exemple lire/écrire).
Les éditeurs d'applet peuvent demander un certificat pour leur permettre de signer numériquement une applet comme sûre,
leur donnant ainsi potentiellement (moyennant l'autorisation adéquate) la permission de sortir de l'espace restrictif et
d'accéder aux ressources du système local.
La machine virtuelle Java (JVM) est l'environnement dans lequel les programmes Java s'exécutent. Cet environnement
est essentiellement un ordinateur abstrait qui exécute un jeu d'instructions spécial. Les bytecodes Java sont les instructions
converties par le compilateur à partir d'un programme Java et exécutées par l'interpréteur.
Le mot Java représente à la fois le langage Java et l'environnement d'exécution Java (ou JVM). La JVM permet de garantir
la portabilité des applications Java. Les rôles principaux de la JVM sont : attribuer de la mémoire aux objets créés,
récupérer les données périmées, assurer le recensement et la gestion des piles, appeler le système hôte pour certaines
fonctions et suivre la sécurité des applications Java.
Les éléments suivants constituent le modèle de sécurité de Java : vérificateur Java, classe SecurityManager, chargeur de
classe et spécifications du langage.
- Le vérificateur effectue en quatre étapes un processus de vérification qui contrôle la validité des bytecodes.
- La classe SecurityManager est responsable des droits d'accès aux ressources du système.
- Le chargeur de classe exécute de nombreuses fonctions, dont le chargement des classes dans la JVM et la mise à
disposition de la classe SecurityManager d'informations relatives à la classe chargée.
- Les spécifications du langage Java sont sûres puisqu'elles interdisent les manipulations de pointeurs, les opérations
de transtypage illégales, les indexations de tableaux incorrectes ou les manques de mémoire.
Les compilateurs JIT (Just In Time : qui génèrent le code machine (processeur)) n'affectent pas la sécurité des
applications Java puisque les bytecodes qu'ils convertissent sont toujours vérifiés en premier.
Principe de compilation et exécution en Java
Un programme écrit en Java est portable, c'est-à-dire qu'il ne dépend pas d'une plate-forme donnée. En réalité le code
intermédiaire n'est exécutable sur aucune plate-forme sans la présence d'une machine virtuelle, un interpréteur (la machine
virtuelle est d'ailleurs parfois appelée interpréteur Java) tournant sur une plate-forme donnée, et capable d'interpréter le
code intermédiaire.

Prof. Marcellin NKENLIFACK, mars 2013 24


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java

[wwwJavaMem]
Figure 8. Etapes de compilation et exécution en Java

Pour peu qu'une plate-forme (windows, Unix, Linux, Amiga, ...) possède une machine virtuelle fonctionnant sous son
système, celle-ci est capable d'exécuter n'importe quelle application Java!
C’est ainsi que l'ensemble des navigateurs permettant d'utiliser des applets possèdent une machine virtuelle.
Avantages/Inconvénients du bytecode Java
- Code portable au niveau binaire
- Moins efficace que du code natif

3.8 « ENVIRONNEMENTS » DE DEVELOPPEMENT


Il existe un grand nombre d'environnements de développement orientés objets pour Java (surtout sous PC). Ceux-
ci présentent une multitude de points communs : éditeur intégré, compilateur, débugger sophistiqué, nombreux générateurs
de code (surtout pour les interfaces graphiques). Nous pouvons citer entre autres : le JDK (devenu Java2 SDK à partir de
JDK 1.2) et Java Workshop (Sun/Oracle) Visual J++ (Microsoft), JBuilder (Borland/Inprise), Visual Café
(WebGain), CodeWarrior (Metrowerks), Kaffe, Eclipse (environnement libre développé initialement par IBM), BlueJ,
Idea, Jcreator, NetBeans, jDeveloper, Xcode, Visual Age (IBM).
Nous nous proposons ici de présenter sommairement l’environnement que nous allons utiliser dans un premier
temps pour les Travaux Pratiques : le JDK (Java Developpment Kit). Le JDK est un environnement minimal mais suffisant
(un compilateur et une machine virtuelle) proposé gratuitement, et pouvant être téléchargé depuis Internet. Il est disponible
sur les plates-formes Solaris, Linux, Windows 9X/NT/2000/XP/2003/Vista/2008/2012 et MacOS (68030 ou supérieurs). Il
est constitué des outils qui fonctionnent sous la forme de commandes en ligne. Mais si l’on désire poursuivre avec Java
pour de gros projets, il faudra alors acquérir un environnement plus adapté (plus convivial).

Voici quelques outils faisant partie du « paquet JDK » :


 Un compilateur : javac
 Un interpréteur général d'applications : java
 Un interpréteur (plus léger) jre
 Un outil de visualisation (interpreteur) d'Applets : appletviewer
 Un débogueur : jdb
 Un décompilateur : javap
 Un générateur de documentation : javadoc.
 Un outil d'interfaçage avec d’autres langages (C, C++) : javah
 Un outil d’archivage : jar
 Un outil de signature numérique (protection…) de logiciels : javakey
 Un outil de conversion du code écrit (dans votre environnement d’origine) vers le code « ASCII » et le code universel
« Unicode » : native2ascii
 Un générateur d’objets d’accès distant à partir de classes contenant les méthodes d’accès distant : rmic
 Un moteur d’initialisation et lancement d’objets de service distant sur un port: rmiregistry
 Un outil de conversion (mise à jour) des méthodes de la classe AWT (de jdk1.0 vers jdk 1.1) : updateAWT

L’outil JavaDoc
Il s’agit d’un utilitaire associé à JAVA qui génère automatiquement une documentation de code JAVA au format
HTML. La documentation fait apparaître l’ensemble des classes et leurs relations hiérarchiques avec différents points
d’entrée, par index, par package ou par arborescence d’héritage. Pour chaque classe apparaissent tous ses attributs et
méthodes, avec la signature complète de chaque méthode. Il s’agit d’un outil très intéressant présent dans le JDK,

Prof. Marcellin NKENLIFACK, mars 2013 25


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
permettant de générer automatiquement la documentation d’un programme ou d’un projet. Par défaut, la documentation
générée est au format HTML.
NB : A titre d’exemple, toute la documentation des « API » java de SUN a été générée grâce à javadoc.
La documentation générée contient les fichiers suivants:
• Un fichier html par classe ou interface contenant le détail de chaque classe ou interface.
• Un fichier html par package
• Un fichier overview-summary.html
• Un fichier deprecated.html
• Un fichier serialized-form.html
• Un fichier overview-frame.html
• Un fichier all-classes.html
• Un fichier package-summary.html pour chaque package.
• Un fichier package-frame.html pour chaque package.
• Un fichier package-tree.html pour chaque package.

3.9 MISE EN ŒUVRE D’UN PROGRAMME COMPORTANT PLUSIEURS CLASSES


Lorsqu’un programme comporte une seule classe, il suffit de compiler et de lancer l’exécution.
Par contre si le programme possède plusieurs classes, plusieurs démarches sont possibles.
• Un fichier source par classe : chaque classe est sauvegardée dans un fichier source qui sera lui-même compilé. Le
fichier principal (contenant la fonction main) doit également être compilé puis exécuté.
• Plusieurs classes dans le même fichier source : un fichier source peut contenir plusieurs classes à condition
qu’une seule soit publique. La classe contenant la méthode main doit obligatoirement être publique afin que la machine
virtuelle y ait accès. Une classe n’ayant aucun attribut d’accès reste accessible à toutes les autres classes de même
paquetage donc, à fortiori du même fichier sources.

3.10 QUELQUES MOTS RESERVES, PRIMITIFS ET LITTERAUX JAVA


abstract else instanceof strictfp while boolean false
assert (JDK 1.4) enum (JDK 1.5) interface super byte null
break extends native switch char true
case final new synchronized double
catch finally package this float
class for private throw int
const (Non utilisé) goto (Non utilisé) protected throws long
continue if public transient short
default implements return try void
do import static volatile

3.11 FRAMEWORKS ET API


Plusieurs API et microarchitectures (frameworks) sont disponibles (spécifiées par Sun/Oracle) pour donner à Java plusieurs
champs d’utilisation. On peut citer à la base :
- JSE : Ce framework est destiné aux applications pour poste de travail.
- JEE : Ce framework est spécialisé dans les applications serveurs. Il contient pour ce faire, un grand nombre
d'API et d'extensions. On parle de Java Enterprise Edition.
- JME : Ce framework est spécialisé dans les applications mobiles. On parle de Java Micro Edition.
- JavaCard : Framework est spécialisé dans les applications liées aux cartes à puces et autres SmartCards
Plusieurs autres standards complètent les frameworks de base Java :
- JavaMedia : Framework multimédia, contenant les API Java2D, Java3D, JavaSound, Java advanced Imaging…
- Java Telephony
- Java TV
- JXTA : Système de peer-to-peer reposant sur Java
- Jini
- JAIN
- JDMK
- JavaSpeech
- JMI
- JavaSpaces
En ce qui concerne la manipulation des objets de stockage (objets persistants), on utilisera :
- JDBC (Java DataBase Connectivity)
- JDO (Java Data Objects)
- EJB (Enterprise Java Beans)

Prof. Marcellin NKENLIFACK, mars 2013 26


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java

3.12 PROGRAMMATION JAVA, COMPILATION, EXECUTION


3.12.1 PREMIER PROGRAMME « BONJOUR » / « HELLO WORLD »
Le programme « Hello world » type est présenté ci-dessous en Java :
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello world!");
}
}

Test du programme « Hello World »


Le nom du fichier soure sera HelloWorld.java.
Pour le tester, vous utiliserez les commandes suivantes (sous Linux) :
javac HelloWorld.java
CLASSPATH=.
java HelloWorld
La ligne « CLASSPATH=. » est nécessaire pour indiquer à Java qu'il doit également chercher les programmes class
dans le répertoire courant. Ce chemin peut également être spécifié par l'option -classpath (ou -cp en abrégé) :
javac HelloWorld.java
java -cp . HelloWorld

• Le deuxième programme Bonjour est présenté ci-dessous en Java :


// BonjourDate.java
import java.util.*;

public class BonjourDate {


public static void main(String[] args) {
System.out.println("Bonjour.");
System.out.print("Date et Heure : ");
Date d;
d = new Date();
System.out.println(d);
}
}

• Le troisième programme Bonjour avec paramètres en ligne de commande est présenté ci-dessous :
class TestCommande
{
public static void main(String[] args)
{
string ch ;
System.out.println("Bonjour et Merci de choisir Java");
for (int i = 0; i < args.length; i++)
{
//system.out.print(i == 0 ? args[i] : " " + args[i]);
if (i == 0) ch = arg[i];
else ch = " " + args[i];
system.out.print(ch);
}
System.out.println();
}
}

En exécutant avec la commande


javac Testcommande.java
java Testcommande Je suis en Master Pro.
On obtient le résultat suivant:
Bonjour et Merci de choisir Java
Je suis en Master Pro

Prof. Marcellin NKENLIFACK, mars 2013 27


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
3.12.2 OUTILS QUI D’AUTOMATISATION DU PROCESSUS DE CONSTRUCTION.
Les plus utilisés sont :
- Ant (génération de code portable en XML)
- Scons (génération portable de Java/C/C++).
Exemple :
Java (target = 'classes', source = 'src')
Jar (target = 'test.jar', source = 'classes')
Application :
% scons -Q
javac -d classes -sourcepath src src/Exemple1.java src/Exemple2.java src/Exemple3.java
jar cf test.jar classes

3.12.3 EXECUTION D'UNE APPLET JAVA


Il suffit de créer une page HTML pouvant être très simple :
<HTML>
<TITLE> test applet Java </TITLE>
<BODY>
<APPLET code=« NomFichier.class » width=270 height=200>
</APPLET>
</BODY>
</HTML>
Il faut ensuite visualiser la page créée dans l'appletviewer ou dans un navigateur Internet compatible avec la version de Java
dans laquelle l'applet est écrite.

3.13 STRUCTURES
3.13.1 LES LITTÉRAUX
Lorsque vous insérez une valeur littérale dans un programme, le compilateur sait exactement à quel type il se réfère. Parfois
cependant, il peut arriver que le type soit ambigu. Quand c’est le cas, vous devez guider le compilateur en adjoignant des
informations supplémentaires sous forme de caractère associé à la valeur littérale. Ces caractères sont présentés ci-après :
public class Literals {
char c = 0xffff; // max char hex value
byte b = 0x7f; // max byte hex value
short s = 0x7fff; // max short hex value
int i1 = 0x2f; // Hexadecimal (lowercase)
int i2 = 0X2F; // Hexadecimal (uppercase)
int i3 = 0177; // Octal (leading zero)
// Hex and Oct also work with long.
long n1 = 200L; // long suffix
long n2 = 200l; // long suffix
long n3 = 200;
//! long l6(200); // not allowed
float f1 = 1;
float f2 = 1F; // float suffix
float f3 = 1f; // float suffix
float f4 = 1e-45f; // 10 to the power
float f5 = 1e+9f; // float suffix
double d1 = 1d; // double suffix
double d2 = 1D; // double suffix
double d3 = 47e47d; // 10 to the power
} ///:~

Prof. Marcellin NKENLIFACK, mars 2013 28


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java

3.13.2 EXERCICES
Exercice 1 :
Créer la classe qui définit une abstraction des nombres complexes.
Class complex
private re, im :real ;
function cons (re, im : real) return complex ;
function add (L, R : complex) return complex ;
…. … …
fin class complex ;

Corps de la classe complex


function cons (re, im : real) return complex is
begin
return complex’(re, im) ;
end function cons ;
function add (L, R : complex) return complex is
begin
return complex’(L.re + R.re , L.im + R.im) ;
end function add ;
La classe pourra par exemple être utilisée comme suit :
constant C : complex := cons(0.0, 1.0) ;
variable A, B : complex ;
signal S : complex ;
… … …
S <= A + C * cons(2.0,0.0) ;
Dans cet exemple, la visibilité est limitée à la définition de la classe pour tous les éléments marqués private. Si ils avaient été
marqués public, ils seraient visibles à l’extérieur, par exemple dans toutes les sous-classes héritant de la classe.

Exercice 2 : Lecture d’informations au clavier


Pour faciliter l’apprentissage du langage, il est préférable de réaliser des programmes travaillant en mode console (texte).
L’affichage dans la console ne présente aucune difficulté, il suffit de recourir à l’une des fonctions System.out.println ou
System.out.print. Malheureusement, Java ne prévoit rien de compaable pour la lecture au clavier.

1-) On souhaite développer une petite classe offrant les services de base que sont la lecture d’entiers, de flottants de caractères …
// nom du fichier = «Clavier.java »
// classe fournissant des fonctions de lecture au clavier -
import java.io.* ;
public class Clavier
{ public static String lireString () // lecture d'une chaine
{ String ligne_lue = null ;
try
{ InputStreamReader lecteur = new InputStreamReader (System.in) ;
BufferedReader entree = new BufferedReader (lecteur) ;
ligne_lue = entree.readLine() ;
}
catch (IOException err)
{ System.exit(0) ;
}
return ligne_lue ;
}
public static float lireFloat () // lecture d'un float
{ float x=0 ; // valeur a lire
try
{ String ligne_lue = lireString() ;
x = Float.parseFloat(ligne_lue) ;
}
catch (NumberFormatException err)
{ System.out.println ("*** Erreur de donnee ***") ;
System.exit(0) ;
}
return x ;
}
public static double lireDouble () // lecture d'un double

Prof. Marcellin NKENLIFACK, mars 2013 29


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Les Objets et le langage Java
{ double x=0 ; // valeur a lire
try
{ String ligne_lue = lireString() ;
x = Double.parseDouble(ligne_lue) ;
}
catch (NumberFormatException err)
{ System.out.println ("*** Erreur de donnee ***") ;
System.exit(0) ;
}
return x ;
}
public static int lireInt () // lecture d'un int
{ int n=0 ; // valeur a lire
try
{ String ligne_lue = lireString() ;
n = Integer.parseInt(ligne_lue) ;
}
catch (NumberFormatException err)
{ System.out.println ("*** Erreur de donnee ***") ;
System.exit(0) ;
}
return n ;
}
// programme de test de la classe Clavier
public static void main (String[] args)
{ System.out.println ("donnez un flottant") ;
float x ;
x = Clavier.lireFloat() ;
System.out.println ("merci pour " + x) ;
System.out.println ("donnez un entier") ;
int n ;
n = Clavier.lireInt() ;
System.out.println ("merci pour " + n) ;
}
}
2-) utiliser cette classe pour écrire un programme calculant n fois la racine carrée de nombres réels quelconques et affiche le résultat à
l’écran. L’entier n est d’abord lu et les différent réel sont lus par la suite. On peut utiliser la fonction Math.sqrt (x) pour calculer la
racine carrée de x.
3-) modifier la classe « clavier » pour qu’elle puisse permettre de lire plusieurs valeurs sur une seule ligne.
4-) modifier le programme pour qu’il puisse contrôler la saisie de mauvaises valeurs. Par exemple 45é ou 3.5 pour un entier. Ceci
devrait éviter que le programme s’interrompe avec le message *** Erreur de donnee ***.

Prof. Marcellin NKENLIFACK, mars 2013 30


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

4 BIBLIOTHEQUES DE CLASSES ET TECHNIQUES DE PROGRAMMATION

4.1 LES PAQUETAGES


Les packages constituent un moyen commode pour découper une application volumineuse en modules bien distincts
tout en gérant efficacement les conflits de noms entre ces modules.
Le découpage en modules est une étape délicate de la conception orientée objets. Toute la difficulté consiste à identifier des
modules suffisamment indépendants les uns des autres pour minimiser les interactions et permettre des développements
séparés des différents modules.
Un paquetage est donc vu comme un regroupement logique d’un ensemble de classes sous un identificateur commun.
Cette notion est proche de la notion de bibliothèque que l’on rencontre dans les autres langages. Elle facilite le
développement et la cohabitation des logiciels en permettant de répartir les classes correspondantes dans différents
paquetages. Les paquetages suivent une organisation hiérarchisée (comme la structure arborescente des répertoires).
• L’attribution du nom de paquetage se fait au niveau du fichier source : package NomDuPaquetage
• Lorsque dans un programme vous faites référence à une classe, le compilateur la recherche dans le paquetage par
défaut (java.lang). Pour utiliser une classe appartenant à un autre paquetage, il est nécessaire de fournir l’information au
compilateur. Pour ce faire vous pouvez :
- citer le nom du paquetage avec le nom de la classe :
exemple : NomduPaquetage.Rectangle = new NomduPaquetage.Rectangle (2,5) ;
- importer une classe particulière du paquetage :
exemple : import NomduPaquetage.NomDeLaClasse // import Figures.Rectangle
- importer le paquetage :
exemple : import NomduPaquetage.* // import Figures.*

Evolution de l’enrichissement des « bibliothèques » Java

Java 1.0 Java 1.1 Java 1.2 J2SE 1.3 J2SE 1.4 J2SE 5
Nombre de de packages 8 23 59 76 135 166
Nombre de classes 201 503 1520 1840 2990 3280
Méthodes 1545 3 85 15 060

4.1.1 PAQUETAGES STANDARDS :


Java est fourni avec de nombreuses classes standards structurées en paquetages (java.awt, java.awt.event, javax.swing, etc).
Par ailleurs, il existe un paquetage particulier nommé java.lang qui est automatiquement importé par le compilateur. C’est
ce qui vous permet d’utiliser les classes standards telles que Math, Sysem, Float ou Integer, sans avoir à introduire
d’instruction import.
Voici en quelques points, les grands packages (ensembles de classes) qui sont fournis en standard avec Java :
• Le package lang : fournit plusieurs classes liées aux langages : opérations et types de base, etc.
• Le package io : constitué d’un ensemble de classes destinées à la gestion de toutes les opérations d'entrées/sorties.
• L'Abstract Window Toolkit : fournit des méthodes d'accès à toutes les ressources graphiques de la machine. Les
éléments graphiques utilisés sont ceux du système hôte. Cependant, les concepteurs de l'AWT se sont assurés que
tous les comportements proposés au sein de cette librairie soient supportés par tous les environnements pouvant
supporter Java.
• Le package applet : constitué des outils pour réaliser des applets (application pouvant s'exécuter dans un navigateur
Internet). Il doit être utilisé conjointement avec l'AWT. En effet, dans un document HTML, l'applet occupera
toujours une zone graphique.
• Le package beans : constitué des outils pour la programmation orientée composants.
• Le package JDBC (Java DataBase Connectivity) : regroupe toutes les fonctionnalités permettant d'accéder à des
bases de données diverses.

4.1.2 LES PAQUETAGES POUR CRÉER DES INTERFACES GRAPHIQUES PLUS INTÉRESSANTES
Trois groupes de packages permettent de gérer les interfaces graphiques :
- AWT : Abstract Window Toolkit / Abstract Widget Toolkit. AWT utilise des "composants lourds", c'est à dire
utilisant les ressources du système d'exploitation. Ce qui lui assure une bonne performance.
- Swing (intégré à partir de la version 1.2 du JDK). Alors que swing utilise des "composants dits légers", n'utilisant
pas ces ressources. Swing est plus robuste que l'AWT, plus portable, et plus facile à utiliser. Swing ne remplace

Prof. Marcellin NKENLIFACK, mars 2013 31


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
pas complètement AWT, mais fournit des composants plus performants. Swing possède des fonctionnalités
avancées, la possibilité d'étendre les composants, une adaptation du rendu de composants, etc. Swing est une API
mature, éprouvée et parfaitement connue. Malheureusement, ses deux gros défauts sont sa consommation en
ressource machine et la lenteur d'exécution des applications qui l'utilisent.
- SWT : Standard Widget Toolkit, intégré à partir de JSE5, depuis l’arrivée de l’environnement ECLIPSE. SWT
combine les avantages des deux précédentes approches (utilisaion des composants système et implémentation des
autres composants en Java).
Etant donné que chaque composant AWT a son équivalent swing dans le package "javax.swing". Nous nous intéresserons
plus aux possibilités développées dans les packages Swing et SWT.
Les composants d'une interface utilisateur sont placés dans des conteneurs. Chaque objet conteneur utilise un gestionnaire
de placement (layout) pour contrôler la taille de l'écran et la disposition des objets qu'il contient.

4.1.3 EXEMPLES DE CODES


4.1.3.1 application simple utilisant le package « SWING »
Voici le code complet du programme “HelloWorldSwing" utilisant le package swing.
import javax.swing.*;
import javax.swing.*;

public class HelloWorldSwing


{
/*-- Création d’une interface GUI --*/
private static void createAndShowGUI()
{
//--Assure une meilleure décoration de la fenêtre.
JFrame.setDefaultLookAndFeelDecorated(true);
//--Création et initialisation de la fenêtre
JFrame frame = new JFrame("Premier programme : HelloWorld avec Swing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//--création du label "Hello World"
JLabel label = new JLabel("Hello World, Welcome Aboard / Bonjour, Bienvenue à bord");
frame.getContentPane().add(label);
//--Affichage de la fenêtre
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
//--Définition d’un processus de distribution d'événements
//création et mise en route de votre application GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
} );
}
}

Il s’agit d’un cas simple d’application graphique à l’aide des classes du paquetage Swing. Elle ne fait pas grand chose, mais
présente tout de même l’essentiel qu’on doit retrouver dans un tel programme :
1. importation des packages pertinents
2. initialisation du (ou des ) “container" de base
3. affichage du “container"
4. sécurisation du processus (thread)

Nous avons ici importé le package “Swing” principal (seul utile dans notre exemple).
import javax.swing.*;

Mais il faut noter que la plupart des programmes auront besoin d’importer deux packages AWT :
import java.awt.*;
import java.awt.event.*;

Prof. Marcellin NKENLIFACK, mars 2013 32


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
Ces packages sont nécessaires compte tenu du fait que SWING s’appuie à la base sur l’infrastructure AWT, y compris les
modèles d’événements AWT. Les modèles d’événements spécifient comment un composant réagit lorsqu’un événement
survient. Par exemple un clique sur un bouton, ou un déplacement de la souris.

Figure 9. Ecran d’exécution de l’application HelloWorld utilisant les objets « Swing »

4.1.3.2 Exemple2 d’application (L’environnement Tortue)


import java.applet.*;
import java.awt.*;
public class Tortue
{
double cap;
int nx,ny,ax,ay;
Tortue(int x, int y)
{ax=x; ay=y; cap=Math.PI/2;}
void gauche(double angle)
{cap=cap+angle*Math.PI/180;}
void droite(double angle)
{cap=cap-angle*Math.PI/180;}
void avance(int dist, Graphics g)
{
nx=ax + (int) Math.round(dist*Math.cos(cap));
ny=ay - (int) Math.round(dist*Math.sin(cap));
g.drawLine(ax,ay,nx,ny);
ax=nx; ay=ny;
}
void recule(int dist, Graphics g)
{avance(-dist,g);}
void arbre(int dist,int n,Graphics g)
{
double a;
if (n>0)
{
if (n==1)
{
if (Math.round(Math.random()*25)==5)
{
g.setColor(Color.red);
g.fillOval(ax,ay,7,7);
g.setColor(Color.green);
}
else
{
g.setColor(Color.green);
g.fillOval(ax,ay,8,3);
}
}
else
{
if (n<=6) {g.setColor(Color.green);}
else {g.setColor(Color.darkGray);}
avance(dist,g);
a=Math.floor(Math.random()*3)*10+10;
gauche(a*0.75);
arbre(dist*3/4,n-1,g);
droite(a*3/2);
arbre(dist*3/4,n-1,g);
gauche(a*0.75);
if (n>6) {g.setColor(Color.darkGray);}
recule(dist,g);

Prof. Marcellin NKENLIFACK, mars 2013 33


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
}
}
}
}
//////////////////////////////////////////////////
import java.applet.*;
import java.awt.*;
public class Foret2 extends Applet
{TextField valeur=new TextField("10");
Button boutonArbre=new Button("Lancer le Dessin d'arbre");
Button boutonQuitter=new Button("Quitter");
Tortue matortue=new Tortue(200,400);
Font font1=new Font("Helvetica",Font.BOLD,14);
public void init()
{
resize(400,400);
matortue.ax=size().width/2;
matortue.ay=size().height;
this.setLayout(new FlowLayout(FlowLayout.LEFT,10,10));
String titre="Tortue Arboricole";
Label lab1=new Label("Profondeur de l'arbre");
lab1.setBackground(Color.blue);
lab1.setForeground(Color.white);
valeur.setBackground(Color.white);
valeur.setForeground(Color.red);
boutonArbre.setBackground(Color.pink);
boutonQuitter.setBackground(Color.blue);
lab1.setForeground(Color.white);
lab1.setFont(font1);
add(lab1);
add(valeur);
add(boutonArbre);
add(boutonQuitter);
}
public boolean action(Event e,Object arg)
{
Graphics g=getGraphics();
if ("Lancer le Dessin d'arbre".equals(arg))
{
g.clearRect(0,0,size().width,size().height);
int num=Integer.parseInt(valeur.getText());
g.setColor(Color.red);
g.setFont(font1);
g.drawString("Un très bel Arbre",20,395);
matortue.arbre(80,num,g);
}
if ("Quitter".equals(arg))
{
//Dispose();
System.exit(0);
return true;
}
return true;
}
public static void main(String args[])
{
Frame fenetre= new Frame("Application de trace d'arbre");
Foret2 monappli=new Foret2();
monappli.init();
monappli.start();
fenetre.add("Center",monappli);
fenetre.resize(400,500);
fenetre.show();
}
}

Prof. Marcellin NKENLIFACK, mars 2013 34


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

Figure 10. Résultat exécution de l’application Arbre utilisant l’environnement Tortue

4.2 RECAPITULATIF PLATEFORME JAVA (PAR CATEGORIE) :


[wwwJavaWiki]

4.2.1 LES API STANDARDS (J2SE)


Java Bean RMI IO Applet
Reflexion Collection Logging AWT
Net (réseau) Preferences Security JFC
Internationalisation Express. régulière Swing

4.2.2 LES API D’ACCÈS AUX DONNÉES


Données Web Entreprise XML Divers
Java Mail JAXP JAI
JNDI SAX JAAS
EJB DOM JCA
Servlets JMS JAXM JCE
JDBC JMX JAXR Java Help
JTA JAX-RPC JMF
RMI-IIOP SAAJ JSSE
JSP Java IDL JAXB Java speech
JSTL JINI Java 3D
JDO Jave Server Faces JXTA

4.2.3 LES AUTRES API (DE LA COMMUNAUTÉ OPEN SOURCE)


Web XML Divers
Données Jakarta Struts Apache Xerces Jakarta Log4j
Webmacro Apache Xalan Jakarta regexp
Entreprise
OJB Expresso Apache Axis
Castor Barracuda JDOM
Hibernate Turbine DOM4J

Prof. Marcellin NKENLIFACK, mars 2013 35


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

4.3 LES EXCEPTIONS


Pour certaines méthodes spécifiques, certaines causes d’erreur peuvent être prévues à l’avance. C’est le cas lorsque
la méthode doit être utilisée dans un contexte bien particulier qui risque de ne pas être respecté par l’utilisateur. Par
exemple, une méthode qui ouvre un fichier en lecture ne fonctionnera pas si le fichier n’existe pas. Cette cause d’erreur
peut être prévue par le programmeur de la librairie de gestion des fichiers.
Dans un tel cas, le programmeur peut tester un certain nombre de causes d’erreur potentielles et associer à la méthode des
comportements particuliers si ces erreurs sont détectées.
Le mécanisme approprié en JAVA pour traiter ces erreurs est fourni par les « exceptions ».
Les exceptions sont des objets particuliers dont les classes dérivent toutes de la classe Exception, qui elle-même dérive
de la classe Throwable. Cette classe contient au moins une chaîne de caractères pour décrire le type d’exception. Il existe
un certain nombre d’exceptions génériques définies dans le langage et correspondant à des situations fréquentes ou des
erreurs de programmation classiques. Un certain nombre d’entre elles ont déjà été présentées au fil de ce document. Mais le
programmeur peut définir ses propres classes d’exception en les faisant hériter de la classe Exception.
• Il n'est pas obligatoire de capturer ou propager les exceptions « unchecked » (non contrôlées) : Error et
RunTimeException. Mais une exception levée non propagée et non capturée finit par provoquer l'arrêt de la
"fonction ou la méthode du programme principal".
• Les Exceptions de la classe des IOException doivent être obligatoirement capturées ou propagées.
• Il est possible de créer des nouvelles sous-classes d'Exception et de propager de telles exceptions par l'instruction
throw (pour qu’elles soient levées par une méthode principale appelante ou se trouvant plus loin).
Le traitement des exceptions en Java
L'exécution de certaines instructions ou méthodes peuvent lever des (erreurs d'exécution) exceptions. Celles-ci sont
organisées en classes. Par exemple, la classe RuntimeException regroupe les incidents du genre : division par 0
(ArithmeticException), en dehors des bornes d'un tableau (IndexoutOfBoundsException), méthode appliquée à une
référence nulle (NullPointerException), ...
• try ... catch, capture d'exception :
try { bloc d'instructions pouvant lever des exceptions }
catch {type_d_exception e) { traitement de e} // définit l'exception à capturer et son traitement
catch {autre_type_d_exception e) { traitement de e}
dès qu'une exception est levée dans le corps de try, le traitement de ce corps est terminé et catch définit le traitement
de l'exception capturée.
• finally dans un try ... catch :
try { bloc d'instructions pouvant lever des exceptions }
catch {type_d_exception1 e) { traitement1 de e}
catch {autre_d_exception2 e) { traitement2 de e}
finally { corps toujours exécuté }
le traitement du corps de la clause finally est toujours exécuté qu'une exception ait été levée et donnée lieu à un
traitement "catch", ou qu'aucune erreur ne soit survenue au cours du corps de try.
• « throws », décaler/propager une exception :
• [<modificateur>] <type> <nomMéthode> ([<paramètres>]) throws <liste d'exceptions> { <corps de la méthode
pouvant lever des exceptions > }
Les exceptions listées sont propagées/transmises à la méthode appelante si elles sont levées dans le corps de la
méthode traitée.
Donc une exception peut-être propagée jusqu'à une méthode appelante qui la capture et la traite.
L’exemple ci-dessous illustre le mécanisme des exceptions en Java.
FileOutputStream fos = null;

try {
//<-- Créer un flux pour écrire dans un fichier. Le fichier
//n'est pas spécifié puisque ce n'est pas essentiel pour l'exemple.
fos = new FileOutputStream(...);
fos.write(a); //'a' aurait reçu une valeur ultérieurement
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
//Fermer le flux, qu'il y ait une exception lancée ou pas
if(fos != null) fos.close();
}

Prof. Marcellin NKENLIFACK, mars 2013 36


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
Dans le cas d'une erreur d'entrée/sortie dans le bloc "try", l'exécution reprend dans le bloc "catch" correspondant à cette
situation (exception de type "IOException"). Dans ce bloc "catch", la variable "e" référence l'exception qui s'est produite.
Ici, nous invoquons la méthode "printStackTrace()" qui affiche dans la console des informations sur l'exception qui s'est
produite : nom, motif, état de la pile d'appels au moment de la levée de l'exception, et éventuellement le numéro de ligne à
laquelle l'erreur s'est produite. Le bloc finally est ensuite exécuté (ici pour refermer les ressources utilisées). Il ne s'agit ici
que d'un exemple, l'action à mettre en œuvre lorsqu'une exception survient dépend du fonctionnement général de
l'application et de la nature de l'exception.

4.4 PRESENTATION DE QUELQUES BIBLIOTHEQUES DE CLASSES JAVA

4.4.1 INTRODUCTION
Pour prendre en charge certaines fonctionnalités, la plupart des langages de programmation reposent sur des
bibliothèques déjà construites. Par exemple, le langage C (à l’origine) n'intégrait pas la prise en charge directe des fonctions
d'E/S. Le JDK dispose d'une bibliothèque très impressionnante qui inclut la connectivité des bases de données, la
conception GUI, les E/S et la programmation en réseau. Bien que le JDK contienne de nombreux paquets de prise en
charge, dix d'entre eux méritent une présentation spécifique.
Langage = Noyau principal du langage Java (lang)
Utilitaires = Prise en charge des structures de données utilitaires (util)
E/S = Prise en charge de divers types d'entrée/sortie (IO)
Réseau = Prise en charge de TCP/IP et programmation des sockets (net)
AWT = Conception GUI et gestion des événements (awt)
Sécurité = Prise en charge de la sécurité par cryptographie (security)
RMI = Prise en charge de la programmation distribuée (rmi)
SQL = Prise en charge de l'interrogation des bases de données avec SQL (sql)
Reflection = Donne des informations sur les classes à l'exécution
Texte = Prise en charge de l'internationalisation

4.4.2 LE PAQUET DU LANGAGE (LANG)


Le paquet java.lang est un des plus importants de la bibliothèque des classes Java. Il contient les classes
principales de prise en charge du langage. Il est pratiquement impossible d'écrire un programme Java sans utiliser le paquet
du langage. Les sections suivantes présentent quelques-unes des classes les plus importantes de ce paquet.

4.4.2.1 La classe Object


La classe Object est parent de toutes les classes Java. Cela signifie que toutes les classes Java sont dérivées de la
classe Object. Cette classe contient elle-même plusieurs méthodes importantes telles que : clone, equals et toString.

Voici une liste non exhaustive des propriétés et méthodes de la classe Object :
package java.lang;
public class Object {
public final Class<?> getClass() { . . . }
public String toString() { . . . }
public boolean equals(Object obj) { . . . }
public int hashCode() { . . . }
protected Object clone()
throws CloneNotSupportedException { . . . }
public final void wait()
throws IllegalMonitorStateException,
InterruptedException { . . . }
public final void wait(long millis)
throws IllegalMonitorStateException,
InterruptedException { . . . }
public final void wait(long millis, int nanos) { . . . }
throws IllegalMonitorStateException,
InterruptedException { . . . }
public final void notify() { . . . }
throws IllegalMonitorStateException
public final void notifyAll() { . . . }
throws IllegalMonitorStateException
protected void finalize()
throws Throwable { . . . }
}

Un objet qui utilise la méthode clone fait simplement une copie de lui-même. Pour cela, une certaine quantité de mémoire
est affectée au clone, puis le contenu de l'objet initial est copié dans l'objet clone. Par exemple, nous voulons obtenir une

Prof. Marcellin NKENLIFACK, mars 2013 37


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
copie de la classe Document avec une propriété texte et auteur. Pour créer une occurrence de la classe Document
contenant les deux propriétés et les valeurs associées à l'objet, utilisez la méthode clone.
Le code suivant montre comment y parvenir :
Document document1 = new Document ("docText.txt", "Jean Martin");
Document document2 = document1.clone( );
La méthode equals compare deux objets du même type sur la base de leurs propriétés. Elle renvoie une valeur booléenne
qui dépend de l'objet qui a appelé la méthode et de l'objet qui lui a été transmis. Par exemple, si equals est appelée par un
objet qui lui transmet un objet complètement identique, la méthode equals renvoie la valeur True.
La méthode getClass retourne la classe de laquelle l’objet a été instancié.
La méthode finalize est exécutée juste avant la destruction d’un objet.
La méthode forname : méthode de la classe Object qui permet de créer un objet d’une classe à la volée à partir d’une
chaîne de caractères contenant le nom de la classe et les paramètres du constructeur.
La méthode toString donne un résultat de type String qui représente la valeur de l'objet. Pour que cette méthode renvoie
des informations correctes quel que soit le type d'objet, la classe de l'objet doit la redéfinir.

4.4.2.2 Classes d'enveloppe de type (Wrapper type)


Dans Java, les types de données primitifs ne sont pas utilisés en tant qu'objets, pour des raisons de performances.
Ces types de données incluent les nombres, les valeurs booléennes et les caractères, etc.
Traiter ces types de données primitifs comme des objets dégraderait considérablement les performances du langage (à
cause du temps système consacré au traitement des objets). Cependant, certaines classes et méthodes Java nécessitent que
les types de données primitifs soient des objets. Il est également utile, dans certains cas, d'ajouter des méthodes
personnalisées à ces types. Pour ces raisons, les classes Java d'enveloppe de type peuvent être instanciées. Ci-dessous, la
liste des types de données primitifs que les paquets du Langage prennent en charge en tant qu'objets :
Boolean = True ou False (1 Bit)
Byte = -128 à 127 (nombre entier signé sur 8 bits)
Character = Caractère Unicode (16 bits)
Double = +1.79769313486231579E+308 à +4.9406545841246544E-324 (64 bits)
Float = +3.40282347E+28 à +1.40239846E-45 (32 bits)
Integer = -2147483648 à 2147483647 (nombre entier signé sur 32 bits)
long = -9223372036854775808 à 9223372036854775807 (nombre entier signé sur 64 bits)
short = -32768 à 32767 (nombre entier signé sur 16 bits)
Bien que chacune de ces classes contienne ses propres méthodes, plusieurs d'entre elles sont standards pour plusieurs
objets. Elles incluent ClassType, typeValue, toString et Equals.
La méthode ClassType est le constructeur des classes d'enveloppe. Elle prend simplement un argument du type de la classe
qu'elle enveloppe. Par exemple, le code suivant montre la construction d'une classe d'enveloppe du type Character.
Character charWrapper = new Character ('T');
La méthode typeValue renvoie le type primitif de la classe d'enveloppe. Le code suivant illustre l'utilisation de l'objet
charWrapper. Remarquez que charPrimitive est un type de données primitif (char). Cependant, avec cette méthode, des
types de données primitifs peuvent être attribués aux enveloppes de types.
char charPrimitive = charWrapper.charValue( );
Les méthodes toString et Equals sont utilisées de la même façon que dans la classe Object. Elles sont généralement
utilisées pour le débogage.

Primitive type Size Minimum Maximum Wrapper type Default


boolean — — — Boolean false
char 16-bit Unicode 0 16 Character ‘\u0000’ (null)
Unicode 2 -1
byte 8-bit -128 +127 Byte (byte)0
short 16-bit 15 15 Short (short)0
-2 +2 —1
int 32-bit 31 31 Integer 0
-2 +2 —1
long 64-bit 63 63 Long 0L
-2 +2 —1
float 32-bit IEEE754 IEEE754 Float 0.0f
double 64-bit IEEE754 IEEE754 Double 0.0d
void — — — Void
Tableau 2 Types primitifs et Classes enveloppes correspondantes

NB : Tous les types numériques sont signés.

Prof. Marcellin NKENLIFACK, mars 2013 38


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.4.2.3 La classe Math
La classe Math fournit des méthodes utiles qui implémentent des fonctions mathématiques courantes. Cette classe
n'est pas instanciée; elle est déclarée comme final, ce qui signifie qu'elle ne comporte pas de sous-classe. Parmi les
méthodes de cette classe, se trouvent : sin, cos, exp, log, max, min, random, sqrt et tan.
Quelques méthodes sont surchargées pour accepter et renvoyer différents types de données. Voici quelques exemples
d'utilisation de ces méthodes.
double d1 = Math.sin (45);
double d2 = 23.4;
double d3 = Math.exp (d2);
double d4 = Math.log (d3);
double d5 = Math.max (d2, Math.pow (d1, 10);
Cette classe déclare aussi les constantes PI et E (exponentielle de 1) qui peuvent être facilement utilisées dans les calculs.
Ne confondez pas la classe Math avec le paquet java.math. Ce dernier assure la prise en charge des classes permettant de
travailler avec des nombres importants.

4.4.2.4 La classe String


La classe String sert à déclarer et à manipuler des chaînes de caractères. A la différence de C/C++, Java n'utilise pas
de tableaux de caractères pour représenter des chaînes. La classe String, destinée aux chaînes de caractères constantes, est
habituellement construite quand le compilateur Java rencontre une chaîne de caractères entre guillemets. Il y a cependant
plusieurs façons de construire des chaînes. Le tableau suivant donne la liste des constructeurs de chaînes ainsi que les
paramètres qu'ils acceptent.
Constructeurs
String ( )
String (String)
String (char valeur[ ])
String (char valeur[ ], int décalage, int nombre)
String (StringBuffer)
La classe String contient plusieurs méthodes importantes, essentielles dans le traitement des chaînes de caractères.
Liste de quelques méthodes parmi les plus utiles, avec ce qu'elles acceptent et renvoient.
length ( ) -> int
charAt (int index) -> char
compareTo (String) -> int
startsWith (String prefixe) -> boolean
endsWith (String suffixe) -> boolean
indexOf (int ch) -> int
substring (int indexDébut, int indexFin) ->String
concat (String) -> String
toLowerCase ( ) -> String
toUpperCase ( ) -> String
valueOf (Object) -> String
Comme elles sont surchargées pour accepter et renvoyer différents types de données, ces méthodes sont encore plus
puissantes. Les exemples suivants illustrent l'utilisation de la classe String et de quelques-unes de ses méthodes.
String s1 = new String ("Hello World.");
char cArray[ ] = {'J', 'B', 'u', 'i', 'l', 'd', 'e', 'r'};
String s2 = new String (cArray); //s2 = "JBuilder"
int i = s1.length( ); //i = 12
char c = s1.charAt(4); //c = 'o'
i = s1.indexOf('l'); //i = 2 (le premier 'l')
String s3 = "abcdef".substring (2, 5) //s3 = "cde"
String s4 = s3.concat ("f");//s4 = "cdef"
String s5 = valueOf (i); //s5 = "2" (valueOf( )est static)

4.4.2.5 La classe StringBuffer


La classe StringBuffer est différente de la classe String, puisque les objets StringBuffer peuvent être modifiés. Tout
comme la classe String, la classe StringBuffer dispose de plusieurs constructeurs.
Liste des constructeurs de la classe StringBuffer.
StringBuffer ( )
StringBuffer (int longueur)
StringBuffer (String)
Plusieurs méthodes importantes différencient la classe StringBuffer et la classe String, dont : Length, Capacity, setLength,
charAt, setCharAt, Append, Insert et toString.
La méthode Append est utilisée relativement souvent dans le traitement des objets StringBuffer. Elle sert à ajouter du texte
à l'objet StringBuffer. Par chance, la méthode Append a été fortement surchargée.

Prof. Marcellin NKENLIFACK, mars 2013 39


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
La méthode Capacity est également souvent utilisée avec les objets StringBuffer. Elle renvoie la quantité de mémoire
affectée au StringBuffer. Comme la mémoire affectée à un objet StringBuffer peut être contrôlée avec le constructeur
StringBuffer (int length), cette valeur peut être supérieure à la valeur renvoyée par la méthode Length. Le code suivant
illustre quelques-unes des méthodes associées à la classe StringBuffer.
StringBuffer s1 = new StringBuffer(10);
int c = s1.capacity( ); //c = 10
int l = s1.length( ); //l = 0
s1.append("Bor"); //s1 = "Bor"
s1.append("land"); //s1 = "land"
c = s1.capacity( ); //c = 10
l = s1.length( ); //l = 7
s1.setLength(2); //s1 = "Bo"
StringBuffer s2 = new StringBuffer("Helo World");
s2.insert (3, "l"); //s2 = "Hello World"

4.4.2.6 La classe System


La classe System permet d'accéder aux ressources indépendantes de la plate-forme du système. C'est une classe
déclarée comme final, qui ne peut donc pas donner naissance à des sous-classes. Ses méthodes et variables sont également
déclarées comme statiques, ce qui lui permet d'être disponible sans être instanciée.
Les méthodes de la classe System sont utiles dans de nombreux cas. Une fonction importante consiste à obtenir l'heure du
système avec la méthode currentTimeMillis. Il est également possible d'extraire et de modifier les ressources du système
avec les méthodes Get et Set. La classe System permet de forcer la « Garbage collection » avec la méthode gc ; enfin, la
classe System permet aux développeurs de charger des bibliothèques de liens dynamiques avec la méthode loadLibrary.
L'aspect le plus utile de la classe System tourne autour des variables qu'elle déclare, qui permettent d'avoir une interaction
avec le système. On y trouve les variables in, out, err. La variable in représente le flux d'entrée standard du système, alors
que la variable out représente le flux de sortie standard. La variable err est le flux d'erreur standard. Les flux sont décrits en
détail dans la section consacrée au paquet des E/S.

4.4.3 LE PAQUET DES UTILITAIRES (UTIL)


Le paquet java.util contient plusieurs classes et interfaces utilitaires cruciales pour le développement Java. La
plupart d'entre elles aident le développeur lors de la conception de différents types de structures de données.
Quelques-unes des classes associées au paquet des utilitaires
Calendar = Permet l'utilisation des fonctions de calendrier
Date = Représente les dates et les heures
Dictionary = Classe abstraite parent de Hashtable
Hashtable = Permet d'associer des clés à des valeurs
SimpleTimeZone = Représente un fuseau horaire
Stack = Permet d'empiler les objets
StringTokenizer = Décompose un objet String en jetons
Vector = Implémente un tableau dynamique d'objets
Le paquet des utilitaires déclare aussi trois interfaces : Enumeration, EventListener et Observable. Dans cette section,
nous n'aborderons que la classe Vector et l'interface Enumeration.

4.4.3.1 L'interface Enumeration


L'interface Enumeration sert à implémenter une classe pouvant énumérer des valeurs. Une classe qui implémente
l'interface Enumeration facilite l'investigation de structures de données.
Avec les méthodes définies dans l'interface Enumeration, l'objet Enumeration peut extraire en continu tous les éléments
d'une structure de données, un par un. Seules deux méthodes sont déclarées dans l'interface Enumeration :
hasMoreElements et nextElement.
La méthode hasMoreElements renvoie True s'il reste des éléments dans la structure de données. La méthode nextElement
renvoie l'objet suivant dans la structure de données en cours d'énumération.

Un exemple simple illustre l'implémentation de l'interface Enumeration. Il contient une classe appelée canEnumerate, qui
implémente l'interface Enumeration. Une occurrence de cette classe peut être utilisée pour imprimer tous les éléments d'un
objet Vector (v dans ce cas).
canEnumerate enum = v.elements( );
while (enum.hasMoreElements( ))
{
System.out.print (enum.nextElement( ));
}
Un objet Enumeration est limité car il ne peut être utilisé qu'une seule fois. L'interface ne dispose pas de méthode
permettant de revenir sur l'élément précédent. Ainsi, une fois la totalité de la liste énumérée, l'objet est consommé.

Prof. Marcellin NKENLIFACK, mars 2013 40


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.4.3.2 La classe Vector
Le JDK 1.1 ne prend pas en charge de nombreuses structures de données dynamiques, comme les listes liées et les
files d'attente ; elle définit seulement une classe Stack. Cependant, la classe Vector permet d'implémenter facilement des
structures de données dynamiques.
La liste de quelques méthodes de la classe Vector parmi les plus importantes:
Vector (int capacitéInitiale)
Vector (int capaciteInitiale, int incrémentCapacité)
setSize (int nouvelleTaille)
capacity ( )
size ( )
elements ( )
elementAt (int)
firstElement ( )
lastElement ( )
removeElementAt (int index)
addElement (Object)
toString ( )
Comme elle affecte plus de mémoire que nécessaire pendant l'ajout de nouveaux éléments, la classe Vector est efficace.
Par conséquent, la capacité d'un objet Vector est généralement supérieure à sa taille réelle. Le paramètre incrémentCapacité
du deuxième constructeur précise l'augmentation de la capacité de l'objet Vector quand on lui ajoute un élément.
Le code suivant illustre l'utilisation de la classe Vector. Dans ce code, l'objet Vector vector1 est créé et énumère ses
éléments de trois façons : avec la méthode nextElement d'Enumeration, avec la méthode elementAt de Vector et avec la
méthode toString de Vector. Pour afficher le résultat, un composant AWT appelé textArea est créé et la propriété text est
définie avec la méthode setText. Voici le code ajouté à la fin du constructeur VectorTest1.
Vector vector1 = new Vector (10, 2); //taille initiale : 10,
//incrémentCapacité : 2
for (int i=0; i<10;i++)
vector1.addElement(new Integer(i)); //addElement n'accepte pas
//les types int
//enumérer vector1
Enumeration e = vector1.elements( );
frame.textArea1.setText ("Eléments utilisant nextElement( )
d'Enumeration :\n");
while (e.hasMoreElements( ))
frame.textArea1.setText (frame.textArea1.getText( )+
e.nextElement( )+ " | ");
frame.textArea1.setText (frame.textArea1.getText( )+ "\n\n");
//enumérer en utilisant la méthode elementAt( )
frame.textArea1.setText (frame.textArea1.getText( )+ "Eléments
utilisant elementAt( ) de Vector :\n");
for (int i=0; i< vector1.size( );i++)
frame.textArea1.setText (frame.textArea1.getText( )+
vector1.elementAt(i) + " | ");
frame.textArea1.setText (frame.textArea1.getText( )+ "\n\n");
//enumérer en utilisant la méthode toString( )
frame.textArea1.setText (frame.textArea1.getText( )+ "Voici
le vecteur sous forme de String :\n");
frame.textArea1.setText (frame.textArea1.getText( )+
vector1.toString( ));

4.4.4 LE PAQUET DES ENTRÉE/SORTIES ( E/S - I/O )


Le paquet java.io prend en charge la lecture et l'écriture de données sur différentes unités. Les classes de ce paquet
peuvent être réparties en trois paquets différents. Il s'agit des classes de flux d'entrée, des classes de flux de sortie, des
classes File et de la classe StreamTokenizer (décrite plus loin dans ce chapitre).

4.4.4.1 Classes de flux d'entrée


Un flux d'entrée (Input) sert à lire des données depuis une source d'entrée (c'est-à-dire un fichier, une chaîne de
caractères, la mémoire, etc.). Dans cette définition, il y a plusieurs classes encapsulées. Les classes de flux d'entrée incluent
: InputStream, BufferedInputStream, DataInputStream, FileInputStream et StringBufferInputStream.
La méthode de base de lecture de données avec une classe de flux Input est toujours la même : (1) créer une occurrence
d'une classe de flux d'entrée, puis (2) préciser l'emplacement des données à lire. Les classes de flux d'entrée utilisent les
données sous forme d'un flux de données continu. S'il ne reste plus de données disponibles, la classe de flux d'entrée se
bloque (attend que de nouvelle données soient disponibles).
Outre les classes de flux d'entrée, le paquet des E/S fournit des classes de lecture qui correspondent à toutes les classes de
flux d'entrée (sauf DataInputStream). Il s'agit des classes Reader, BufferedReader, FileReader et StringReader. Les
classes de lecture sont identiques aux classes de flux d'entrée, sauf qu'elles lisent des caractères Unicode et non des octets.

Prof. Marcellin NKENLIFACK, mars 2013 41


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
La classe InputStream est une classe abstraite de laquelle toutes les autres classes de flux d'entrée sont dérivées. Elle
fournit l'interface de base pour la lecture d'un flux d'octets. Le tableau suivant dresse la liste de quelques méthodes
InputStream avec ce qu'elles attendent. Chacune des méthodes, sauf la méthode close, renvoie une valeur de type int.
read ( )
read (byte b[ ])
read (byte b[ ], int décalage, int longueur)
available ( )
skip (long)
close ( )
La première méthode, abstract int read, lit un octet à partir du flux en entrée et renvoie un nombre entier (la valeur
renvoyée peut être de type char). A la fin du flux, elle renvoie -1. La deuxième méthode, int read(byte b[ ]), lit plusieurs
octets et les place dans son paramètre tableau. Elle renvoie le nombre d'octets lus ou -1 quand la fin du flux est atteinte. La
dernière méthode read, int read(byte b[ ], int décalage, int longueur), permet au développeur de préciser le nombre d'octets
à lire et où les mettre dans le tableau.
La méthode int available renvoie le nombre d'octets en entrée qui peuvent être lus sans blocage. La méthode skip ignore
dans le flux un nombre d'octets précisé. Pour terminer, la méthode close permet de fermer le flux en entrée. Normalement,
cette méthode est appelée automatiquement, mais il est plus sûr de l'appeler manuellement.
La classe FileInputStream ressemble beaucoup à la classe InputStream, sauf qu'elle est conçue pour lire à partir de
fichiers. Elle contient deux constructeurs :
FileInputStream(String nom ) et FileInputStream(File fichier). Le premier constructeur prend comme paramètre un nom
de fichier. Le deuxième prend simplement un objet File. La classe File est présentée plus loin. L'exemple suivant illustre
une utilisation de la classe FileInputStream.
import java.io.*;
class fileReader {
public static void main (string args[ ] )
{
byte buff[ ] = new byte [80];
try {
InputStream fileIn = new FileInputStream("Readme.txt");
int i = fileIn.read(buff);
}
catch(FileNotFoundException e)
{
}
catch(IOException e)
{
}
String s = new String(buff);
System.out.println(s);
}
}
Dans cet exemple, un tableau de caractères est créé pour recevoir les données en entrée. Ensuite, un objet FileInputStream
est instancié et transmet le nom du fichier en entrée à son constructeur. Ensuite, la méthode read( ) de FileInputStream lit
un flux de caractères qu'elle met dans le tableau buff. Les 80 premiers octets du fichier Readme.txt sont lus et mis dans le
tableau buff. La classe FilerReader aurait pu être utilisée à la place de la méthode FileInputStream. Les seules
modifications nécessaires seraient le remplacement d'un tableau de type byte par un tableau de type char, et l'objet reader
serait instancié de la manière suivante.
Reader fileIn = new FileReader("Readme.txt");
Enfin, pour voir le résultat de la lecture, un objet string est créé en utilisant le tableau buff array, puis il est transmis à la
méthode System.out.println.
Comme cela a déjà été dit, la classe System est définie dans java.lang et donne accès aux ressources du système.
System.out est un membre statique de la classe System et représente le périphérique de sortie standard. La méthode println
est appelée pour envoyer la sortie sur le périphérique de sortie standard. L'objet System.out est du type PrintStream,
présenté dans la section réservée aux classes de flux de sortie.
L'objet System.in, du type InputStream, est un autre membre statique de la classe System. Naturellement, il représente le
périphérique d'entrée standard.

4.4.4.2 Classes de flux de sortie


Les classes de flux de sortie (Output) sont la contrepartie des classes de flux d'entrée. Elles permettent d'envoyer
des flux de données en sortie sur diverses unités. Dans Java, les classes de flux de sortie principales sont : OutputStream,
PrintStream, BufferedOutputStream, DataOutputStream et FileOutputStream.
Pour envoyer un flux de données en sortie, il faut créer un objet de flux Output et diriger les données en sortie vers une
unité particulière. Comme on peut s'y attendre, il y a aussi des classes d'écriture. A toutes les classes, sauf à
DataOutputStream, correspond une classe d'écriture. Comme la classe OutputStream est la contrepartie de la classe
InputStream, elle définit les méthodes suivantes.

Prof. Marcellin NKENLIFACK, mars 2013 42


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
write (int)
write (byte b[ ] )
write (byte b[ ], int décalage, int longueur)
flush ( )
close ( )
La méthode flush sert à vider le flux en sortie (c'est-à-dire qu'elle force la sortie des données qui étaient stockées en
mémoire tampon). La classe PrintStream est principalement destinée à l'envoi en sortie des données sous forme de texte.
Elle a deux constructeurs : PrintStream(OutputStream) et PrintStream(OutputStream, boolean autoflush).
Les deux constructeurs sont différents. Avec le premier, l'objet PrintStream vide les données de la mémoire tampon sur la
base de conditions précisées, alors que le deuxième vide les données quand il trouve un caractère de nouvelle ligne (si
autoflush a la valeur True).
Voici quelques méthodes définies par PrintStream.
checkError ( )
print (Object obj)
print (String s)
println ( )
println (Object obj)
Les méthodes print et println sont surchargées pour accepter et renvoyer différents types de données. La méthode
checkerror vide le flux et renvoie une valeur False en cas d'erreur.

4.4.4.3 Classes de fichiers


Les classes FileInputStream et FileOutputStream fournissent uniquement les fonctions de base de gestion des
entrées et sorties de fichiers. Le paquet java.io fournit la classe File et la classe RandomAccessFile pour une prise en
charge évoluée des fichiers. La classe File fournit un accès facile aux attributs et fonctions des fichiers.
La classe RandomAccessFile fournit diverses méthodes de lecture et d'écriture sur un fichier.
La classe File a trois constructeurs : File (String chemin), File (String chemin, String nom) et File (File dir, String nom).
La classe File implémente également de nombreuses méthodes importantes.
Liste de méthodes, avec ce qu'elles renvoient
delete -> boolean
canRead -> boolean
canWrite -> boolean
exists -> boolean
isDirectory -> boolean
renameTo -> boolean
long lastModified -> long
long length -> long
getName -> String
getParent -> String
getPath -> String
La classe RandomAccessFile est plus puissante que les classes FileInputStream et FileOutputStream. Elle implémente
des méthodes de lecture et d'écriture pour tous les types primitifs. Elle a les deux constructeurs suivants :
RandomAccessFile(String nom, String mode) et RandomAccessFile(File fichier, String mode). Le paramètre mode
précise si l'objet RandomAccessFile est utilisé en lecture ("r") ou en lecture/écriture ("rw"). RandomAccessFile
implémente de nombreuses méthodes puissantes.
Liste de quelques méthodes, avec ce qu'elles acceptent.
skipBytes (int)
getFilePointer ( )
seek (long pos)
read ( )
read (byte b[ ], int décalage, int longueur)
readType ( )
write ( )
write (byte b[ ], int décalage, int longueur)
length ( )
close ( )

4.4.4.4 La classe StreamTokenizer


Cette classe sert à décomposer un flux en jetons individuels. La classe StreamTokenizer implémente des méthodes
utilisées pour définir la syntaxe lexicale des jetons. Cette technique de traitement des flux en jetons est peut-être la plus
utilisée dans l'écriture de compilateurs. StreamTokenizer fournit des méthodes permettant de faire de l'analyse syntaxique
rudimentaire sur les données en entrée. La lecture se fait d'unité lexicale (token) en unité lexicale. Le constructeur d'un
StreamTokenizer prend en argument un objet StreamInput ou Reader.
Exemple de code :
StreamTokenizer tokenizer = new StreamTokenizer(
new StringReader("Mary had 1 little lamb..."));

while(tokenizer.nextToken() != StreamTokenizer.TT_EOF){

Prof. Marcellin NKENLIFACK, mars 2013 43


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

if(tokenizer.ttype == StreamTokenizer.TT_WORD) {
System.out.println(tokenizer.sval);
} else if(tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
System.out.println(tokenizer.nval);
} else if(tokenizer.ttype == StreamTokenizer.TT_EOL) {
System.out.println();
}

}
La classe StreamTokenizer permet de reconnaître des identificateurs, des nombres, des chaînes entre côtes, et autre
styles de commentaires. Il est possible de spécifier que certains caractères puissent être interprétés comme des espaces
blancs ou des caractères de début (begin) ou de fin (end), etc. tout ceci est configuré dans votre StreamTokenizer
avant le début de l’analyse du contenu.

4.4.5 BIBLIOTHÈQUE GÉNÉRIQUE JAVA (JGL)


Le JDK 1.1 prend en charge trois types de structures de données : Vector, Stack et Hashtable. Il ne prend pas très
bien en charge divers algorithmes, comme le « tri » et le « filtrage ». La bibliothèque générique Java (JGL), distribuée
gratuitement, peut pallier à ces insuffisances. Parmi les fonctionnalités les plus utiles de la JGL se trouvent la sérialisation,
la sécurité multi-thread, des performances optimales, 11 structures de données et plus de 40 algorithmes ; elle est
totalement compatible avec le JDK.
La JGL inclut aussi plusieurs structures de données.
Définitionn de chaque structure de données.
Array = Linéaire, stockage contigu
Deque = Linéaire, stockage non contigu ; insère éléments aux 2 extrémités
Dlist = Liste doublement liée
Slist = Liste simplement liée
HashMap = Stocke des mappes en utilisant une table hash
OrderedMap = Stocke des mappes dans l'ordre
HashSet = Stocke un ensemble en utilisant une table hash
OrderedSet = Stocke un ensemble dans l'ordre
PriorityQueue = Déroule des éléments dans un ordre trié
Queue = Structure de données FIFO (premier entré, premier sorti)
Stack = Structure de données FILO (premier entré, dernier sorti)
La JGL contient aussi plusieurs types d'algorithmes.
Description de chaque algorithme
Applying = Applique une fonction à tous les éléments d'une séquence
Copying = Copie une séquence
Filling = Remplit une séquence avec un élément unique
Filtering = Filtre une séquence
Finding = Trouve un élément sur la base d'une condition
Heap = Manipule un tas
Replacing = Remplace un élément
Reversing = Inverse une séquence
Set operations = Exécute une union, une intersection, une inclusion, une différence
Shuffling = Mélange une séquence aléatoirement
Sorting = Trie une séquence
Swapping = Intervertit des éléments ou des séquences
Outre les conteneurs et les algorithmes, la JGL définit plusieurs interfaces et exceptions. Elle contient aussi des itérateurs
qui prennent en charge différentes itérations dans les conteneurs et les objets des fonctions.
Récapitulatif du paragraphe :
Les bibliothèques des classes standards fournissent de nombreux paquets essentiels au développement Java. Ces paquets
incluent le langage, les E/S, les utilitaires, le réseau, AWT et le texte, la sécurité, RMI, Reflection et SQL.
Les types de données primitifs sont essentiels pour des raisons de performances. Sans ces types de données, des calculs
complexes ralentiraient beaucoup les performances de l'application.
Avec les classes d'enveloppe de type, les développeurs peuvent traiter des types de données primitifs comme s'il s'agissait
d'objets.
Le paquet de la JBCL (Bibliothèque des Composants Java Beans) apporte aux développeurs plusieurs composants UI
dont : ButtonBar, ButtonControl, CheckBoxControl, CheckBoxPanel, ListControl, ChoiceControl, GridControl et
StatusBar.
Avec les classes MultiCaster, les Java Beans disposent d'un moyen efficace de gestion des événements. Elles utilisent un
tableau à la place d'un vecteur pour conserver une liste des objets « Auditeurs » d'événements.

Prof. Marcellin NKENLIFACK, mars 2013 44


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

4.5 LES TABLEAUX EN JAVA


Un tableau est un ensemble d’éléments de même type désignés par un nom unique, chaque élément étant représenté
par un indice précisant sa position au sein de l’ensemble. Les tableaux sont considérés comme des objets et les tableaux à
plusieurs indices peuvent être obtenus par composition de tableaux.

4.5.1 DÉCLARATION ET CRÉATION


. ETUDIANT te [ ] ; // te est une référence à un tableau d’objets (classe EUDIANT)
. int t [ ] ; // t est un tableau d’entiers
. int [ ] t ; // autre façon de déclarer
♦ Les tableau sont dynamiques par défaut. D’ailleurs, une déclaration de tableau ne doit pas préciser la taille du tableau.
L’instruction ci-dessous sera rejétée par le compilateur.
. int t2 [ ] ; // erreur :
♦ La création se fait à l’aide de l’opérateur new.
. int t ;
. t = new int [n] ;
♦ La valeur de l’expression fournie à l’opérateur new n’est calculée qu’au moment de l’exécution du programme. Elle peut
donc différer d’une fois à l’autre, contrairement à ce qui se produit dans le cas des langages fixant la dimension lors de la
compilation.
♦ Lors de la déclaration d’une référence de tableau, on peut fournir une liste de valeurs :
. int t [ ] = {1, 0, 8,4} ; // Mais la notation {1, 0, 8, 4} n’est utilisable que dans une déclaration.
. t = {1, 0, 8,4} ; // incorrecte.
♦ Il est possible d’affecter la référence (comme pointeurs en C) d’un tableau à un autre tableau :
. int [ ] t1 = new int [3] ;
. for (int i=0; i<3; i++) t1[I] =i;
. int [ ] t2 = new int [2];
. for (int i=0; i<2; i++) t2[I] =10+i;
. t1 = t2; // la référence contenue dans t2 est reportée dans t1; désormais, t1 et t2
désignent le même tableau.
♦ La taille d’un tableau est déterminée par le champ length.
. int [ ] t1 = new int [3] ;
. System.out.println( “taille de t : “+t.length ); // affiche taille du tableau : 3

4.5.2 EXEMPLES :
♦ Nous présentons un exemple de programme utilisant un tableau d’objets de type Point :
public class TabPoint
{ public static void main (String args[])
{ Point [] tp ;
tp = new Point[3] ;
tp[0] = new Point (1, 2) ;
tp[1] = new Point (4, 5) ;
tp[2] = new Point (8, 9) ;
for (int i=0 ; i<tp.length ; i++)
tp[i].affiche() ;
}
}
class Point
{ public Point(int x, int y)
{ this.x = x ; this.y = y ;
}
public void affiche ()
{ System.out.println ("Point : " + x + ", " + y) ;
}
private int x, y ;
}
♦ Exemple de programme qui détermine le nombre d’élèves ayant une note supérieure à la moyenne de la classe.
public class Moyenne
{ public static void main (String args[])
{ int i, nbEl, nbElSupMoy ;
double somme ;
double moyenne ;
System.out.print ("Combien d'eleves ") ;
nbEl = Clavier.lireInt();
double notes[] = new double[nbEl] ;
for (i=0 ; i<nbEl ; i++)
{ System.out.print ("donnez la note numero " + (i+1) + " : " ) ;
notes[i] = Clavier.lireDouble() ;
}
for (i=0, somme=0 ; i<nbEl ; i++) somme += notes[i] ;
moyenne = somme / nbEl ;
System.out.println ("\nmoyenne de la classe " + moyenne) ;

Prof. Marcellin NKENLIFACK, mars 2013 45


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
for (i=0, nbElSupMoy=0 ; i<nbEl ; i++ )
if (notes[i] > moyenne) nbElSupMoy++ ;
System.out.println (nbElSupMoy + " eleves ont plus de cette moyenne") ;
}
}

Exercice 3 :
Modifier le programme précédent pour pouvoir effectuer le TRI des notes saisies avant de les afficher.

Exercice 4 :
Effectuer le produit vectoriel entre deux vecteur de réels.

4.5.3 TABLEAUX À PLUSIEURS INDICES :


Les tableau à plusieurs indices n’existent pas explicitement en Java. On peut néanmoins les obtenir en créant des tableaux
dont les éléments sont eux même des tableaux. Cette possibilité est d’ailleurs plus riche que celle de tableaux à plusieurs
indices offerte par les autres langages. Elle permet entre autres de créer des tableaux « irréguliers », c’est à dire dans
lesquels les différentes lignes pourront être de taille différente.
♦ Déclaration et création :
int t [ ] [ ] ; int [ ] t1 [ ] ; int [ ] [ ] t2 ;
t = { new int [3], new int [2]}; // l’initialiseur de t comporte deux éléments dont l’évaluation crée un tableau de 3
entiers et un tableau de 2 entiers.
Ainsi, t[0] désigne la référence au premier tableau de 3 entiers ; t[0][1] le deuxième élément de ce tableau ; etc.
t.length vaut 2 ; t[0].length vaut 2 ; t[1].length vaut 3 ;
♦ Autre
int t [ ] [ ] ; t = new int [2] [ ] ; // création d’un tableau de 2 tableaux d’entiers
int [ ] t1 = new int [3] ; // t1 référence à un tableau de 3 entiers
int [ ] t2 = new int [2] ; // t2 référence à un tableau de 2 entiers
t[0] = t1 ; t[1] = t2 ; // rangement des deux références dans t
int t3 [ ] [ ] = { {30, 31, 32}, {20, 21} } ; // exemple d’une imbrication des initialisations
♦ Exemple :
Ce programme utilise deux méthodes statiques définies dans une classe Util, permettant :
- d’afficher les valeurs des éléments d’un tableau d’entiers à deux indices, ligne par ligne (méthode affiche).
- De mettre à zéro les éléments d’un tableau d’entiers à deux indices (méthode raz).
class Util
{ static void raz (int t[] [])
{ int i, j ;
for (i= 0 ; i<t.length ; i++)
for (j=0 ; j<t[i].length ; j++)
t[i] [j] = 0 ;
}
static void affiche (int t[] [])
{ int i, j ;
for (i= 0 ; i<t.length ; i++)
{ System.out.print ("ligne de rang " + i + "= ") ;
for (j=0 ; j<t[i].length ; j++)
System.out.print (t[i] [j] + " ") ;
System.out.println() ;
}
}
}
public class Tab2ind1
{ public static void main (String args[])
{ int t[] [] = { {1, 2, 3}, {11, 12}, {21, 22, 23, 24} } ;
System.out.println ("t avant raz : ") ;
Util.affiche(t) ;
Util.raz(t) ;
System.out.println ("t apres raz : ") ;
Util.affiche(t) ;
}
}

Exercice 5 :
Modifier le programme précédent en le rendant plus dynamique et en créant une interface graphique utilisateur à cet effet. On
mettra l’accent sur la qualité et la convivialité de l’interface (saisie/édition des matrice, etc.). A cet effet, le gestionnaire de mise en
forme (Layout manager) pourra être utilisé pour faciliter la présentation : BoerderLayout, GridLayout, FlowLayout, etc.

Exercice 6 :

Prof. Marcellin NKENLIFACK, mars 2013 46


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
• Calculer le produit et la somme de deux matrices d’ordre n et afficher le résultat.

Exercice 7 :
Résoudre le système d’équation linéaire AX=B ; //A, X, B étant des matrices (confère cours analyse numérique)

4.6 IMPLANTATION PRATIQUE DES FLUX ET FICHIERS EN JAVA


Les fichiers seront manipulés à l’aide des flux (associés aux fichiers). Un flux est un "canal" susceptible de recevoir
(flux de sortie) ou de délivrer (flux d’entrée) de l’information sous forme d’une suite d’octets.
Comme dans la plupart des langages, Java distingue les flux binaires des flux texte. Dans le premier cas,
l’information est transmise sans modification de la mémoire au flux ou du flux à la mémoire. Dans le second cas,
l’information subit une transformation appelée formatage de manière que le flux reçoive ou transmette en définitive une
suite de caractères. La fonction println effectue un tel formatage.
Les fichiers sont manipulés à travers des flux à accès direct ou à accès séquentiel.
Java possède plusieurs dizaines de classes pour la manipulation des flux, que nous ne pouvons pas détailler toutes
ici. C’est pourquoi nous allons voir comment procéder pour réaliser les opérations classiques.

4.6.1 CRÉATION SÉQUENTIELLE D’UN FICHIER BINAIRE


La classe FileOutputStream (dérivée de la classe abstraite OutputStream, base de toutes les classes relatives aux
flux binaires) permet de manipuler un flux binaire associé à un fichier en écriture. L’un de ses constructeurs associant
l’objet f à un fichier a pour syntaxe :
FileOutputStream f = new FileOutputStream ("nomfich.dat"); // ouverture d’un fichier en écriture
Cependant, les méthodes de la classe FileOutputStream sont rudimentaires (ce sont les mêmes que celles prévues dans
OutputStream), limitées à envoyer sur le flux un octet ou un tableau d’octets.
Par contre, la classe DataOutputStream comporte des méthodes plus évoluées (envoi sur un flux d’un type primitif
quelconque) et dispose (entre autres) d’un constructeur recevant en argument un objet de type FileOutputStream.
DataOutputStream sortie = new DataOutputStream ; // crée un objet sortie qui par l’intermédiaire de l’objet f se trouve
associé au fichier "nomfich.dat".
♦ Exemple : un petit programme qui lit les nombres entiers au clavier (jusqu’à ce qu’on entre un nombre nul) et les
recopie dans un fichier binaire.
import java.io.* ;
public class Crsfic1
{ public static void main (String args[]) throws IOException
{
String nomfich ;
int n ;
System.out.print ("donnez le nom du fichier a creer : ") ;
nomfich = Clavier.lireString() ;
DataOutputStream sortie = new DataOutputStream
( new FileOutputStream (nomfich)) ;
do { System.out.print ("donnez un entier : ") ;
n = Clavier.lireInt() ;
if (n != 0)
{ sortie. writeInt (n) ;
}
}
while (n != 0) ;
sortie.close () ;
System.out.println ("*** fin creation fichier ***");
}
}
Remarques : i) La clause throws IOException dans l’entête du main. En effet, la méthode WriteInt (comme toutes les
méthodes d’écriture et de lecture) peut déclencher une exception (explicite) du type IOException en cas d’érreur
d’écriture. Dans ces conditions, celle-ci doit être soit traitée, soit déclarée dans throws.
ii) Java dispose d’une classe File permettant de manipuler des noms de fichiers et de répertoires. On aurait pu mettre en
argument du constructeur FileOutputStream un objet de type File à la place d’un objet de type String.

4.6.2 LISTE SÉQUENTIELLE (D’ÉLÉMENTS) D’UN FICHIER BINAIRE :


La classe FileInputStream dérivée de InputStream permet de manipuler un flux binaire envoyé à un fichier en
lecture. La syntaxe de l’un de ses constructeurs est :
FileInputStream f = new FileInputStream (“nomfich.dat”);
Si le fichier n’existe pas, une exception FileNotFoundException (dérivant de IOException) est générée.
On dispose également d’une classe DataInputStream.
DataInputStream entree = new DataInputStream (f); // crée un objet entrée par l’objet f associé à "nomfich.dat".
♦ Exemple : un petit programme qui lit un fichier binaire d’entiers.

Prof. Marcellin NKENLIFACK, mars 2013 47


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
import javax.swing.* ; // pour showInputDialog
import java.io.* ;
public class Lecsfic1
{ public static void main (String args[]) throws IOException
{ String nomfich ;
int n = 0 ;
System.out.print ("donnez le nom du fichier a lister : ") ;
nomfich = Clavier.lireString() ;
DataInputStream entree = new DataInputStream
( new FileInputStream (nomfich)) ;
System.out.println ("valeurs lues dans le fichier " + nomfich + " :") ;
boolean eof = false ; // sera mis a true par exception EOFile
while (!eof)
{ try
{ n = entree.readInt () ;
}
catch (EOFException e)
{ eof = true ;
}
if (!eof) System.out.println (n) ;
}
entree.close () ;
System.out.println ("*** fin liste fichier ***");
}
}
Exercice 8 :
1- Ecrire le programme qui crée un fichier de 1000 entiers uniformément répartis entre 0 et 20, dénommé Notes.data et placé
dans le sous-répertoire IG
2- Ecrire le programme qui comptera le nombre d’apparitions de chaque Note (on rangera ces fréquences dans un tableau). On
affichera le résultat et on dessinera ensuite l’histogramme des fréquences. Conclusion ?
3- Ecrire le programme qui déterminera pour chaque valeur la plus longue suite de valeurs identiques.

4.6.3 ACCÈS DIRECT À UN FICHIER BINAIRE


La classe RandomAccessFile dispose des fonctionnalités des deux classes DataOutputStream et DataInputStream,
y compris des méthodes readInt, readFloat, writeInt, writeFloat, …
RandomAccessFile entree = new RandomAccessFile (“nomfich.dat”); // “rw” pour read &write…
La classe RandomAccessFile dispose d’une méthode spécifique seek pour agir sur le « pointeur de fichier ». Tant que l’on
n’agit pas explicitement sur ce pointeur, il est automatiquement incrémenté après chaque opération, du nombre d’octets lus
ou écrits.
♦ Exemple : un petit programme d’accès à un rang (position) quelconque d’un fichier. La consultation s’achève lorsqu’on
entre 0.
import java.io.* ;
public class Accdir1
{ public static void main (String args[]) throws IOException
{
String nomfich ;
int n, num ;
RandomAccessFile entree ;
System.out.print ("donnez le nom du fichier a consulter : ") ;
nomfich = Clavier.lireString() ;
entree = new RandomAccessFile (nomfich, "r") ;
long taille = entree.length() ;

do
{ System.out.print ("Numero de l'entier recherche : ") ;
num = Clavier.lireInt() ;
if (num == 0) break ;
int rang = 4*(num-1) ;
if ( (rang>0) && (rang<taille))
{ entree.seek (rang) ;
n = entree.readInt() ;
System.out.println (" valeur = " + n) ;
}
else { System.out.println ("entier inexistant") ;
continue ;
}
}
while (num != 0) ;

entree.close () ;
System.out.println ("*** fin consultation fichier ***");
}
}

Prof. Marcellin NKENLIFACK, mars 2013 48


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
Remarque : i) la formule 4*(num –1) se justifie par le fait que le premier octet du fichier est de rang 0 et que, nous avons
convenu que, pour l’utilisateur, le premier entier du fichier serait le numéro 1.
ii) noter aussi la protection contre le positionnement hors du fichier.
NOTE : L’accès direct n’a d’intérêt que lorsqu’on est en mesure de fournir le rang de l’emplacement concerné, ce qui n’est
pas toujours possible. Par exemple dans un fichier annuaire (répertoire téléphonique), on recherche une personne par son
nom plutôt que par son numéro d’ordre dans le fichier. Cette contrainte qui semble imposer une recherche séquentielle,
peut être contournée par la création d’un "index", c’est à dire une table de correspondance entre un nom d’individu et sa
position dans le fichier.

4.6.4 LES FLUX TEXTE


4.6.4.1 Introduction
Avec les classes DataInputStream et DataOutputStream vous pouvez lire ou écrire sur un flux binaire des
informations de n’importe quel type primitif, en particulier les caractères ou les chaînes. Cependant, dans ce cas, les
caractères sont représentés en mémoire sous forme de deux octets (codage Unicode), ils sont véhiculés sous cette forme
(sans aucune transformation) sur le flux.
Or dans tous les environnements on est habitués à manipuler des fichiers dits de type texte. Ceux-ci peuvent être
créés ou consultés avec un éditeur de texte ou un traitement de texte employant le mode texte. Ils peuvent également être
listés par une commande de l’environnement, telle que "type" depuis une fenêtre DOS sur PC, "more" ou "pr" sous UNIX
(ou Linux). Dans les fichiers texte, chaque caractère est codé sur un seul octet (code ASCII) et suivant un code dépendant
plus ou moins de l’environnement. Généralement on retrouvera des caractères de fin de ligne : caractère de code
hexadécimal 10, ou LF (Line Feed) sous Unix, et de la suite des deux caractères de code hexadécimal 13 (CR Carriage
Return) et 10 (LF) dans les environnements PC.
♦ Java dispose de deux familles de classes, dérivées des classes abstraites Printer et Reader, permettant de manipuler des
flux texte. Les caractères manipulés subiront une transformation à savoir :
- pour un flux de sortie : conversion de deux octets représentant un caractère Unicode en un octet local de ce caractère
dans l’implémentation.
- pour un flux en entrée : une conversion d’un octet représentant un caractère dans le code local en deux octets
représentant le code Unicode de ce caractère.
- évidemment, les fin de ligne seront transformées en accord avec leur représentation locale.

4.6.4.2 Création d’un fichier texte :


Les méthodes de la classe FileWriter permettent d’écrire des caractères, des tableaux de caractères ou des chaînes.
FileWriter f = new FileWriter ("nomfich.dat"); // associe un fichier à l’objet f.
Si on souhaite disposer de plus de possibilités de formatage, on peut recourir à la classe PrintWriter qui dispose d’un
constructeur recevant en argument un objet de la classe FileWriter.
PrintWriter sortief = new PrintWriter (f); // crée un objet sortie qui, par f, est associé à "nomfich.txt"
♦ La classe PrintWriter dispose également des méthodes Print et Println.
♦ Exemple : un petit programme qui lit des entiers au clavier et qui , pour chacun d’eux écrit une ligne d’un fichier texte
contenant le nombre et son carré, sous la forme suivante :
11 a pour carré 121
import java.io.* ;
public class Crftxt1
{ public static void main (String args[]) throws IOException
{
String nomfich ;
int n ;
System.out.print ("Donnez le nom du fichier a creer : ") ;
nomfich = Clavier.lireString() ;
PrintWriter sortie = new PrintWriter (new FileWriter (nomfich)) ;
do
{ System.out.print ("donnez un entier : ") ;
n = Clavier.lireInt() ;
if (n != 0)
{ sortie.println (n + " a pour carre " + n*n) ;
}
}
while (n != 0) ;
sortie.close () ;
System.out.println ("*** fin creation fichier ***");
}
}

Prof. Marcellin NKENLIFACK, mars 2013 49


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.6.4.3 Lecture d’un fichier texte :
♦♦ On peut accéder aux lignes du fichier (sans rechercher à interpréter le contenu).
On utilisera la classe FileReader, couplée avec la classe BufferedReader qui dispose de la méthode readLine.
BufferedReader entree = new BufferedReader( new FileReader (“nomfich.txt”));
Voici le code :
import java.io.* ;
public class Lecftxt1
{ public static void main (String args[]) throws IOException
{
String nomfich ;
String ligne ;
int n ;
System.out.print ("Donnez le nom du fichier a lister : ") ;
nomfich = Clavier.lireString() ;
BufferedReader entree = new BufferedReader (new FileReader (nomfich)) ;

do
{ ligne = entree.readLine() ;
if (ligne != null) System.out.println (ligne) ;
}
while (ligne != null) ;
entree.close () ;
System.out.println ("*** fin liste fichier ***");
}
}

♦♦ On peut accéder aux différentes informations présentes dans une ligne


Nous savons que Java ne dispose pas de fonctionnalités de lecture formatée analogues à celles d’écriture formatée que
procure la classe PrintWriter
En revanche il dispose d’une classe StringTokenizer permettant de découper une chaîne en différent « tokens » (sous-
chaînes), en se fondant sur la présence de caractères séparateurs qu’on choisit librement. Par ailleurs, on pourra appliquer à
ces différents « tokens », les possibilités de conversion d’une chaîne en un type primitif ce qui permettra d’obtenir les
valeurs voulues.
♦ Exemple de programme :
Supposons que nous disposons d’un fichier texte nommé "reel.txt", contenant des nombres flottants répartis
aléatoirement c’est à dire chaque ligne peut en comporter zéro un ou plusieurs séparés les uns des autres par au moins un
espace comme dans cet exemple :
12 4.2 1.5e-3
4.5 78.4 1.25e2 4.33 -3.5
-2
-1 6.2 8.97
-3e-5
Nous allons réaliser un programme qui effectue l’affichage à l’écran de ces différents nombres et qui en calcule la somme.
Nous construisons à partir de chaque ligne lue (ici ligneLue) un objet de type StringTokenizer :
ème
StringTokenize tok = new StringTokenize (ligneLue, “ “); // 2 argument = différents séparateurs utilisés (ici espace)
Ensuite nous avons recours aux méthodes suivantes de StringTokenize :
- countToken, qui compte le nombre de tokens d’un objet type.
- nextToken, qui fournit le token suivant s’il existe.

import java.io.* ;
import java.util.* ; // pour StringTokenizer
public class Lectxt3
{ public static void main (String args[]) throws IOException
{ String nomfich ;
double x, som = 0. ;
System.out.print ("donnez le nom du fichier a lister : ") ;
nomfich = Clavier.lireString() ;
BufferedReader entree = new BufferedReader (new FileReader (nomfich)) ;
System.out.println ("Flottants contenus dans le fichier " + nomfich + " :") ;
while (true)
{ String ligneLue = entree.readLine() ;
if (ligneLue == null) break ;
StringTokenizer tok = new StringTokenizer (ligneLue, " ") ; // espace separateur
int nv = tok.countTokens() ;
for (int i=0 ; i<nv ; i++)
{ x = Double.parseDouble (tok.nextToken()) ;
som += x ;
System.out.println (x + " ") ;
}

Prof. Marcellin NKENLIFACK, mars 2013 50


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
}
entree.close () ;
System.out.println ("somme des nombres = " + som) ;
System.out.println ("*** fin liste fichier ***");
}
}

Exercice 9 :
Ecrire un programme qui lit le fichier texte créé plus haut (contenant les nombres et leurs carrés) et en extrait les différents
nombres et leurs carrés.

Remarque :
L’objet in est un objet constant appartenant à la classe InputStream. On peut connecter un flux texte au clavier en
procédant ainsi :
InputStreamReader entree = new InputStreamReader (System.in);
On pourra lire des lignes de texte en procédant ainsi :
BufferedReader entree = new BufferedReader (lecteur);
C’est d’ailleurs ainsi que nous procédons dans les classes de lecture au Clavier.
Exercice 10 :
1-) Ecrire un programme généralisé qui crée un fichier LICGI de 100 étudiants ayant les propriétés :
« nom : string[18] ; classe : string[4] ; note1 : 0..20 ; note2 : 0..20 ; moy : real ; reussi : boolean ; classement : int ; »
Le nom sera une chaîne de caractères construite de façon aléatoire et de longueur [5..18]. La classe aura aléatoirement la
valeur : GI1, GI2 , GI3. Les notes des valeurs aléatoires [0..20], la moyenne initialisée à -l et reussi initialisé à False.
N.B : On pourra enregistrer chaque étudiant dans un fichier texte sur une ligne.

2-) Ecrire le programme qui calcule la moyenne pour chaque étudiant, et met le champ réussi à True si la moyenne est ≥10.
3-) Ecrire le programme qui affiche les étudiants de DUTGI ayant réussi. On vérifiera la moyenne.
3-) Ecrire le programme qui effectue le classement des étudiants de DUTIG crées précédemment.
4-) Ecrire le programme qui crée un fichier trié alphabétiquement pour chaque classe (TRI par nom, prenom et classe), en utilisant le
fichier précédent.

4.6.5 GESTION GLOBALE DES FICHIERS PHYSIQUES (NIVEAU SYSTÈME) : CLASSE « FILE »
Elle permet des opérations concernant le fichier dans sa globalité (sur le disque), et non plus chacune des
informations qu’il contient. On pourra créer, supprimer, ou renommer un fichier ou un répertoire, tester l’existence d’un
fichier ou d’un répertoire, obtenir des informations relatives aux protections ou aux dates de modification, lister les noms
de fichiers d’un répertoire …
Exercice 11 :
1-) Ecrire un programme qui recherche tous les fichiers temporaires sur le disque et affiche les statistiques par type (*.bak, *.tmp,
*.log, *.swp, etc.) et par catégorie (nombre, taille, etc.)
2-) Ecrire le programme qui les efface après confirmation de l’utilisateur. L’accent sera mis sur la qualité et la convivialité des
interfaces.

4.7 LES PACKAGES SWING


Le problème qui se pose dans la conception des interfaces graphiques (en Java - portable) est que les systèmes de
gestion d'interface utilisateur (GUI - Graphical User Interface systems) sont très différents les uns des autres :
- X Window + motif
- X Window + gtk
- MacOS X
- MS Windows
- Etc.

Deux stratégies possibles :


• Faire une utilisation maximale du système graphique cible
• Faire une utilisation minimale du système graphique cible

Dans cette partie, nous donnons une présentation des possibilités de la plateforme JSE qui dispose de packages pour
développer des programmes offrant de belles interfaces graphiques utilisateurs (GUI).
En effet, la “boite à outils” Swing, incluse dans la plateforme Java SE, fournit un ensemble assez riche de composants GUI.
En plus, Swing offre beaucoup plus de fonctionnalités, bien au-delà d’une simple “boite à outils" standard.

Prof. Marcellin NKENLIFACK, mars 2013 51


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.7.1 PRÉSENTATION ET UTILISATION
[wwwSwing06]
Swing s'intègre aux JFC (Java Fundation Class) lancées par Sun en 1997 pour la création d’interfaces graphiques plus
élaborées que AWT et intégré depuis la version 2 de Java (1.2) ).
JFC = Java 2D API + copier-coller inter-applications + Swing + Accessibilité
Swing : offre des composants légers (lightweight) 100% java
- Prennent en charge leur affichage sans passer par des objets « Peers » gérés par le Système
- multiplication des composants plus riches en fonctionnalités (listes arborescentes, grilles….)
- aspect de l’IHM : Motif, Windows, Métal, Mac, ...
- modèle MVC (Model View Controler)

On peut utiliser Swing qui offre un ensemble de composants, pour construire des programmes avec interfaces
graphiques conviviales. Ceux-ci apporteront une grande interactivité à vos applications Java. Swing contient tout ce
qu’on peut attendre d’une “boite à outils”, supports et primitives d’interfaces modernes : table controls, list controls,
tree controls, buttons et labels … / undo support, customizable text package, integrated internationalization and
accessibility support ... / drag and drop, event handling, customizable painting, window management, etc. Bref, une
grande richesse en termes de fonctionnalités graphiques. Nous allons décrire les élements fournis par Swing et JFC.
* Composants GUI Swing
Ceci va des composants simples tels que les cases à cocher et les boutons, aux composants complexes tels
que zones textes, arbres et tables d’opération ou encore explorateurs de fichiers. Des fonctionnalités comme la
lecture de textes dans un format, ou encore la lecture de mots de passe sont intégrées aux champs de saisie. Bien
sûr, on a également la possibilité de créer ses propres composants.
* Java 2D
Pour faciliter l’intégration des données multimedia (figures, images, animations, diverses synthèses ...) à
votre application, vous pouvez utiliser l’API Java 2DTM.
* Support (creation et intégration) des modules d’extension “Look-and-Feel”
Il est possible de metre en oeuvre ses propres look-and-feel, de spécifier ceux disponibles sur votre plateforme
système ou encore d’exploiter ceux (des centaines) disponibles avec Swing (grâce par exemple au module GTK+).
* Echange de données
Ceci est possible grace aux mécanismes de transfert disponibles Via : couper, copier, coller, glisser,
deposer, etc. (cut, copy, paste, and drag and drop). Ces possibilités offertes dans Swing sont essentielles pour
toute application, lorsqu’on veut faire communiquer les applications entre elles, ou les composants au sein
d’une même application.
* Internationalisation
Il est possible pour le développeur de construire une application qui interagit avec le monde entier en
tenant compte de la langue et des conventions culturelles de chacun. Le gestionnaire de mise en forme de
Swing facilite la prise en compte de diverses langues manipulant des milliers de caractères qui pourront être
facilement supportées (incluant : Japonais, Chinois, Coréen, etc.)
* Gestion d’Accessibilité
Ceci prend en compte les technologies de présentation des informations de la façon la plus accessible
(technologies d’assistance: voie, Braille, Clavier assisté dynamiquement ...). Cette API rend disponible cette
technologie.
* Annulation et Rétablissement (undo Framework)
Swing dispose d’une microarchitecture permettant au développeur de fournir des supports pour effectuer
les actions annuler (undo) et rétablir/refaire (redo). L’opération est disponible en standard dans les
composants « text » de Swing. Pour les autres composants, Swing supporte un nombre « illimité » d’actions
pour « annuler » et « rétablir », et il est facile de les adapter à sa propre application. Par exemple, vous pouvez
très bien activer facilement annuler pour l’ajout et et la suppression d’élements dans un objet « table ».
* Support de Déploiement Flexible
Les programmes Java peuvent être déployés comme application ordinaire, ou sur des interfaces Web
(Applets) à l’aide des « Plug-in Java », qui supportent pratiquement tous les navigateurs Internet. Le
programmeur dispose à cet effet de l’outil “Java Web Start”.

4.7.2 QUEL PAQUETAGE SWING UTILISER ?


Swing est robuste, efficace et offre une immense gamme de paquetages. Depuis la version 1.4 du JDK, Swing
offre plus de 17 packages publiques. Nous présentons quelques-uns ci-dessous :
javax.accessibility javax.swing.plaf javax.swing.text.html
javax.swing javax.swing.plaf.basic javax.swing.text.parser
javax.swing.border javax.swing.plaf.metal javax.swing.text.rtf
javax.swing.colorchooser javax.swing.plaf.multi javax.swing.tree

Prof. Marcellin NKENLIFACK, mars 2013 52


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
javax.swing.event javax.swing.table javax.swing.undo
javax.swing.filechooser javax.swing.text

La plupart des programmes utilisent juste une partie de ces paquetages. Généralement un ou les deux ci-après :
• javax.swing
• javax.swing.event (pas toujours requis)

Prof. Marcellin NKENLIFACK, mars 2013 53


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

4.7.3 HIÉRARCHIE DES CLASSES : COMPOSANTS LÉGERS DU PACKAGE JAVA SWING

Figure 11. Hiérarchie des classes du package "java swing"

• La classe JApplet : créer des applications (applets) qu'un navigateur Web peut télécharger sur le Net et exécuter.
• La classe JDialog permet de créer des boites de dialogue.
• La classe JFrame : utilisée pour créer des objets de type cadre ou fenêtre d'encadrement non contenue dans une autre fenêtre.
• La classe JComponent est la classe dont héritent tous les composants graphiques swing qui ne sont pas des fenêtres.
• La classe AbstractButton est la superclasse des objets de type bouton.
• La classe JButton permet de créer et gérer des objets de type bouton. Le package swing permet de créer des boutons plus évolués
qu'avec AWT (avec des images, ronds, etc.).
• La classe JCheckBox permet la gestion des cases à cocher.
• La classe JComboBox permet de gérer des listes déroulantes.
• La classe JLabel sert à créer des étiquettes.
• La classe JList permet de créer et gérer les zones de listes.
• La classe JMenu représente un menu qui peut être inséré sur une barre de menu.
• La classe JMenuBar permet de créer des barres de menu.
• La classe JMenuItem permet de créer les options des menus, les séparateurs et les sous-menus.
• La classe JradioButton : créer des boutons radio pour permettre aux utilisateurs de choisir une seule option parmi plusieurs.
• La classe JTextArea permet de créer des zones de saisie de texte de plusieurs lignes.
• La classe JTextComponent est une classe abstraite dont dérivent les zones de texte.
• La classe JTextField sert à gérer des zones de texte permettant la saisie d'une seule ligne.
• La classe JToggleButton est la superclasse dont héritent JCheckBox et JRadioButton.

Figure 12. Hiérarchie des classes du package swing (suite et fin)

Prof. Marcellin NKENLIFACK, mars 2013 54


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.7.4 STRUCTURE DE L’INTERFACE GRAPHIQUE
• La création de l’interface graphique passe forcément par une instance de la classe Jframe.
• Du point de vue du système d’exploitation, cette fenêtre représente l’application.
• La fenêtre joue le rôle de « conteneur » dans lequel vont être disposés les différents éléments constitutifs
(composants) de l’interface graphique de l’application (boutons, listes déroulantes, zone de saisie…).
Ces éléments sont désignés sous les termes de :
- contrôles (IHM)
- composants (components en JAVA)
- widgets (Xwindow-Motif, ...)

4.7.5 ILLUSTRATION DE SWING SUR DES EXEMPLES

4.7.5.1 Exemple3 d’application (Simple Menu Déroulant → Projet):


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//---------------------------------------------
public class Projet extends JFrame
{
JPanel contentPane;
JMenuBar menuBar1 = new JMenuBar();
JMenu menuFile = new JMenu();
JMenuItem menuFileNouveau = new JMenuItem();
JMenuItem menuFileOuvrir = new JMenuItem();
JMenuItem menuFileEnregistrer = new JMenuItem();
JMenuItem menuFileFermer = new JMenuItem();
JMenuItem menuFileApercu = new JMenuItem();
JMenuItem menuFileImprimer = new JMenuItem();
JMenuItem menuFileExit = new JMenuItem();
JMenu menuEdition = new JMenu();
JMenuItem menuEditionAnnuler = new JMenuItem();
JMenuItem menuEditionRefaire = new JMenuItem();
JMenuItem menuEditionCouper = new JMenuItem();
JMenuItem menuEditionCopier= new JMenuItem();
JMenuItem menuEditionColler = new JMenuItem();
JMenuItem menuEditionSupprimer = new JMenuItem();
JMenuItem menuEditionSelectionner = new JMenuItem();
JMenu menuSysteme = new JMenu();
JMenuItem menuSystemNouvmat = new JMenuItem();
JMenuItem menuSystemNouvvect = new JMenuItem();
JMenuItem menuSystemModifmat = new JMenuItem();
JMenuItem menuSystemModifvect= new JMenuItem();
JMenu menuResol = new JMenu();
JMenu menuResolDirecte = new JMenu();
JMenuItem menuResolDirecteGaussimple = new JMenuItem();
JMenuItem menuResolDirecteGaussPivPar = new JMenuItem();
JMenu menuResolIndirecte = new JMenu();
JMenuItem menuResolIndirecteGauss_sd = new JMenuItem();
JMenuItem menuResolIndirectejacobi = new JMenuItem();
JMenuItem menuResolTriangulaire = new JMenuItem();
JMenu menuOutils = new JMenu();
JMenuItem menuOutilsParametre = new JMenuItem();
JMenuItem menuOutilsConfig = new JMenuItem();
JMenu menuFenetre = new JMenu();
JMenuItem menuFenetreMatrice = new JMenuItem();
JMenuItem menuFenetreVecteur = new JMenuItem();
JMenuItem menuFenetreSolution = new JMenuItem();
JMenu menuHelp = new JMenu();
JMenuItem menuHelpIndex = new JMenuItem();
JMenuItem menuHelpAidesuraide = new JMenuItem();
JMenuItem menuHelpAbout = new JMenuItem();
JToolBar toolBar = new JToolBar();
JLabel statusBar = new JLabel();
BorderLayout borderLayout1 = new BorderLayout();
JMenu menuResolPerform = new JMenu();
JMenuItem menuResolAfficherSolution = new JMenuItem();
JMenuItem menuSystemAffichermatrice = new JMenuItem();
JMenuItem menuSystemAffichervect = new JMenuItem();
JMenuItem menuResolPerformPrecision = new JMenuItem();
JMenuItem menuResolPerformNombreoper = new JMenuItem();
JMenuItem menuResolPerformTempsmis = new JMenuItem();
JMenu menuSystemProprietesmat = new JMenu();
JMenuItem menuSystemericeProprietesmatTriangil = new JMenuItem();
JMenuItem menuSystemericeProprietesmatDeter = new JMenuItem();
JMenuItem menuSystemericeProprietesmatDefpositif = new JMenuItem();
JMenuItem menuSystemericeProprietesmatSymet = new JMenuItem();

Prof. Marcellin NKENLIFACK, mars 2013 55


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
JMenuItem menuSystemericeProprietesmatTriangul = new JMenuItem();
JMenuItem menuResolDirecteGaussPivTot = new JMenuItem();
JMenuItem menuResolIndirecteJordan = new JMenuItem();
//---------------------------------------------
//...Construire le projet (cadre)...
public Projet()
{
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//---------------------------------------------
//..Initialiser le composant...
private void jbInit() throws Exception
{
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
Dimension TailleEcran = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(TailleEcran);
this.setTitle("PREMIER PROJET DE POO en DUT IG2");
statusBar.setText(" ");
menuFile.setText("FichierSysEquation");
menuFileNouveau.setText("Nouveau fichier SysEqua");
menuFileNouveau.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
menuFileNouveau_actionPerformed(e);
}
});
menuFileOuvrir.setText("Ouvrir fichier SysEqua");
menuFileOuvrir.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
menuFileOuvrir_actionPerformed(e);
}
});
menuFileEnregistrer.setText("Enregistrer fichier SysEqua");
menuFileEnregistrer.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
menuFileEnregistrer_actionPerformed(e);
}
});
menuFileFermer.setText("Fermer fichier SysEqua");
menuFileFermer.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
menuFileFermer_actionPerformed(e);
}
});
menuFileApercu.setText("Aperçu avant impression");
menuFileImprimer.setText("Imprimer");
menuFileExit.setText("Quitter");
menuFileExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fileExit_actionPerformed(e);
}
});
menuEdition.setText("Edition");
menuEditionAnnuler.setText("Annuler");
menuEditionRefaire.setText("Répeter");
menuEditionCouper.setText("Couper");
menuEditionCopier.setText("Copier");
menuEditionColler.setText("Coller");
menuEditionSupprimer.setText("Supprimer");
menuEditionSelectionner.setText("Sélectionner tout");
menuSysteme.setText("Systeme");
menuSystemNouvmat.setText("Saisie Matrice");
menuSystemNouvvect.setText("Saisie Vecteur");
menuSystemModifmat.setText("Modifier Matrice");
menuSystemModifvect.setText("Modifier Vecteur");
menuResol.setText("Résolution");
menuResolDirecte.setText("Méthodes Directes");

Prof. Marcellin NKENLIFACK, mars 2013 56


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
menuResolDirecteGaussimple.setText("Gaussimple");
menuResolDirecteGaussPivPar.setText("GaussPivPartiel");
menuResolIndirecte.setText("Méthodes Indirectes");
menuResolIndirecteGauss_sd.setText("Gauss Seidel");
menuResolIndirectejacobi.setText("jacobi");
menuResolTriangulaire.setText("Méthode Triangulaire");
menuOutils.setText("Outils");
menuOutilsParametre.setActionCommand("Paramètre");
menuOutilsParametre.setText("Paramètres");
menuOutilsConfig.setText("Configurations");
menuFenetre.setText("Fenêtres");
menuFenetreMatrice.setText("Fenetre Matrice [A]");
menuFenetreVecteur.setText("Fenetre Vecteur [B]");
menuFenetreSolution.setText("Fenetre Vecteur Sol. [X]");
menuHelp.setText("Aide");
menuHelpIndex.setText("Index de l'aide");
menuHelpAidesuraide.setText("Aide sur l'aide");
menuHelpAbout.setText("A propos");
menuHelpAbout.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
AideApropos_actionPerformed(e);
}
});
contentPane.setPreferredSize(new Dimension(87, 50));
menuResolPerform.setToolTipText("");
menuResolPerform.setActionCommand("Performences");
menuResolPerform.setText("Performences");
menuResolAfficherSolution.setText("Afficher Solutions [X]");
menuSystemAffichermatrice.setText("Afficher matrice");
menuSystemAffichervect.setText("Afficher vecteur");
menuResolPerformPrecision.setText("Precision de calcul");
menuResolPerformNombreoper.setText("Nombre d\'operations");
menuResolPerformTempsmis.setText("Temps mis");
menuSystemProprietesmat.setToolTipText("");
menuSystemProprietesmat.setText("Proprietes Matrice");
menuSystemericeProprietesmatDeter.setText("Calcul Determinant");
menuSystemericeProprietesmatTriangul.setText("Triangulariser");
menuSystemericeProprietesmatSymet.setText("Test Symetrique");
menuSystemericeProprietesmatDefpositif.setText("Test Def positive");
menuResolDirecteGaussPivTot.setText("GaussPivTotal");
menuResolIndirecteJordan.setText("Jordan");
menuFile.add(menuFileNouveau);
menuFile.add(menuFileOuvrir);
menuFile.add(menuFileEnregistrer);
menuFile.add(menuFileFermer);
menuFile.addSeparator();
menuFile.add(menuFileApercu);
menuFile.add(menuFileImprimer);
menuFile.addSeparator();
menuFile.add(menuFileExit);
menuEdition.add(menuEditionAnnuler);
menuEdition.add(menuEditionRefaire);
menuEdition.add(menuEditionCouper);
menuEdition.add(menuEditionCopier);
menuEdition.add(menuEditionColler);
menuEdition.add(menuEditionSupprimer);
menuEdition.addSeparator();
menuEdition.add(menuEditionSelectionner);
menuSysteme.add(menuSystemNouvmat);
menuSysteme.add(menuSystemNouvvect);
menuSysteme.addSeparator();
menuSysteme.add(menuSystemModifmat);
menuSysteme.add(menuSystemModifvect);
menuSysteme.addSeparator();
menuSysteme.add(menuSystemAffichermatrice);
menuSysteme.add(menuSystemAffichervect);
menuSysteme.addSeparator();
menuSysteme.add(menuSystemProprietesmat);
menuResol.add(menuResolTriangulaire);
menuResol.add(menuResolDirecte);
menuResolDirecte.add(menuResolDirecteGaussimple);
menuResolDirecte.add(menuResolDirecteGaussPivPar);
menuResolDirecte.add(menuResolDirecteGaussPivTot);
menuResol.add(menuResolIndirecte);
menuResolIndirecte.add(menuResolIndirecteJordan);
menuResolIndirecte.add(menuResolIndirecteGauss_sd);
menuResolIndirecte.add(menuResolIndirectejacobi);
menuResol.addSeparator();
menuResol.add(menuResolAfficherSolution);
menuResol.addSeparator();
menuResol.add(menuResolPerform);

Prof. Marcellin NKENLIFACK, mars 2013 57


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
menuOutils.add(menuOutilsParametre);
menuOutils.add(menuOutilsConfig);
menuFenetre.add(menuFenetreMatrice);
menuFenetre.add(menuFenetreVecteur);
menuFenetre.add(menuFenetreSolution);
menuHelp.add(menuHelpIndex);
menuHelp.add(menuHelpAidesuraide);
menuHelp.addSeparator();
menuHelp.add(menuHelpAbout);
menuBar1.add(menuFile);
menuBar1.add(menuEdition);
menuBar1.add(menuSysteme);
menuBar1.add(menuResol);
menuBar1.add(menuOutils);
menuBar1.add(menuFenetre);
menuBar1.add(menuHelp);
this.setJMenuBar(menuBar1);
contentPane.add(statusBar, BorderLayout.SOUTH);
contentPane.add(toolBar, BorderLayout.NORTH);
menuResolPerform.add(menuResolPerformNombreoper);
menuResolPerform.add(menuResolPerformTempsmis);
menuResolPerform.add(menuResolPerformPrecision);
menuSystemProprietesmat.add(menuSystemericeProprietesmatDeter);
menuSystemProprietesmat.add(menuSystemericeProprietesmatTriangul);
menuSystemProprietesmat.add(menuSystemericeProprietesmatSymet);
menuSystemProprietesmat.add(menuSystemericeProprietesmatDefpositif);
menuSystemProprietesmat.add(menuSystemericeProprietesmatTriangil);
}
//---------------------------------------------
//...Opération effectuée pour Fichier | Quitter ...
public void fileExit_actionPerformed(ActionEvent e)
{
int reponse = JOptionPane.showConfirmDialog(this, "Voulez vous quitter","fenêtre de
sortie",JOptionPane.YES_NO_OPTION);
if (reponse == 0) System.exit(0);
}
//---------------------------------------------
//...Opération effectuée pour Aide | A propos ...
public void AideApropos_actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(this,"Premier projet de POO en IG2");
}
//---------------------------------------------
//...Remplacé, ainsi nous pouvons sortir quand la fenêtre est fermée...
protected void processWindowEvent(WindowEvent e)
{
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
fileExit_actionPerformed(null);
}
}
//---------------------------------------------
void menuFileNouveau_actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(this,"Vous avez cliqué sur Menu Fichier Nouveau");
}
//---------------------------------------------
void menuFileOuvrir_actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(this,"Vous avez cliqué sur Menu Fichier Ouvrir");
}
//---------------------------------------
void menuFileEnregistrer_actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(this,"Vous avez cliqué sur Menu Fichier Enregistrer");
}
//---------------------------------------
void menuFileFermer_actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(this,"Vous avez cliqué sur Menu Fichier Fermer");
}
//---------------------------------------
public static void main (String args[])
{
Projet monprojet = new Projet();
monprojet.setVisible(true);
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Prof. Marcellin NKENLIFACK, mars 2013 58


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.7.5.2 Voici un exmple d’application illustrant l’utilisation de « Jbutton » de « Swing »
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SwingApplication implements ActionListener


{
private static String labelPrefix = "Nombre de cliques sur le Bouton: ";
private int numClicks = 0;
final JLabel label = new JLabel(labelPrefix + "0 ");

//Specification du type d'environnement graphique :


//null (use the default), "Metal", "System", "Motif", "GTK+"
final static String LOOKANDFEEL = null;

public Component createComponents() {


JButton button = new JButton("Je suis un Bouton a Swing !");
button.setMnemonic(KeyEvent.VK_I);
button.addActionListener(this);
label.setLabelFor(button);
/*
* An easy way to put space between a top-level container
* and its contents is to put the contents in a JPanel
* that has an "empty" border.
*/
JPanel pane = new JPanel(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
pane.setBorder(BorderFactory.createEmptyBorder(
30, //haut
30, //gauche
10, //bas
30) //droite
);

return pane;
}

public void actionPerformed(ActionEvent e) {


numClicks++;
label.setText(labelPrefix + numClicks);
}

private static void initLookAndFeel() {


String lookAndFeel = null;

if (LOOKANDFEEL != null) {
if (LOOKANDFEEL.equals("Metal")) {
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
} else if (LOOKANDFEEL.equals("System")) {
lookAndFeel = UIManager.getSystemLookAndFeelClassName();
} else if (LOOKANDFEEL.equals("Motif")) {
lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
} else if (LOOKANDFEEL.equals("GTK+")) { //new in 1.4.2
lookAndFeel = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
} else {
System.err.println("Unexpected value of LOOKANDFEEL specified: "
+ LOOKANDFEEL);
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
}
try {
UIManager.setLookAndFeel(lookAndFeel);
} catch (ClassNotFoundException e) {
System.err.println("Couldn't find class for specified look and feel:"
+ lookAndFeel);
System.err.println("Did you include the L&F library in the class path?");
System.err.println("Using the default look and feel.");
} catch (UnsupportedLookAndFeelException e) {
System.err.println("Can't use the specified look and feel ("
+ lookAndFeel
+ ") on this platform.");
System.err.println("Using the default look and feel.");
} catch (Exception e) {
System.err.println("Couldn't get specified look and feel ("
+ lookAndFeel
+ "), for some reason.");
System.err.println("Using the default look and feel.");
e.printStackTrace();
}
}
}

Prof. Marcellin NKENLIFACK, mars 2013 59


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Set the look and feel.
initLookAndFeel();

//Make sure we have nice window decorations.


JFrame.setDefaultLookAndFeelDecorated(true);

//Create and set up the window.


JFrame frame = new JFrame("Exemple Application Swing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

SwingApplication app = new SwingApplication();


Component contents = app.createComponents();
frame.getContentPane().add(contents, BorderLayout.CENTER);

//Display the window.


frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {


//--Définition d’un processus de distribution d'événements
//création et mise en route de votre application GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

Figure 13. Ecran : utilisation des classes SWING Button

4.7.5.3 Voici un exemple d’application illustrant l’utilisation de JEditor de Swing.


Programme affichant (chargement) la page d’accueil du site de l’IUTFV de Bandjoun.
import java.net.URL;
import javax.swing.*;
import javax.swing.event.*;
public class JEditorPane1
{
public static void main(String[] args)
{
final JEditorPane editeur;
JPanel pannel = new JPanel();

try
{
editeur = new JEditorPane(new URL("http://www.iutfv-bandjoun.info"));
editeur.setEditable(false);
editeur.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
URL url = e.getURL();
if (url == null)
return;
try {
editeur.setPage(e.getURL());
} catch (Exception ex) {

Prof. Marcellin NKENLIFACK, mars 2013 60


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
ex.printStackTrace();
}
}
}
});
pannel.add(editeur);
} catch (Exception e1) {
e1.printStackTrace();
}
JFrame f = new JFrame("Test Affichage Page ACCUEIL IUT FOTSO VICTOR");
f.setSize(500, 300);
f.getContentPane().add(pannel);
f.setVisible(true);
}
}

Figure 14. Ecran : utilisation des classes SWING et JEditor

4.8 LE DEVELOPPEMENT D'INTERFACES GRAPHIQUES AVEC SWT


4.8.1 PRÉSENTATION
C’est vrai que Swing et AWT ne sont plus vraiment en concurrence. Par contre, SWT (Standard Widget ToolKit)
(développé initialement par IBM – Eclipse) s’impose. Ses caractéristiques initiales sont :
- approche similaire à AWT,
- beaucoup plus ambitieux, nombreux composants, modèle MVC (JFace)
- Windows, Xwindows, Motif, GTK, Mac OS, etc.
SWT est écrit en Java et utilise la technologie JNI pour appeler les composants natifs. SWT utilise autant que
possible les composants natifs du système lorsque ceux-ci sont présentés, sinon ils sont reécrit en pur Java. Les données de
chaque composant sont aussi stockées autant que possible dans le composant natif, limitant ainsi les données stockées dans
les objets Java correspondants. SWT ofrre une grande rapidité d'exécution, des ressources machines moins importantes lors
de l'exécution et un rendu parfait des composants graphiques selon le système utilisé, puisqu'il utilise des composants
natifs. La dépendance vis à vis du système graphique de l'environnement d'exécution n’influence pas le fait que l'API de
SWT reste la même quelque soit la plate-forme utilisée.
SWT est livrée avec 2 parties : une bibliothèque dépendante du système d'exploitation et un fichier .jar lui aussi dépendant
du système. Toutes les fonctionnalités de SWT ne sont implémentées que sur les systèmes où elles sont supportées (par ex.,
les ActiveX ne sont utilisables que sur le portage de SWT sur les systèmes Windows).

Malheureusment, le fait que SWT n'utilise pas de purs objets java, il n'est pas possible de compter sur le « ramasse
miettes » pour libérer la mémoire des composants créés manuellement. Pour libérer cette mémoire, il est nécessaire
d'utiliser la méthode dispose() pour les composants instanciés lorsque ceux ci ne sont plus utiles.
Il faut toutefois rester vigilant lors de l'utilisation de certains objets qui ne sont pas des contrôles, tels que les objets de type
Font ou Color, qu'il convient de libérer explicitement sous peine de « fuites de mémoire ».
N’oubliez pas qu’il faudrait éviter d’utiliser un objet dont la méthode dispose() a été appelée. Ceci entrainerait un résultat
imprévisible !

Prof. Marcellin NKENLIFACK, mars 2013 61


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
SWT est donc une « API » qui éssaie de trouver le compromis entre la portabilité (Write Once Run Anywhere) et les
performances.

SWT facilite le développement d'une interface graphique à l’aide de trois concepts :


• Composants ou contrôles (widgets),
• Système de mise en page et de présentation des composants,
• Modèle des gestions des événements.

Voici la structure (étapes clés) d'une application graphique utilisant l’API SWT :
• création d'un objet de type Display qui assure le dialogue avec le système sous jacent,
• création d'un objet de type Shell qui est la fenêtre de l'application,
• création des composants et leur ajout dans le Shell,
• enregistrements des Listeners pour le traitement des événements,
• exécution de la boucle de gestion des événements jusqu'à la fin de l'application,
• libération des ressources de l'objet Display.

4.8.2 LISTE DES PACKAGES DE SWT DE BASE


Package Rôle
org.eclipse.swt Package de base qui contient la définition de constantes et d'exceptions
org.eclipse.swt.accessibility
org.eclipse.swt.custom Contient des composants particuliers
org.eclipse.swt.dnd Contient les éléments pour le support du « cliqué / glissé »
org.eclipse.swt.events Contient les éléments pour la gestion des événements
org.eclipse.swt.graphics Contient les éléments pour l'utilisation des éléments graphiques (couleur, polices, curseur, contexte graphique, ...)
org.eclipse.swt.layout Contient les éléments pour la gestion de la présentation
org.eclipse.swt.ole.win32 Contient les éléments pour le support de OLE 32 sous Windows
org.eclipse.swt.printing Contient les éléments pour le support des impressions
org.eclipse.swt.program
org.eclipse.swt.widgets Contient les différents composants

Tableau 3. LISTE DES PACKAGES DE SWT

4.8.3 LE PROGRAMME « HELLOWORLD » AVEC SWT


import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;

public class TestSWT1


{
public static void centrerSurEcran(Display display, Shell shell)
{
Rectangle rect = display.getClientArea();
Point size = shell.getSize();
int x = (rect.width - size.x) / 2;
int y = (rect.height - size.y) / 2;
shell.setLocation(new Point(x, y));
}

public static void main(String[] args)


{
Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(340, 100);
centrerSurEcran(display, shell);

Label label = new Label(shell, SWT.CENTER);


label.setText("Bonjour!");
label.pack();

shell.open();

while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();

display.dispose();
}
}

Prof. Marcellin NKENLIFACK, mars 2013 62


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

NB : Pour exécuter cet exemple sous windows, il faut que le fichier « swt.jar » correspondant à la plate-forme Windows soit inclus dans
le classpath et que l'application puisse accéder à la bibliothèque swt-win32-2135.dll

4.8.4 QUELQUES COMPOSANTS


On peut les regrouper en deux grandes familles :
- les contrôles (composants graphiques) : Ils héritent tous de la classe abstraite Control.
- les conteneurs qui permettent de grouper des contrôles. Ils héritent tous de la classe abstraite Composite.
Une application SWT obéit à une hiérarchie de composants dont la racine est un objet de type Shell.
La classe SWT
Elle définit des constantes concernant les styles. Les styles sont des comportements ou des caractéristiques
définissant l'apparence du composant. Ceux-ci sont directement fournis dans le constructeur d'une classe encapsulant un
composant.
L'objet Display
Une application SWT doit absolument instancier un objet de type Display, qui assurera le dialogue entre
l'application et le système graphique du système d'exploitation utilisé.
Display display = new Display();
- la méthode readAndDispatch() lit les événements dans la pile du système graphique natif pour les diffuser à
l'application. Elle renvoie true s’il y a encore des traitements a effectuer sinon elle renvoie false.
- La méthode sleep() met en attente le thread d'écoute des événements jusqu'à l'arrivée d'un nouvel événement.
L'objet Shell
Cet objet représente une fenêtre gérée par le système graphique du système d'exploitation courant. Un objet de type
Shell pourra être associé à un objet de type Display pour obtenir une fenêtre principale de l’application, ou être associé à un
autre objet de type Shell pour obtenir une fenêtre secondaire.
Plusieurs styles peuvent être associés à la classe Shell : BORDER, H_SCROLL, V_SCROLL, CLOSE, MIN, MAX,
RESIZE, TITLE, SHELL_TRIM, DIALOG_TRIM
La classe Control
Trois styles y sont définis : BORDER, LEFT_TO_RIGHT et RIGHT_TO_LEFT
Le seul constructeur de la classe Control nécessite aussi de préciser le composant père sous la forme d'un objet de type
Composite. L'association avec le composant père est obligatoire pour tous les composants lors de leur création.
Cette classe possède plusieurs méthodes pour enregistrer des listeners pour certains événements. Ces événements sont :
FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, MouseEnter, MouseExit, MouseHover,
MouseUp, MouseMove, Move, Paint, Resize.
Elle possède aussi plusieurs méthodes dont les principales sont :
Nom Rôle
boolean forceFocus() Force le focus au composant pour lui permettre de recevoir les événements clavier
Display getDisplay() Renvoie l'objet Display associé au composant
Shell getShell() Renvoie l'objet Shell associé au composant
void pack() Recalcule la taille préférée du composant
void SetEnabled() Permet de rendre actif le composant
void SetFocus() Donne le focus au composant pour lui permettre de recevoir les événements clavier
void setSize() Permet de modifier la taille du composant
void setVisible() Permet de rendre visible ou non le composant

Tableau 4. Principales méthodes de la classe Control

Les différents contrôles :


Les contrôles de base
Button, Label, Text
Les contrôles de type liste
Combo, List
Les contrôles pour les menus
Menu, MenuItem
Les contrôles de sélection ou d'affichage d'une valeur
ProgressBar, Scale, Slider
Les contrôles de type « onglets »
TabFolder, TabItem
Les contrôles de type « tableau »
Table, TableColumn, TableItem

Prof. Marcellin NKENLIFACK, mars 2013 63


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
Les contrôles de type « arbre »
Tree, TreeItem, ScrollBar
Les contrôles pour le graphisme
Canvas, GC, Color, Font, Image
Les différents conteneurs
Les conteneurs de base
Composite, Group
Les contrôles de type « barre d'outils »
ToolBar, ToolItem, Les classes CoolBar et Cooltem
La gestion des erreurs
Le positionnement des contrôles
Le positionnement absolu,
Le positionnement relatif avec les LayoutManager
FillLayout, RowLayout, GridLayout, FormLayout
La gestion des événements (interfaces)
KeyListener, MouseListener, MouseMoveListener, MouseTrackListener, ModifyListener, VerifyText(),
FocusListener, TraverseListener, PaintListener
Les boîtes de dialogue
Les boîtes de dialogues prédéfinies
MessageBox, ColorDialog, FontDialog, FileDialog, DirectoryDialog, PrintDialog
Les boites de dialogues personnalisées

4.9 TECHNIQUES DE THREAD


4.9.1 GENERALITES
Un thread est un processus "léger". Plusieurs threads partagent le même espace d'adressage, les mêmes variables
d'instances.
Même si vous n'en êtes pas toujours conscient, les threads font partie de tout programme Java; quand vous
exécutez une application Java, la machine virtuelle Java (Java Virtual Machine ou JVM) exécute sa méthode main() dans
son propre thread. Les applets s'exécutent aussi dans leurs propres threads. Cela montre combien le concept des threads est
intégré à Java. Pour qu'un programmeur Java puisse donner la pleine mesure de ses capacités, il lui faut connaître le
fonctionnement des threads et la façon de les utiliser dans le développement des programmes Java.
A quoi servent les threads ?
Avant tout, un thread est une seule et même entité de travail qui peut s'exécuter de façon indépendante à l'intérieur
d'une application. Une application multithread prend en charge l'exécution simultanée de plusieurs threads. Pour
comprendre l'utilité des threads, prenons un exemple montrant comment leur présence peut augmenter considérablement la
productivité d'une application, alors que leur absence est pénalisante. Considérons le cas où vous voulez utiliser un
navigateur Web pour, simultanément, télécharger un fichier d'un site et accéder à un autre site. Si le navigateur ne peut pas
exécuter ces deux tâches simultanément, il vous faut attendre la fin du téléchargement avant de commencer l'autre action; si
le fichier est volumineux, imaginez la perte de temps qui en découle. Il est certainement plus productif de consacrer le
temps de téléchargement à d'autres tâches. C'est pourquoi la plupart des navigateurs Web sont multithreads.

Evolution ?
Le concept de threads n'est pas vraiment récent. Avant Java, les threads n'étaient pas aussi connus que maintenant
parce qu'aucune « API » n'existait pour standardiser leur utilisation sur des plates-formes différentes. Java est fourni avec
une API de threads prise en charge par chaque JVM exécutée sur chaque plate-forme.

4.9.2 CREATION D'UN THREAD


Il convient maintenant de montrer comment un thread est créé dans Java. Le paquet java.lang définit une classe
Thread réservée à la création des threads. Ainsi, pour créer un thread dans votre application, vous pouvez mettre une
déclaration semblable à celle-ci:
Thread monPremierThread = new Thread();
Cette déclaration crée une occurrence de Thread appelée monPremierThread; cependant, elle ne sert pas à grand chose, car
vous n'avez aucun moyen de dire à monPremierThread ce qu'il doit faire. La classe Thread définit des méthodes qui
précisent le comportement général de tous les threads; elle ne dispose d'aucune méthode ni propriété pouvant exécuter les
tâches particulières que le thread doit faire.
La classe Thread serait donc inutile? Non, cela signifie simplement que nous ne savons pas encore en faire bon usage.
Il y a deux façons de créer des threads: la première met en jeu une sous-classe de la classe Thread; la deuxième met en jeu
une implémentation de l'interface Runnable. Nous allons les étudier toutes les deux :

Prof. Marcellin NKENLIFACK, mars 2013 64


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.9.2.1 Sous-classes de la classe Thread
Dans la section précédente, nous avons dit qu'un objet de type Thread ne pouvait pas être programmé directement
par l'utilisateur pour exécuter une tâche particulière. Dans ce cas, comment programmer les threads? La réponse réside dans
une des méthodes définies par la classe Thread :
public void run() { }
Dans cette méthode se trouve la principale logique d'exécution des threads; la méthode run() est au thread ce que la
méthode main() est à l'application. Tout comme main() est le point de départ de l'exécution d'une application, run() est la
première instruction qui s'exécute au démarrage d'un thread.
Par elle-même, la méthode run() par défaut ne fait rien; par conséquent, créer directement une occurrence de la classe
Thread donne un thread qui dispose d'une méthode run() inutile. La solution évidente consiste à créer une sous-classe de la
classe Thread et à redéfinir sa méthode run(). Voici comment faire :
public class monThreadUtile extends Thread
{
//constructeurs
public void run()
{
//faire quelque chose d'utile
}
}
A partir de maintenant, quand vous créerez une occurrence de monThreadUtile , l'objet tirera sa fonctionnallité de la
méthode run() redéfinie.
Enfin, pour démarrer le thread, il suffit d'appeler sa méthode start() de la façon suivante:
monThreadUtile t = new monThreadUtile ();
t.start();

Exemple: Implémentation d'un thread de comptage :


threadComptage est une classe Thread simple qui effectue un comptage entre deux nombres. Bien qu'il s'agisse d'un
exemple simplifié, il montre néanmoins comment créer des threads séparés et comment les faire coexister dans le même
environnement. threadComptage est illustré ci-dessous:
public class threadComptage extends Thread {
private int start;
private int finish;
public threadComptage (int from, int to) {
this.start = from;
this.finish = to;
}
public void run() {
System.out.println(this.getName()+ " début d'exécution...");
for (int i = start; i <= finish; i++) {
System.out.print (i + " ");
} //for
System.out.println(this.getName() + " fin d'exécution.");
} //run
}

Le constructeur de threadComptage prend deux paramètres de type int pour initialiser ses propriétés start et finish . La
méthode run() identifie d'abord l'objet thread en cours en affichant son nom à l'écran. Ensuite, elle utilise une boucle for
pour effectuer le comptage entre start et finish, et elle affiche chaque nombre à l'écran. Avant de terminer, elle affiche un
message de fin d'exécution.
threadComptage peut être utilisé dans une application de la façon suivante:
public class threadTester
{
static public void main(String[] args)
{
threadComptage thread1 = new threadComptage (1, 10);
threadComptage thread2 = new threadComptage (20, 30);
thread1.start();
thread2.start();
}
}

La méthode main() ci-dessus crée deux objets threadComptage : thread1 compte de 1 à 10 ; thread2 compte de 20 à 30 .
Elle démarre ensuite les deux threads en appelant leurs méthodes start() . Quand cette méthode main() est exécutée dans
une application, le résultat ressemble à ceci:
Thread-1 début d'exécution...
Thread-2 début d'exécution...
20 21 22 23 24 25 26 27 28 29 30 Thread-2 fin d'exécution.

Prof. Marcellin NKENLIFACK, mars 2013 65


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
1 2 3 4 5 6 7 8 9 10 Thread-1 fin d'exécution.
En premier lieu, remarquez que le résultat ne garde pas aux threads les noms thread1 et thread2, comme vous pourriez vous
y attendre. Sauf si vous attribuez un nom spécifique à un thread, Java lui donne automatiquement un nom sous la forme
Thread-n , où n est un numéro unique. Dans ce cas, le premier thread démarré reçoit le nom Thread-1 et le deuxième le
nom Thread-2 . Si vous préférez donner des noms plus descriptifs, utilisez la méthode setName(String) de la classe Thread.
Ensuite, remarquez que Thread-1 a démarré en premier mais se termine en dernier. Pourquoi? La réponse est que, dans
Java, les threads ne s'exécutent pas toujours dans le même ordre. En fait, à chaque exécution de threadTester , vous pouvez
obtenir un résultat différent. Voici un autre résultat généré par threadTester :
Thread-1 début d'exécution...
1 2 3 4 5 6 7 8 Thread-2 début d'exécution...
20 21 22 23 9 10 Thread-1 fin d'exécution.
24 25 26 27 28 29 30 Thread-2 fin d'exécution.
Dans ce résultat, remarquez que Thread-2 a démarré avant même la fin de Thread-1. L'ordre d'exécution des threads est
contrôlé par le programmateur de threads de Java et non pas par le programmeur.

4.9.2.2 Implémentation de l'interface Runnable


Comme le montre la section précédente, créer des sous-classes de la classe Thread est une façon de créer des
threads. Cette méthode convient si vous concevez une nouvelle classe dont les objets doivent s'exécuter dans des threads
séparés. Mais comment faire pour que des objets d'une classe existant déjà s'exécutent dans leurs propres threads? Il suffit
d'implémenter l'interface Runnable.
Cette interface sert à ajouter un support de thread aux classes qui n'héritent pas de la classe Thread. Elle ne déclare qu'une
méthode :
public void run()
Ainsi, pour que des objets d'une classe existante s'exécutent dans leurs propres threads, procédez comme suit:
- Demandez à la classe d'implémenter l'interface Runnable
- Implémentez la méthode run() pour cette classe

Pour créer threadComptage2 , utilisez l'interface Runnable au lieu de créer une sous-classe de la classe Thread; il suffit de
modifier sa déclaration selon l'exemple ci-dessous:
public class threadComptage2 implements Runnable {
//la suite n'est pas modifiée
}

Bien que l'implémentation de la classe threadComptage2 n'ait besoin d'aucune modification pour implémenter Runnable, la
façon de créer ses objets doit être modifiée. Au lieu d'instancier threadComptage, comme nous l'avons fait auparavant, il
faut créer un objet Runnable à partir de threadComptage2 et le transmettre à un des constructeurs de threads. Voici
comment créer l'objet thread1 selon cette méthode:
Runnable rThread = new threadComptage2(1, 10);
Thread thread1 = new Thread(rThread);

Etudions maintenant pourquoi nous avons travaillé ainsi. threadComptage est une sous-classe de la classe Thread; elle
hérite par conséquent du comportement d'un thread Java. Cela signifie que vous disposez dans un objet de threadComptage
de toutes les fonctionnalités prises en charge par la classe Thread, comme appeler start(). Cependant, threadComptage2
n'hérite en rien de la classe Thread et ne prend donc pas en charge le comportement de la classe Thread. threadComptage2
n'a fait que définir la méthode run(), qui peut être appelée quand un objet threadComptage2 est exécuté dans un thread.

4.9.3 L'API DES THREADS

4.9.3.1 La classe Thread définit les constructeurs suivants:


public Thread ( )
public Thread (Runnable cible)
public Thread (Runnable cible, String nom)
public Thread (String nom)
public Thread (ThreadGroup groupe, Runnable cible)
public Thread (ThreadGroup groupe, String nom)
public Thread (ThreadGroup groupe, Runnable cible, String nom)
Pour construire des objets Thread, il n'y a que trois types de paramètres:
- Un objet Runnable dont la méthode run() s'exécute à l'intérieur du thread
- Un objet ThreadGroup auquel attribuer le thread
- Un objet String pour identifier le thread

Prof. Marcellin NKENLIFACK, mars 2013 66


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
La classe ThreadGroup sert principalement à organiser des threads ayant un lien entre eux en groupes. Par exemple, un
navigateur Web peut définir un ThreadGroup pour tous les threads d'une applet.

Les méthodes start() et stop()


public void start()
public final void stop()
public void destroy()
Pour démarrer un thread, appelez simplement sa méthode start(). Si vous essayez d'appeler plusieurs fois la méthode start()
d'un thread, une exception se produit. Pour l'arrêter, utilisez stop() ou destroy(). Stop() termine le thread et lui envoie une
exception ThreadDeath. Cette mesure s'avère nécessaire car, en cas d'interruption, le thread interrompu pourrait entraîner
des résultats imprévisibles; par exemple, il pourrait être en cours de modification d'un fichier ou de ressources système.
Pour éviter de tels problèmes, l'exception ThreadDeath permet d'effectuer le nettoyage nécessaire avant de finir le thread.
Soyez attentif quand vous recevez l'exception ThreadDeath. Quand stop() envoie une exception ThreadDeath et quand
vous la recevez, n'oubliez pas de la renvoyer dans le bloc catch. Si non, le thread ne s'arrête jamais!
Une autre façon consiste à appeler sa méthode destroy(). Cette méthode n'envoie pas d'exception ThreadDeath.

Les méthodes suspend() et resume()


Les méthodes suivantes servent à interrompre et à reprendre un thread :
public final void suspend()
public final void resume()
Appeler suspend() sur un thread interrompt son exécution temporairement. Appeler resume() reprend l'exécution (sauf si un
autre événement a provoqué l'arrêt complet du thread).

La méthode sleep()
Pour mettre un thread au repos, utilisez une des deux méthodes suivantes :
public static void sleep(long milliseconde)
public static void sleep(long milliseconde, int nanoseconde)
Par exemple, pour qu'un thread s'arrête pendant une seconde, appelez sleep(1000) sur le thread.

La méthode yield()
Dans certains cas, de nombreux threads sont en attente de la fin de l'exécution du thread en cours avant de pouvoir
s'exécuter. Pour que le programmateur de threads bascule l'exécution sur les autres threads, appelez la méthode yield() sur
le thread en cours. Pour que yield() fonctionne, il doit y avoir au moins un thread de priorité égale ou supérieure au thread
actuel.

La méthode join()
public final void join()
public final void join(long millisecond)

Pour qu'un deuxième thread attende la fin d'exécution d'un premier thread, appelez la méthode join() sur le premier thread.
Vous pouvez préciser un délai à l'aide d'un paramètre de temps donné en millisecondes. join() attend jusqu'à la fin du délai
ou jusqu'à la fin de l'exécution du premier thread. Pour savoir si un thread s'est terminé, join() utilise la méthode isAlive().
Si isAlive() renvoie true, join() n'est pas renvoyée et continue à attendre que le premier thread se termine. Si isAlive()
renvoie false, join() est renvoyée et le deuxième thread peut s'exécuter.

4.9.3.2 Le cycle de vie d'un thread


Du début à la fin, un thread passe par plusieurs états. Quand vous créez un objet thread, il prend l'état « NEW ».
Quand vous appelez la méthode start() du thread, il prend l'état « Runnable ». N'oubliez pas qu'un thread ne démarre pas
toujours immédiatement après l'appel de sa méthode start(), comme nous l'avons vu dans l'application threadTester. De
l'état Runnable, le thread peut passer à l'état « Not Runnable » ou « Dead ». Appeler sleep(), suspend() ou wait() fait
passer un thread à l'état Not Runnable, alors qu'appeler destroy() ou stop() le fait passer à l'état Dead (un thread passe
également à l'état Dead quand sa méthode run() se termine). Un thread peut repasser à l'état Runnable si vous appelez sa
méthode resume() ou à la fin de la méthode sleep(); mais un thread Dead ne peut jamais revivre. D'autres conditions
affectent le cycle de vie d'un thread; par exemple, un thread à l'état Runnable qui doit attendre la fin d'une
opération particulière avant de s'exécuter prend l'état Not Runnable.

4.9.4 PROTECTION DE VOTRE CODE PAR RAPPORT AUX THREADS


Dans cette section, nous allons examiner pourquoi il est important de protéger certaines parties du code contre une
exécution simultanée par plusieurs threads et comment y parvenir. A la fin de cette section, nous parlerons des moniteurs
Java et de leur rôle dans les programmes multithreads.

Prof. Marcellin NKENLIFACK, mars 2013 67


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.9.4.1 Le mot clé synchronized
Dans certains cas, il est nécessaire qu'une méthode ou un bloc de code ne soit exécutée que par un thread à la fois.
Le mot clé synchronized est utilisé dans ce but. Avant de voir son utilisation, regardons dans quel cas s'en servir.
Pour mieux comprendre quand utiliser le mot clé synchronized, considérons le code suivant :
public class Swapper
{
int from;
int to;
public void swap()
{
int temp = from;
from = to;
to = temp;
}
}

Cette classe déclare une méthode swap() qui intervertit les valeurs de ses deux propriétés, from et to. La méthode prend la
propriété from, la stocke dans une variable temp, puis stocke la valeur de to dans from et la valeur de temp dans to.
Envisageons le cas où deux méthodes différentes démarrent leurs propres threads pour exécuter swap() simultanément -
appelons-les thread1 et thread2. Par hypothèse, le thread1exécute la méthode en premier et, au moment de l'exécution, from
a la valeur 5 et to la valeur 6. thread1 exécute la première ligne de code et donne à temp la valeur 5. A la fin de la deuxième
ligne, from reçoit la valeur 6. A ce moment, thread2 démarre l'exécution de la méthode. Pour thread2, from a la valeur 6
(attribuée par thread1) et to a aussi la valeur 6. thread2 exécute la totalité de la méthode et intervertit les valeurs 6 et 6. Une
fois thread2 terminé, thread1 reprend son exécution à la troisième ligne et attribue à to la valeur de temp (maintenant 6). A
la fin de thread1, from et to ont la valeur 6;
L'opération attendue (intervertir 5 et 6) n'a jamais eu lieu!
Pour éviter ce scénario, il suffit d'ajouter le mot clé synchronized à la signature de swap(), comme ceci:
public synchronized void swap()
Maintenant, un seul thread peut exécuter swap() à un moment donné. Dans ce cas, thread1 exécute la totalité de la méthode
et intervertit correctement les valeurs de from et de to. Une fois thread1 terminé, thread2 exécute swap() et intervertit une
nouvelle fois les valeurs.

Comme règle de base: toute méthode qui modifie des propriétés d'objets devrait être déclarée synchronized.

4.9.4.2 Moniteurs
Un environnement qui prend en charge plusieurs threads doit implémenter quelques techniques de contrôle de la
simultanéité. Il en existe plusieurs, comme les sémaphores, les sections critiques et le verrouillage (exemple des
enregistrements de BD). Java implémente un mécanisme de contrôle de la simultanéité appelé moniteur.
Traditionnellement, un moniteur est un objet, qui contrôle quelque chose, comme une procédure. Le travail du moniteur
consiste à vérifier qu'un seul thread à la fois peut exécuter la procédure qu'il contrôle. Dans Java, chaque objet dispose d'un
moniteur associé. Le moniteur s'assure qu'un seul thread à la fois exécute les méthodes synchronized appartenant à l'objet
qu'il contrôle. Le moniteur interdit à tout autre thread d'exécuter la même méthode synchronized tant que le thread en cours
d'exécution n'est pas terminé. Si aucun thread n'exécute la méthode cible synchronized, un thread peut entrer dans le
moniteur (ou verrouiller le moniteur pour lui-même). A partir de ce moment, aucun autre thread ne peut exécuter la
méthode tant que le thread actuel ne quitte pas le moniteur.
Les moniteurs Java ne sont pas des objets réels, car ils n'ont ni méthode ni propriété. Ils sont intégrés à l'implémentation
multithread de Java et restent invisibles au programmeur. Ainsi, notre présentation de moniteurs restera conceptuelle.

4.9.5 EXEMPLE D’UTILISATION DE « THREADS »


Le programme ci-dessous permet de « tracer » les threads. Il sera d’ailleurs un excellent outil pour les projets.
• Deux (2) threads sont directement programmés
mainAWT-EventQueue
AWT-EventQueue qui traite l'« actionPerformed »
• Swing (et AWT) dispose d'un thread spécifique pour traiter les événements :
- l'event dispatcher : AWT-EventQueue
- il exécute les "handlers"/méthodes associées aux événements
- une file permet de mettre en attente ordonnée les événements qui arrivent
- les « events » paint sont traités sur ce même thread
Simplement, un PaintManager permet de regrouper les « events » paint d'un même composant
import java.awt.*;

Prof. Marcellin NKENLIFACK, mars 2013 68


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
import java.awt.event.*;
import javax.swing.*;

class ThreadSwing
{
public static void main(String args[])
{
System.out.println("main -----> thread name = "
+ Thread.currentThread().getName());
JFrame frame = new JFrame("ThreadSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton bouton = new JButton("Afficher");
frame.getContentPane().add(bouton);
bouton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("actionPerformed -----> thread name = "
+ Thread.currentThread().getName());
infoAllThread();
}
});
frame.pack();
frame.setVisible(true);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {}

}
public static void infoThread(Thread thread, String indent) {
if (thread == null)
System.out.println(indent + "Thread null !!");
else
System.out.println(indent + "Thread : name=" + thread.getName() +
" priority=" + thread.getPriority() +
" daemon=" + thread.isDaemon() +
" alive=" + thread.isAlive());
}
public static void infoThreadGroup(ThreadGroup tGroup) {
infoThreadGroup(tGroup, "");
}
public static void infoThreadGroup(ThreadGroup tGroup, String indent)
{
if (tGroup == null)
System.out.println(indent + "GroupThread null !");
else {
System.out.println(indent + "ThreadGroup" +
" name:" + tGroup.getName() +
" priority_max=" + tGroup.getMaxPriority() +
" daemon=" + tGroup.isDaemon());
int nbreThreadFils = tGroup.activeCount();
System.out.println(indent + "nbreThreadFils="+nbreThreadFils);
Thread[] threadFils = new Thread[nbreThreadFils];
tGroup.enumerate(threadFils,false);
for (int i = 0; i < nbreThreadFils; i++)
infoThread(threadFils[i], indent + " ");
int nbreGroupFils = tGroup.activeGroupCount();
System.out.println(indent + "nbreGroupFils="+nbreGroupFils);
ThreadGroup[] tGroupFils = new ThreadGroup[nbreGroupFils];
tGroup.enumerate(tGroupFils,false);
for (int i = 0; i < nbreGroupFils; i++)
infoThreadGroup(tGroupFils[i],indent + " ");
}
}

public static ThreadGroup getThreadGroupRoot()


{
ThreadGroup current, parent;
current = Thread.currentThread().getThreadGroup();
while ((parent = current.getParent()) != null)
current = parent;
return current;
}

Prof. Marcellin NKENLIFACK, mars 2013 69


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
public static void infoAllThread()
{
ThreadGroup threadGroupRoot = getThreadGroupRoot();
if (threadGroupRoot == null)
System.out.println("ThreadGroupRoot null!");
else
infoThreadGroup(threadGroupRoot);
}
}

4.10 LA SERIALISATION
4.10.1 GENERALITES
La sérialisation d'un objet est le processus de stockage d'un objet complet sur disque ou tout autre système de
stockage, d'où il pourra être restauré à tout moment. Le processus inverse de la restauration est connu sous le nom de
désérialisation. Dans cette section, nous allons voir l'utilité de la sérialisation et la façon dont Java implémente la
sérialisation et la désérialisation.
Un objet sérialisé est dit « persistant ». Par contraste, la plupart des objets en mémoire sont « transiants », ce qui signifie
qu'ils s'en vont quand leurs références sortent de la portée ou quand l'ordinateur est éteint. Les objets « persistants », quant
à eux, existent tant qu'il reste une copie stockée quelque part sur disque, bande ou CD-ROM.

Pourquoi sérialiser ?
Traditionnellement, enregistrer des données sur disque ou une autre unité de stockage nécessite la définition d'un
format de données spécial, l'écriture de fonctions de lecture et d'écriture pour ce format et la création d'une « mappe » entre
le format du fichier et le format des données. Les fonctions de lecture et d'écriture des données étaient soit simples et sans
possibilité d'extension soit complexes et difficiles à créer et à maintenir.
Comme vous devez le savoir maintenant, Java est totalement basé sur les objets et la programmation orientée objet. Pour
cela, le langage fournit un mécanisme de stockage des objets, appelé sérialisation. Avec la façon de faire de Java, vous
n'avez plus besoin de vous préoccuper des détails concernant les formats des fichiers et les E/S. La conception et
l'implémentation d'objets permet de consacrer plus de temps à la résolution des tâches du monde réel. Si, par exemple, vous
rendez une classe persistante et y ajoutez de nouveaux champs par la suite, vous n'avez pas à vous préoccuper de la
modification des programmes de lecture et d'écriture des données.
Tous les champs qui se trouvent dans un objet sérialisé sont automatiquement écrits et restaurés.

4.10.2 SERIALISATION
La sérialisation est une fonction qui date du JDK 1.1. La prise en charge de la sérialisation par Java se compose de
l'interface Serializable, des classes ObjectOutputStream et ObjectInputStream, ainsi que de quelques classes et
interfaces de support. Nous allons illustrer ces trois éléments par une application qui enregistre sur disque des informations
sur les utilisateurs et les relit.
Par exemple, supposons que vous vouliez enregistrer des informations sur un utilisateur particulier comme illustré ci-
dessous. Une fois que l'utilisateur a tapé son nom et son mot de passe dans les champs appropriés, l'application doit
enregistrer ces informations sur disque. Naturellement, cet exemple est très simple, mais il est applicable à l'enregistrement
de données sur les préférences des utilisateurs relatives à leurs applications, du dernier document ouvert, etc.

4.10.2.1 L'interface Serializable


Créons un objet qui représente l'utilisateur actuel. Ses propriétés doivent représenter à la fois le nom de l'utilisateur
et son mot de passe :
package Serialize;
public class InfoUtil implements java.io.Serializable
{
private String nomUtil = "";
private String motPasseUtil = "";
public String obtientNomUtil()
{
return nomUtil;
}
public void définitNomUtil(String s)
{
nomUtil = s;
}
public String obtientMotPasseUtil()
{

Prof. Marcellin NKENLIFACK, mars 2013 70


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
return motPasseUtil;
}
public void définitMotPasseUtil(String s)
{
motPasseUtil = s;
}
}

Remarquez que la classe ci-dessus implémente l'interface java.io.Serializable. Serializable est connue sous le nom
"d'interface de balisage", puisqu'elle ne spécifie aucune méthode à implémenter, mais "balise" plutôt ses objets comme
étant d'un type particulier.
Tout objet prévu pour être sérialisé doit implémenter cette interface. Cela est important, car, sinon, les techniques utilisées
dans la suite ne fonctionnent pas. Si, par exemple, vous essayez de sérialiser un objet qui n'implémente pas cette interface,
une NotSerializableException est émise.

4.10.2.2 Utilisation des flux de sortie


Avant de sérialiser l'objet InfoUtil, donnez-lui les valeurs saisies par l'utilisateur dans les zones de texte. Cette
attribution de valeurs aura lieu lorsqu'il cliquera sur le bouton Sérialiser:
void button1_mouseClicked(MouseEvent e) {
u.définitNomUtil (textFieldName.getText());
u.définitMotPasseUtil (textFieldPassword.getText());
Ensuite, ouvrez un FileOutputStream vers le fichier qui va contenir les données sérialisées. Dans cet exemple, le fichier
s'appelle C:\InfoUtil.txt :
try {
FileOutputStream file = new FileOutputStream
("c:\\InfoUtil.txt");
Ensuite, créez un ObjectOutputStream qui sérialisera l'objet et l'enverra au FileOutputStream.
ObjectOutputStream out = new ObjectOutputStream(file);
Vous pouvez maintenant envoyer l'objet InfoUtil au fichier. Pour cela, appelez la méthode writeObject() de
ObjectOutputStream . Appeler la méthode flush() videra le tampon de sortie pour garantir l'écriture effective de l'objet
dans le fichier.
out.writeObject(u);
out.flush();
Enfin, fermez le flux de sortie pour libérer les ressources utilisées par le flux, comme les descripteurs du fichier.
out.close();
}
Remarquez que, en cas de problème d'écriture sur le fichier ou si l'objet ne prend pas en charge l'interface Serializable,
vous recevez une IOException.
catch (java.io.IOException IOE) {
labelOutput.setText ("IOException");
}
}
Vérifiez dans un éditeur de texte que l'objet a été écrit (N'essayez pas de le modifier, sinon le fichier risquerait d'être
endommagé!). Notez qu'un objet sérialisé contient un mélange de texte ASCII et de données binaires :

Méthodes ObjectOutputStream
La classe ObjectOutputStream contient plusieurs méthodes utiles pour mettre des données dans un flux. Vous
n'êtes pas limité aux objets d'écriture. Appeler writeInt(), writeFloat(), writeDouble() écrira dans un flux n'importe quel
type fondamental. Pour écrire plusieurs objets ou types fondamentaux dans le même flux, appelez ces méthodes plusieurs
fois sur le même objet ObjectOutputStream. Cependant, attention, relire les objets dans le même ordre.

4.10.2.3 Utilisation des flux d'entrée


L'objet a maintenant été écrit sur disque, mais comment le récupérer? Une fois que l'utilisateur a cliqué sur le bouton
« Désérialiser », il vous faut relire les données du disque et les mettre dans un nouvel objet.
Pour commencer le processus, créez un nouvel objet FileInputStream pour lire le fichier que vous venez d'écrire :
void button2_mouseClicked(MouseEvent e) {
try {
FileInputStream file = new FileInputStream
("c:\\userInfo.txt");
Ensuite, créez un ObjectInputStream , ce qui permet de lire les objets de ce fichier.
ObjectInputStream input = new ObjectInputStream(file);

Prof. Marcellin NKENLIFACK, mars 2013 71


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
Ensuite, appelez la méthode readObject() de ObjectInputStream pour lire le premier objet de ce fichier. readObject()
renvoie un type Object qu'il faut transtyper dans le type approprié (InfoUtil).
InfoUtilu = (InfoUtil) input.readObject();
Après la lecture, n'oubliez pas de fermer l'ObjectInputStream pour libérer les ressources qui lui sont associées, comme les
descripteurs du fichier.
input.close();
Enfin, servez-vous de l'objet u comme vous utiliseriez n'importe quel objet de la classe InfoUtil :
labelOutput.setText ("Le nom est : "+u.obtientNomUtil()+",
le mot de passe est : "+
u.obtientMotPasseUtil());
}
La lecture à partir d'un fichier peut provoquer une IOException qu'il vous faut gérer. Vous risquez de recevoir aussi une
StreamCorruptedException (sous-classe de IOException ) si le fichier a été endommagé:
catch (java.io.IOException IOE) {
labelOutput.setText ("IOException");
}
Tenez également compte de l'exception suivante. Si vous essayez de lire un objet pour lequel vous n'avez pas
d'implémentation, la méthode readObject() peut envoyer une ClassNotFoundException. Par exemple, si l'objet a été écrit
par un autre programme ou si vous avez renommé la classe InfoUtil depuis la dernière écriture du fichier, vous obtenez une
ClassNotFoundException.
catch (ClassNotFoundException cnfe) {
labelOutput.setText ("ClassNotFoundException");
}
}

Méthodes de la classe « ObjectInputStream »


ObjectInputStream a aussi des méthodes comme readDouble(), readFloat(), etc., qui correspondent aux méthodes
writeDouble(), writeFloat(), etc. Appelez chaque méthode en séquence, comme pour écrire des objets dans le flux.

4.10.2.4 Ecriture et lecture des flux d'objets


Vous pouvez vous demander ce qui se passe quand un objet en cours de sérialisation contient un champ qui fait
référence à un autre objet plutôt qu'à un type primitif. Dans ce cas, l'objet de base, ainsi que l'objet secondaire, sont écrits
dans le flux.
Cependant, n'oubliez pas que les deux objets écrits dans le flux doivent implémenter l'interface Serializable. Si ce n'est pas
le cas, un appel de la méthode writeObject() provoquera une NotSerializableException.
Cette sérialisation des objets peut poser des problèmes de sécurité potentiels. Dans l'exemple ci-dessus, vous avez écrit un
mot de passe dans un objet sérialisé. Bien que cela soit acceptable dans la plupart des cas, prêtez-y attention quand vous
décidez de sérialiser un objet.
Finalement, pour créer un objet persistant sans utiliser le mécanisme de sérialisation par défaut, l'interface Serializable
documente deux méthodes, writeObject() et readObject(), que vous pouvez implémenter pour exécuter une sérialisation
personnalisée. L'interface « Externalizable » fournit aussi un mécanisme similaire. Pour avoir des informations sur ces
techniques, il vaut mieux consultez la documentation JDK.

4.11 L'ACCES AUX BASES DE DONNEES AVEC JDBC


[wwwJDBC09]
JDBC (Java Data Base Connectivity) est une API java qui permet aux applications java de communiquer avec les
gestionnaires de base de données dans un langage universel. Cette technologie permet de rendre les applications
indépendantes de la base de données à laquelle on se connecte. JDBC garantit les fonctions suivantes :
• Etablir une connexion avec une base de données.
• Envoyer des requêtes SQL.
• Traiter les résultats.

Prof. Marcellin NKENLIFACK, mars 2013 72


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation

4.11.1 ARCHITECTURE D’ACCÈS


Le choix d’une architecture convenanble est important pour interagir avec la base de données. Deux modèles
d’architectures peuvent être envisagés, contenant des couches logicielles reliées par des « protocoles » : l’architecture deux
tiers (2/3) et l’architecture trois tiers (3/3).

Application JDBC
Java
Gestionnaire de Pilote

Pilote PostgreSQL Pilote ... Pilote


Oracle Autre SGBD

Protocole
spécifique

Base de Données Base de Données Base de Données


PostgreSQL Oracle Autre SGBD

Figure 15. Architecture deux tiers (2/3) JDBC

Application /
Serveur (HTTP, RMI, CORBA)
Applet
Java
HTTP
RMI JDBC
CORBA
... Gestionnaire de Pilote

Pilote Pilote ... Pilote


PostgreSQL Oracle Autre SGBD

Protocole
spécifique

Base de Base de Base de


Données Données Données
PostgreSQL Oracle Autre SGBD

Figure 16. Architecture trois tiers (3/3) JDBC

4.11.2 LES PILOTES JDBC DE BASE


[wwwJDBCDriver06]
La connexion à la BD passe généralement par un pilote JDBC, qui peut être commercial (cas de Oracle) ou gratuit (cas
de PostgreSQL, MySQL …).
Comme dans la plupart des méthodes/outils d’accès, on peut dénombrer au moins quatre types de pilotes JDBC :
• Cas1 : Pilotes accédant aux bases de données grâce à une technologie de ponts. Exemple: le pont ODBC. Cela
requiert en général d’installer du code natif sur le poste client.

Prof. Marcellin NKENLIFACK, mars 2013 73


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
• Cas2 : Code Java appellant les méthodes C/C++ natives livrées par les éditeurs de base de données. Cela requiert
d’installer du code natif sur le poste client.
• Cas3 : Ces pilotes fournissent au client une API générique. Le pilote JDBC sur le client communique au moyen de
sockets avec une application intermédiaire sur le serveur qui convertit les requêtes du client en appel API
spécifique du pilote souhaité.
• Cas4 : Via des sockets java, ces pilotes interagissent directement avec le gestionnaire de la base de données.

Utilisation du pilote : Le pilote peut être téléchargé sous forme d’archive sur Internet. Pour utiliser cette archive, il faut la
décompresser, par exemple dans le répertoire d'installation de votre SGBD.
Il faut s'assurer que les fichiers jar sont accessibles dans le classpath ou les préciser manuellement lors de la compilation.
Ceci évitera de repréciser à chaque fois (durant la compilation) le chemin complet du pilote ;
Voir exemple ci-dessous (le classpath n’ayant pas été défini) :
C:\$user>javac -classpath c:\j2sdk1.8.0-rc\jre\lib\postgresql.jdbc4.jar TestJDBC11.java
C:\$user>java -cp .;c:\j2sdk1.8.0-rc\jre\lib\postgresql.jdbc4.jar TestJDBC11

La solution dans ce cas : export CLASSPATH=/usr/lib/jvm/jdk1.6.0_17/lib

4.11.3 CLASSES SOLLICITÉES POUR LA CONNEXION ET L’ACCÈS AUX DONNÉES


Les classes de JDBC sont incluses dans le package java.sql. Celui-ci sera donc importé dans chaque programme
utilisant JDBC : import java.sql.* ;
On retrouve quatre classes principales : DriverManager, Connection, Statement ( ou PreparedStatement ) et ResultSet.
Chaque classe joue un rôle précis pour l’accès aux BD :
• java.sql.DriverManager
La localisation du pilote JDBC et le chargement des classes correspondantes s’effectue grâce à un objet
DriverManager (Gestionnaire de pilote).
• java.sql.Driver
Cette interface prédéfinie en Java devra être implémentée par le programmeur, qui définira une classe pour activer le
chargement des pilotes JDBC.
• java.sql.Connection
Les différentes requêtes SQL transmises et le retour des résultats s’effectueront à travers un objet Connection
représentant le lien (logique) entre l’application et la base de données.
• java.sql.Statement
Cette classe sera très intéressante pour des requêtes SQL élémentaires. Elle contient un ensemble de méthodes parmi
lesquelles :
public ResultSet executeQuery (String sql) throws SQLException
public int executeUpdate (String sql) throws SQLException
public boolean execute(String sql) throws SQLException
• java.sql.ResultSet
Après l’extraction des données de la BD par une requête SQL, une instance de cette classe contient une rangée de
ces données. Il existe diverses méthodes permettant d’y extraire les colonnes.
Voici La syntaxe :
<type> get<type> (int | String)
Exemple: String getString (« title »)
Un objet ResultSet ne pourra contenir plus d’une rangée à la fois (au même instant). Cependant, une méthode next()
permet de référencer en cas de besoin la rangée suivante.
• java.sql.PreparedStatement
L’envoi au SGBD des données d’une requête SQL (pour interprétation mais non pour exécution) utilisera cette
classe. La requête pourra contenir des paramètres susceptibles d’être renseignés ultérieurement.

4.11.4 EXEMPLE D’APPLICATION SIMPLE DE CONNEXION À UNE BD ÉLÉMENTAIRE


//----------------------------------
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class ConnexionBD {


/**
* @param args
* @throws ClassNotFoundException

Prof. Marcellin NKENLIFACK, mars 2013 74


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
* @throws SQLException
*/
public static void main(String[] args) throws ClassNotFoundException, SQLException
{
private Connection ConnPsql ;
String bdurl = "jdbc:postgresql://localhost:5432/testdb";
String user = "master";
String password = "Master*2013";
Statement ObjetReq ;
String requete = "INSERT into PRODUIT VALUES ('Pdt16','Bonbon','500','Rose')" ;
// chargement du pilote
try
{
Class.forName("org.postgresql.Driver").newInstance();
}
catch (Exception e)
{
System.err.println(" Probleme de chargement du pilote JDBC: " + e);
return ;
}
//connection a la base de données
try
{
ConnPsql = DriverManager.getConnection(bdurl, user, password);
}
catch (SQLException e)
{
System.err.println("Probleme de connexion au SGBD : " + e) ;
return ;
}

//creation et execution de la requête


ObjetReq = ConnPsql.createStatement();
ObjetReq.execute(requete);
ObjetReq.close();
}

//-----------------------------------------------------------------------

4.11.5 ACCES AUX DONNEES AVEC JAVA VIA UN PILOTE JDBC


Nous allons voir comment retrouver et présenter les données à partir d’une table d’une base de données.

La classe ResultSet
Cette classe représente une abstraction d'une table qui se compose de plusieurs enregistrements constitués de colonnes qui
contiennent les données.
Les principales méthodes pour obtenir des données sont :
Méthode Role
getInt(int) retourne le contenu de la colonne dont le numéro est passé en paramètre sous forme d'entier.
getInt(String) retourne le contenu de la colonne dont le nom est passé en paramètre sous forme d'entier.
getFloat(int) retourne le contenu de la colonne dont le numéro est passé en paramètre sous forme de nombre flottant.
getFloat(String)
getDate(int) retourne le contenu de la colonne dont le numéro est passé en paramètre sous forme de date.
getDate(String)
next() se déplace sur le prochain enregistrement : retourne false si la fin est atteinte
Close() ferme le ResultSet
getMetaData() retourne un objet ResultSetMetaData associé au ResultSet.

Tableau 5. Principales méthodes pour obtenir des données d'une BD (JDBC)

La méthode getMetaData() retourne un objet de la classe ResultSetMetaData qui permet d'obtenir des informations
sur le résultat de la requête. Ainsi, le nombre de colonnes peut être obtenu grace à la méthode getColumnCount de cet objet.
Nous allons dans un exemple, récupérer les données d’une table « Produit » dans une Base de données « Commerce ».
import java.sql.*;

public class TestJDBC {

Prof. Marcellin NKENLIFACK, mars 2013 75


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
private static void affiche(String message) {
System.out.println(message);
}

private static void arret(String message) {


System.err.println(message);
System.exit(99);
}

public static void main(java.lang.String[] args) {


Connection ConnPsql ;
String bdurl = "jdbc:postgresql://localhost:5432/commerce";
String user = "master";
String password = "Master*2013";
ResultSet resultats = null;
String requete = "";

// chargement du pilote
try {
Class.forName("org.postgresql.Driver").newInstance();
} catch (Exception e) {
arret("Impossible de charger le pilote jdbc pour PostgreSQL");
}

//connection a la base de données


affiche("connection a la base de donnees");
try {

String DBurl = " jdbc:postgresql://localhost:5432/commerce";


ConnPsql = DriverManager.getConnection(bdurl, user, password);
} catch (SQLException e) {
arret("Connection a la base de donnees impossible");
}

//creation et execution de la requête


affiche("creation et execution dela requête");
requete = "SELECT * FROM Produit";

try {
Statement ObjetReq = ConnPsql.createStatement();
resultats = ObjetReq.executeQuery(requete);
} catch (SQLException e) {
arret("Anomalie lors de l'execution de la requete");
}

//parcours des données retournees (table)


affiche("Parcours des donnees retournees");
try {
ResultSetMetaData tabres = resultats.getMetaData();
int nbCols = tabres.getColumnCount();
boolean suivant = resultats.next();

while (suivant) {

for (int i = 1; i <= nbCols; i++)


System.out.print(resultats.getString(i) + "");

System.out.println();
suivant = resultats.next();
}

resultats.close();
} catch (SQLException e) {
arret(e.getMessage());
}

affiche("fin du traitement de parcours de la BD");


System.exit(0);
}
}
//-----------------------------------------------------------------------

Prof. Marcellin NKENLIFACK, mars 2013 76


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliothèques de classes et techniques de programmation
4.11.6 REQUÊTES AVEC JOINTURES

4.11.7 GESTION DES IMAGES

4.11.8 GESTION DES TRANSACTIONS


Les opérations sur la base de données sont en mode « auto-commit » par défaut (chaque opération est validée
unitairement pour former la transaction).
Si on souhaite que plusieurs opérations soient rassemblées en une seule transaction :
• connection.setAutoCommit(false);
• connection.commit () ;
Retour en arrière:
• connection.rollback ();

4.11.9 MISES A JOUR PAR LOTS (BATCH)

4.11.10 EXPORTATION ET IMPORTATION DES DONNÉES

Prof. Marcellin NKENLIFACK, mars 2013 77


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils

5 PROGRAMMATION RESEAU ET REPARTIE

5.1 INTRODUCTION
JAVA est un langage de programmation par excellence des applications réseau et client-serveur, notamment autour du
Worl Wide Web.
Les Bibliothèques réseau Java sont suffisament fournies pour pouvoir lire et écrire des flux d’informations et éffectuer des
traitements répartis entre machines en réseau.

5.2 PROGRAMMATION RÉSEAU

5.2.1 LES SOCKETS (CLIENT SERVEUR)

5.2.2 SERVICE EN DIRECTION DE PLUSIEURS CLIENTS

5.2.3 LES DATAGRAMS

5.2.4 UTILISER DES URLS DEPUIS / EN DIRECTION D’UNE APPLET

5.3 SERVLETS

5.3.1 BASES DE SERVLETS

5.3.2 SERVLETS ET MULTITHREADING

5.3.3 EXÉCUTION DE SERVLETS

5.4 JAVA SERVER PAGES

5.4.1 OBJETS IMPLICITES

5.4.2 PRINCIPALES DIRECTIVES JSP

5.4.3 LES SCIPTS JSP

5.4.4 EXTRACTION DES CHAMPS ET VALEURS

Prof. Marcellin NKENLIFACK, mars 2013 78


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils
5.4.5 PROPRIÉTÉS DE JSP

5.4.6 MANIPULATION DE SESSIONS JSP

5.4.7 CREATION ET MODIFICATION DE “COOKIES”

5.5 INVOCATION DE MÉTHODES À DISTANCE: RMI (REMOTE METHOD


INVOCATION)

5.5.1 INTERFACES DISTANTES

5.5.2 IMPLEMENTATION DES INTERFACES DISTANTES

5.5.3 CREATION DES “STUBS” ET “SQUELETTES”

5.5.4 UTILISATION DES OBJETS DISTANTS

5.6 LE BUS LOGICIEL CORBA

5.6.1 PRESENTATION DE CORBA

5.6.2 APPLETS JAVA ET CORBA

5.6.3 COMPARAISON ENTE CORBA ET RMI

5.7 ENTERPRISE JAVABEANS

5.7.1 COMPARISON ENTRE JAVABEANS ET. EJBS

5.7.2 SPECIFICATION DES EJB

5.7.3 COMPOSENTA EJB

5.7.4 STRUCTURE DES COMPOSANTS EJB

Prof. Marcellin NKENLIFACK, mars 2013 79


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils
5.7.5 OPERATIONS EJB

5.7.6 TYPES D’EJBS

5.7.7 DEVELOPPER UN EJB

5.8 SERVICES DISTRIBUES JINI

5.8.1 CONTEXTE ET PRESENTATION DE JINI

5.8.2 FONCTIONNEMENT DE JINI

5.8.3 DIVERS PROCESSUS JINI

5.8.4 SEPARATION DE L’INTERFACE ET DE L’IMPLEMENTATION

5.8.5 ABSTRACTON DANS LES SYSTEMES REPARTIS

5.9 QUELQUES EXERCISES

5.10 CONCLUSION

Prof. Marcellin NKENLIFACK, mars 2013 80


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils

6 AUTRES CONCEPTS, TECHNIQUES ET OUTILS

6.1 INTRODUCTION
Il est question dans ce chapitre de faire une brève introduction sur les concepts, techniques et outils
complémentaires, pour ouvrir l’esprit des apprenants qui auront à affronter des projets tout au long de leur carrière.

6.2 FICHIERS DE TYPE ARCHIVE JAVA


Une archive java est un fichier « .jar » au format « zip » contenant des fichiers compressés de natures diverses et un fichier
manifeste. Elles ont les caractéristiques suivantes :
• Multi-plateforme
• Auto-descriptif
• Sécurité et authentification
• Téléchargeable par navigateur
La gestion des archives Java est possible depuis la version 1.1 du JDK.
• Les fichiers archives rassemblent et compressent plusieurs classes java dans un seul fichier.
• Les fichiers archives peuvent être signés.
• Un fichier « jar » peut être créé avec la commande jar du JDK; la syntaxe est inspirée de la commande « tar » d'unix.
Exemples:
jar cvf applet.jar *.class
jar tvf applet.jar
jar xvf applet.jar
Utilisation d'un fichier jar:
<APPLET CODE="app.class" ARCHIVE="applet.jar" …>

6.3 UTILISATION DE L'INTERFACE DE CODE NATIF


6.3.1 GENERALITES ET MOTIVATIONS
Nous allons dans ce paragraphe expliquer comment appeler des méthodes natives dans les applications Java en
utilisant l'interface Java (Java Native Interface ou JNI) prévue à cet effet. Nous allons commencer par voir comment la
JNI fonctionne dans le JDK (version supérieur à 1.1).
Nous présenterons ensuite le mot clé « native » et la façon de rendre native n'importe quelle méthode Java. Nous
terminerons par l'étude de l'outil javah du JDK, utilisé pour générer des fichiers d'en-tête C pour des classes Java.

Les motivations en faveur de JNI (Java Native Interface)


Certaines fonctionnalités peuvent être inaccessibles à JAVA :
• Supporter les fonctionnalités dépendantes de la plate forme et requises par l’application (adressage physique, accès au
matériel, interruption, …) ;
• Développer en C/C++ tout en bénéficiant de l’IHM java ;
• Rendre accessible au code java une bibliothèque existante dans un autre langage ;
• Utiliser du code natif pour accélérer le temps d’exécution.
Quelques conséquences :
• La portabilité est annulée ;
• La sécurité et la robustesse deviennent moindres.

Présentation de JNI
Il est possible :
• D’appeler des fonctions C/C++ depuis Java.
• D’accéder à des objets Java depuis le C/C++.
En plus, JNI permet :
• D’écrire des méthodes natives
• D’appeler des méthodes java
• De capturer et de déclencher des exceptions
• De charger des classes
• etc.

Prof. Marcellin NKENLIFACK, mars 2013 81


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils
6.3.2 UTILISATION DE LA JNI
Pour que Java atteigne son but principal, c'est-à-dire l'indépendance vis-à-vis des plates-formes, Sun n'a pas
standardisé son implémentation de la machine virtuelle Java; la société a voulu conserver à l'architecture de la JVM une
certaine souplesse, qui permet aux fournisseurs de personnaliser leurs implémentations. Java reste indépendant des plates-
formes, puisque chaque implémentation de la JVM doit se conformer à certaines règles impératives pour respecter
l'indépendance vis-à-vis des plates-formes (comme la structure standard d'un fichier .class). Avec ce scénario, le seul
problème est un accès difficile aux bibliothèques natives à partir des applications Java, puisque le système d'exécution
diffère selon les implémentations de la JVM. Pour cette raison, Sun propose la JNI comme moyen standard d'accès aux
bibliothèques natives à partir des applications Java. La façon d'accéder aux méthodes natives à partir des applications Java
a changé à partir du JDK1.1. Dans l'ancien JDK, une classe Java pouvait accéder directement aux méthodes d'une
bibliothèque native. La nouvelle implémentation utilise la JNI comme couche intermédiaire entre une classe Java et une
bibliothèque native. Au lieu d'appeler directement les méthodes natives, la JVM utilise pour ses appels réels un pointeur
vers la JNI. De cette façon, même si les implémentations de la JVM sont différentes, la couche utilisée pour accéder aux
méthodes natives (la JNI) est toujours la même.

Utilisation du mot clé native


Cette solution est simple pour rendre natives des méthodes Java.
Voici un résumé des étapes nécessaires:
- Supprimer le corps principal de la méthode.
- Ajouter un point-virgule à la fin de la signature de la méthode.
- Ajouter le mot clé native au début de la signature de la méthode.
- Inclure le corps de la méthode dans une bibliothèque native à charger lors de l'exécution.
Considérons par exemple que la méthode suivante existe dans une classe Java :
public void nativeMethod ()
{
//corps de la méthode
}
Voici comment rendre la méthode native :
public native void nativeMethod ();
Une fois la méthode déclarée comme native, où se trouve son implémentation réelle?
Elle est incluse dans une bibliothèque native. C'est la classe à laquelle cette méthode appartient qui doit appeler la
bibliothèque, ce qui rend son implémentation disponible à qui en a besoin. Pour qu'une classe appelle la bibliothèque, le
plus simple consiste à ajouter ce qui suit à la classe :
static
{
System.loadLibrary (nomDeBibliothèque);
}
Un bloc de code static est toujours exécuté une fois, lors du premier chargement de la classe. Vous pouvez mettre
pratiquement tout ce que vous voulez dans un bloc static; le plus souvent, il sert au chargement des bibliothèques. Si, pour
une raison quelconque, le chargement de la bibliothèque échoue, une exception UnsatisfiedLineError est émise dès qu'une
méthode de cette bibliothèque est appelée. Si le chargement réussit, la JVM ajoute la bonne extension à son nom (.dll dans
Windows et .so dans Unix/Linux).

6.3.3 UTILISATION DE L'OUTIL JAVAH


Le JDK fournit un outil appelé javah, qui génère des fichiers d'en-tête C pour des classes Java. Voici la syntaxe
générale d'utilisation de javah :
javah [options] nomClasse
nomClasse représente le nom de la classe (sans l'extension .class) pour laquelle vous voulez générer un fichier d'en-tête C.
Vous pouvez préciser plusieurs classes sur une ligne de commande. Pour chaque classe, javah ajoute par défaut un fichier
« .h » au répertoire des classes. Si vous voulez que les fichiers « .h » soient placés ailleurs, utilisez l'option -o . Si une
classe se trouve dans un paquet, précisez le paquet et le nom de la classe.
Par exemple, pour générer un fichier d'en-tête pour la classe maClasse du paquet monPaquet , procédez comme suit:
javah monPaquet.maClasse
Le fichier d'en-tête généré inclura le nom du paquet (monPaquet_maClasse.h).

Liste de quelques options utilisées avec javah :


-jni -> Crée un fichier d'en-tête JNI
-verbose -> Affiche des informations sur l'avancement des opérations
-version -> Affiche la version de javah
-o directoryName -> Met le fichier .h résultant dans un répertoire précisé
-classpath path -> Redéfinit le chemin par défaut de la classe

Prof. Marcellin NKENLIFACK, mars 2013 82


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils
Le contenu du fichier « .h » file généré par javah inclut tous les prototypes de fonctions pour les méthodes native de la
classe. Les prototypes sont modifiés pour que le système d'exécution de Java trouve et appelle les méthodes natives. Cette
modification implique un changement du nom de la méthode selon une convention de nom établie pour l'appel des
méthodes natives. Le nom modifié comprend le préfixe Java_ et les noms de la classe et de la méthode. Ainsi, si une
méthode native appelée méthodeNative se trouve dans la classe maClasse, le nom qui figure dans le fichier maClasse.h est
Java_maClasse_méthodeNative.

6.3.4 INTER-ECHANGES JAVA - C/C++


De Java vers C/C++
Méthodologie:
• Utilisation du mot clé native
• Génération d’un fichier d’entête « .h » (avec javah)
• Ecriture du code natif et génération d’une bibliothèque « .dll » (Windows) « .so » (Unix/Linux)
Exemple: Java vers C/C++
Compilation sous Linux
javac JavaVersC.java
gcc -shared bonjour.c -I /usr/local/java/include
-I /usr/local/java/include/linux -o libJavaVersC.so
De C/C++ vers Java
Les mécasnismes de JNI permettent :
- L’acces aux variables d’instance
- L’acces aux variables de classe
- L’acces aux méthodes d’instance
- L’acces aux méthodes de classe

6.4 LA SECURITE DANS LE MONDE JAVA EN GENERAL


6.4.1 ELÉMENTS DE SÉCURITÉ
Depuis le départ, la sécurité a été une préoccupation dans la conception de Java
Voici quelques éléments de sécurité qui doivent rester en permanence dans notre esprit :
1) Se prémunir des programmes malveillants (virus, chevaux de troie, etc.)
2) Pas d'intrusion (pas d'accès à des informations privées)
3) Authentification des parties en cours
4) Cryptage
5) Audit

Remarque sur les point ci-dessus :


•Les points 1 et 2 sont pris en compte dès la norme 1.0 de Java
•Le point 3 a été pris en compte par la norme 1.1
•Le point 4 a été pris en compte par la norme 1.2
•Le point 5 peut être pris en compte dans la norme 1.2 par ajout d'un module

6.4.2 LA "SANDBOX" JAVA


•La sécurité java est axée autour d'une "sandbox" qui va établir le contour de l'environnement auquel peut accéder
l'application.
•La notion de sécurité dans les applications et les applets est très différente :
•Une application peut définir sa politique de sécurité
•Une applet est tributaire de la politique de sécurité définie par le navigateur qui l'a chargée.
•Une "sandbox" peut être le « CPU » et la mémoire centrale de la machine cliente, ou le serveur web de
téléchargement de l'applet.

6.4.3 LA SÉCURITÉ DES APPLETS JAVA


Les applets sont soumises à de nombreuses restrictions:
•Pas d'accès au disque dur local de l'utilisateur.
•Pas de connexion sur une machine autre que le serveur WWW d'origine de l'applet.
•Pas de lancement de programme sur la machine de l'utilisateur.
•Pas de chargement de programmes stockés sur la machine de l'utilisateur (exécutable, bibliothèque partagée).

Prof. Marcellin NKENLIFACK, mars 2013 83


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils
Les modèles de sécurité des Applets selon les versions Java
• java 1.0: sandbox très restrictive
• java 1.1: principe du tout ou rien selon que la signature électronique est utilisée ou non.
• java 1.2: principe du moindre privilège. Une stratégie de sécurité pourra être appliquée à une application ou à une
applet en fonction de son origine, de l'identité du tiers certificateur.
Exemple:
- Accorder à toutes les applets de http://www.iutfv-bandjoun.info la permission de lire les fichiers du
répertoire c:\temp.
- Accorder à toutes les applets la permission de se connecter sur n'importe quelle machine.
- etc.
• java 1.3 / 1.4 / 1.5 / 1.6 / 1.7 / 1.8 : [donné en exercice]
Spécification de la stratégie de sécurité
• Créer ou modifier le fichier de stratégie système
<java.home>\lib\security\java.policy.
• Donner à la propriété système java.policy le nom d'un autre fichier de stratégie de sécurité.
• Créer ou modifier le fichier de stratégie utilisateur dans
<user.home>\java.policy
• Définir une autre valeur pour la propriété java.policy en utilisant l'option -D de la ligne de commande :
java -Djava.policy="test.policy" Test
• Changer la classe utilisée dans le fichier <java.home>\lib\security\java.security
en changeant la ligne policy.provider=java.security.PolicyFile en policy.provider=AutreClasse.
Vous pouvez créer votre fichier d'une stratégie de sécurité
• Création du fichier jar :
jar cvf ecritfichier.jar ecritfichier\*.class
• Dans <java.home>\lib\security\java.security, ajout de la ligne :
policy.url.3=file:${java.home}/lib/security/ecritfichier.policy
• Création du fichier <java.home>\lib\security\ecritfichier.policy, soit manuellement, soit avec l'outil policytool de
la jdk :
/* AUTOMATICALLY GENERATED ON Mon Apr 09 16:52:09 CEST 2009 */
/* DO NOT EDIT */
grant {
permission java.io.FilePermission "c:\\temp\\*", "write";
};

L’applet peut être signée


• Génération d'une paire de clés :
keytool -genkey -alias TestCle -keystore trousseau
• Signature de l'applet :
•Signature de la clé publique par un tiers certificateur (moyennant finance), par exemple:
Verisign http://www.verisign.com
Thawte http://www.thawte.com
On extrait le certificat qui pourra être authentifié :
keytool -export -keystore trousseau -alias TestCle -file certificat.cer
• Auto signature du fichier jar à des fins de test:
jarsigner -keystore trousseau ecritfichier.jar TestCle

6.5 PROTECTION DE VOS CODES SOURCES : OBFUSCATION DE CODE


Les informations sont stockées dans les fichiers de bytecode lorsque vous compilez votre fichier source java.
Malheureusement, si une personne procède à la décompilation, il pourra le récupérer le code source intégralement (sans les
commentaires). Ceci montre la nécessité de trouver des moyens pour « brouiller » le code avant sa diffusion. Les outils
permettant d’atteindre ce résultat sont appelés « obfuscateurs ».
Des exemples de décompilateurs :
• Historiquement, mocha en 1996 par Hanpeter Van Vliet
• DJ Java Decompiler: http://members.fortunecity.com/neshkov/dj.html

Plusieurs outils d'obfuscation existent


• Zelix Class Master : http://www.zelix.com
- Obfuscation des noms et du code.

Prof. Marcellin NKENLIFACK, mars 2013 84


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils
- Cryptage des chaînes.
- Suppression des classes, méthodes, données non utilisées.
- Interface graphique et langage de script
- Support de la J2ME et J2EE
• yGuard: http://www.yworks.com
• ProGuard: http://proguard.sourceforge.net
• CodeShield: http://www.codingart.com

6.6 DEVELOPPEMENTS AVEC JME


JME (Java Micro Edition) permet le développement des applications sur des appareils mobiles tel que des PDA, des
téléphones cellulaires, des terminaux de points de vente, des systèmes de navigations pour voiture, ...
Il s’agit là d’un véritable « retour aux sources » puisque Java avait été initialement développé pour piloter des appareils
électroniques.

6.6.1 LES CONFIGURATIONS


Deux configurations sont essentiellement utilisées : Connected Device Configuration (CDC) et Connected Limited Device
Configuration (CLDC) :
• La CDC est plus adaptée aux terminaux relativement puissants comme les PDA. En effet, elle nécessite une
machine virtuelle java optimisée appelée CVM qui offre les mêmes fonctionnalités que la JVM classique.
• La CLDC est, par contre, dédiée aux appareils avec de faibles capacités comme les téléphones portables. La
machine virtuelle allégée correspondante est la KVM (Kilobyte Virtual Machine) et ne possède pas certaines
fonctions de la JVM classique.

6.6.2 LES PROFILS


Lorsqu'une configuration définit le fondement d'une application, un profil en fournit la structure. Les profils définissent
l'ensemble des API à utiliser dans une application JME et sont conçus spécialement pour chaque configuration.
Sun propose deux profils de référence JME : le profil Foundation et le profil Mobile Information Device Profile (MIDP).
• Le profil Foundation est destiné à la configuration CDC. Les développeurs qui utilisent ce profil ont accès à une
implémentation complète des fonctionnalités de J2SE.
• Le profil MIDP est destiné à la configuration CLDC. Il prend en charge un nombre limité des classes de J2SE et
définit des classes d'entrée/sortie et d'interface spécialisées pour une configuration CLDC.
Présentation
Ils sont composés d’un ensemble d'API spécifiques pour un type de machines ou une fonctionnalité particulière. Ils
permettent l'utilisation de fonctionnalités précises et doivent être associés à une configuration. Ils permettent donc d'assurer
une certaine modularité à la plate-forme JME.
Il existe plusieurs profiles :
Profil Configuration JSR
MIDP 1.0 CLDC 37 Package javax.microedition.*
Foundation Profile CDC 46
Personal Profile CDC 62
MIPD 2.0 CLDC 118
Personal Basis Profile CDC 129
RMI optional Profile CDC 66
Mobile Media API (MMAPI) 1.1 CLDC 135 Permet la lecture de clips audio et vidéo
PDA 75
JDBC optional Profile CDC 169
Wireless Messaging API (WMA) 1.1 CLDC 120 Permet l'envoi et la réception de SMS

Tableau 6. Les profiles définis (JME)

Lorsqu’on combine les profiles MIDP (Mobile Information Device Profile) et CLDC (Connected Limited Device
Configuration), on a un environnement d’exécution Java de référence, très adapté aux équipements compactes et mobiles
tesl que les téléphones cellulaires, les PDAs, etc.
MIDP était le premier profile développé, dont l'objectif principal était le développement d'application sur des machines aux
ressources et interface limitées tel qu'un téléphone cellulaire. Ce profil peut aussi être utilisé pour développer des
applications sur des PDA de type Palm.
L'API du MIDP se compose des API du CDLC et de trois packages :
• javax.microedition.midlet : cycle de vie de l'application ;

Prof. Marcellin NKENLIFACK, mars 2013 85


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Autres concepts, techniques et outils
• javax.microedition.lcdui : interface homme machine ;
• javax.microedition.rms : persistance des données.
Des informations complémentaires et le téléchargement de l'implémentation de référence de ce profil peuvent être trouvées
sur le site de Sun : http://java.sun.com/products/midp/

6.6.3 LES MIDLETS


Les midlets sont des petites applications créées à l’aide de MIDP. Les classes héritent de la classe abstraite
javax.microedition.midlet.Midlet. Cette classe permet le dialogue entre le système et l'application.
Elle possède trois méthodes principales qui permettent de gérer le cycle de vie de l'application en fonction des trois états
possibles (active, suspendue ou détruite) :
• startApp() : cette méthode est appelée à chaque démarrage ou redémarrage de l'application ;
• pauseApp() : cette méthode est appelée lors de la mise en pause de l'application ;
• destroyApp() : cette méthode est appelée lors de la destruction de l'application.
Ces trois méthodes doivent obligatoirement être redéfinies.

6.6.4 CONCLUSION
[WWWJME06]
La fusion PDA, téléphone, console de jeux, lecteur mp3 se fait. Les débits de communications augmentent et les
applications logicielles deviennent vraiment communiquantes et les accès aux bases de données, à divers serveurs ouvrirent
encore plus les possibilités des développeurs. Avec MIDP, les développeurs peuvent déjà toucher un bon nombre d'usagers.
Au fur et à mesure, les avancées technologiques importantes toucheront le grand public et on y a déjà remarqué
l'importance de la téléphonie.
En plus des SDK propriétaires à chaque constructeur, d'autres technologies essayent de s'insérer dans ce marché. On
trouve, par exemple, un framework .NET dépouillé même si peu des téléphones actuels l'utilisent (plutôt reservé aux PDA
de type PocketPC) ... Macromedia propose dans son Flash MX de créer des applications pour les appareils mobiles, un
FlashPlayer allégé existe aussi.

Prof. Marcellin NKENLIFACK, mars 2013 86


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Annexe

7 ANNEXE : QUELQUES PROBLEMES COURANTS ET ASTUCES


[wwwSolProb04]

7.1 COMMON COMPILER AND INTERPRETER PROBLEMS (AND THEIR


SOLUTIONS)
If you're having trouble compiling your Java source code or running your application, this section might be able to help you. If nothing in
this section helps, please refer to the documentation for the compiler or interpreter you're using.

7.1.1 COMPILER PROBLEMS


* Can't Locate the Compiler
On UNIX systems, you may see the following error message if your path isn't set properly:
* javac: Command not found
Use setenv or a similar command to modify your PATH environment variable so that it includes the directory where the Java compiler
lives.
* Syntax Errors
If you mistype part of a program, the compiler may issue a syntax error. The message usually displays the type of the error, the line
number where the error was detected, the code on that line, and the position of the error within the code. Here's an error caused by
omitting a semicolon (;) at the end of a statement:
* testing.java:14: `;' expected.
System.out.println("Input has " + count + " chars.")
^
1 error
Sometimes the compiler can't guess your intent and prints a confusing error message or multiple error messages if the error cascades over
several lines. For example, the following code snippet omits a semicolon (;) from the bold line:
* while (System.in.read() != -1)
count++
System.out.println("Input has " + count + " chars.");
When processing this code, the compiler issues two error messages:
* testing.java:13: Invalid type expression.
count++
^
testing.java:14: Invalid declaration.
System.out.println("Input has " + count + " chars.");
^
2 errors
* The compiler issues two error messages because after it processes count++, the compiler's state indicates that it's in the middle
of an expression. Without the semicolon, the compiler has no way of knowing that the statement is complete.
If you see any compiler errors, then your program did not successfully compile, and the compiler did not create a .class file. Carefully
verify the program, fix any errors that you detect, and try again.
Semantic Errors
In addition to verifying that your program is syntactically correct, the compiler checks for other basic correctness. For example, the
compiler warns you each time you use a variable that has not been initialized:
* testing.java:13: Variable count may not have been initialized.
count++
^
testing.java:14: Variable count may not have been initialized.
System.out.println("Input has " + count + " chars.");
^
2 errors
Again, your program did not successfully compile, and the compiler did not create a .class file. Fix the error and try again.

7.1.2 INTERPRETER PROBLEMS


* Can't Find Class
A common error of beginner Java programmers using the UNIX or Windows 95/NT JDK is to try to interpret the .class file created by
the compiler. For example, if you try to interpret the file HelloWorldApp.class rather than the class HelloWorldApp, the interpreter
displays this error message:
* Can't find class HelloWorldApp.class
The argument to the Java interpreter is the name of the class that you want to use, not the filename.
The main Method Is Not Defined

Prof. Marcellin NKENLIFACK, mars 2013 87


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Annexe
The Java interpreter requires that the class you execute with it have a method named main, because the interpreter must have somewhere
to begin execution of your Java application. The main Method<Image: (in the Getting Started trail)> discusses the main method in detail.
If you try to run a class with the Java interpreter that does not have a main method, the interpreter prints this error message:
* In class classname: void main(String argv[]) is not defined
In the above message, classname is the name of the class that you tried to run.
* Changes to My Program Didn't Take Effect
Sometimes when you are in the edit/debug/run cycle, it appears that your changes to an application didn't take effect -- a print statement
isn't printing, for example. This is common when running Java applications on MacOS using Java Runner. If you recompile a .class file,
you must quit Java Runner and bring it up again, since Java Runner does not reload classes.

7.2 COMMON APPLET PROBLEMS (AND THEIR SOLUTIONS)


This section covers some common problems that you might encounter when writing Java applets. After each problem is a list of possible
solutions.
* Problem: Applet Viewer says there's no <APPLET> tag on my HTML page, but it really is there.
•Check whether you have a closing applet tag: </APPLET>.

* Problem: I recompiled my applet, but my applet viewing application won't show the new version, even though I told it to reload
it.
•In many applet viewers (including browsers), reloading isn't reliable. This is why we recommend that you simply use the JDK Applet
Viewer, invoking it anew every time you change the applet. •If you get an old version of the applet, no matter what you do, make sure
that you don't have an old copy of the applet in a directory in your CLASSPATH. See Managing Source and Class Files<Image: (in the
Learning the Java Language trail)> for information about the CLASSPATH environment variable.
* Problem: The light gray background of my applet causes the applet to flicker when it's drawn on a page of a different color.
•You need to set the background color of the applet so that it works well with the page color. See Creating a GUI<Image: (in the Writing
Applets trail)> for details.
* Problem: The Applet getImage method doesn't work.
•Make sure you're calling getImage from the init method or a method that's called after init. The getImage method does not work when
it's called from a constructor.
* Problem: Now that I've copied my applet's class file onto my HTTP server, the applet doesn't work.
•Does you applet define more than one class? If so, make sure that the class file (ClassName.class) for each class is on the HTTP server.
Even if all the classes are defined in one source file, the compiler produces one class file per class. •Did you copy all the data files for
your applet -- image and sound files, for example -- to the server? •Make sure all the applet's class and data files can be read by everyone.
•Make sure the applet's class and data files weren't garbled during the transfer. One common source of trouble is using the ASCII mode
of FTP (rather than the BINARY mode) to transfer files.
* Problem: I can't get my applet to run. The browser displays a ClassCastException.
•If your applet has multiple classes, did you specify the right one (an Applet subclass) in the applet tag's CODE attribute?

7.3 COMMON COMPONENT PROBLEMS (AND THEIR SOLUTIONS)


* Problem: How do I increase or decrease the number of components in a container?
•To add a component to a container, use one of the three forms of the Container add() method. See General Rules for Using Components
for information. To remove a component from a container, use the Container remove() or removeAll() method. Or just add the
component to another container, since that automatically removes the component from its previous container.
* Problem: My window never shows up!
•Did you either set the size of the window or pack it? •Did you make the window visible using the show method?
* Problem: My component never shows up!
•Did you add the component to its container using the right add() method for the container's layout manager? BorderLayout (the default
layout manager for windows), silently fails to add your component if you call the one-argument version of add(). See the Laying Out
Components within a Container<Image: (in the Creating a User Interface trail)> lesson for examples of using the add() method. •If you're
not using the default layout manager, did you successfully create an instance of the right layout manager and call setLayout() on the
container? •If the component is added properly, but to a container that might already be visible, did you call validate() on the container
after adding the component? •If your component is a custom component (a Canvas subclass, for example), does it implement the
minimumSize() and preferredSize() methods so that they return the correct size of the component? •If you use a non-AWT layout
manager, or none at all, does the component have a reasonable size and display coordinates? In particular, if you use absolute positioning
(no layout manager), you must explicitly set the size of your components, or they just won't show up. See Doing Without a Layout
Manager <Image: (in the Creating a User Interface trail)>.
* Problem: My custom component doesn't get updated when it should.
•Make sure that the component's repaint() method is called every time the component's appearance should change. For standard
components, this isn't a problem, since platform-specific code takes care of all the drawing of the component. For custom components,
however, you have to explicitly call the repaint() method on the component whenever the component's appearance should change.
Invoking repaint() on a container of the component is not good enough. See How to Use Canvases for more information.
* Problem: My component isn't getting XYZ event.
•Check whether the component is getting any events, at all. If it isn't, make sure you're referring to the right component -- that you
instantiated the right class, for example. •Make sure your component passes through the kind of event you're trying to catch. For
example, many standard components don't pass through mouse events, so the AWT can't generate Event objects for them. Can you use

Prof. Marcellin NKENLIFACK, mars 2013 88


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Annexe
another event type, such as ACTION_EVENT (handled by the action() method), instead? If not, you might be forced to implement a
Canvas subclass (or a Panel or Applet subclass) so that you can see all the events that occur.
* Problem: My application doesn't get a WINDOW_DESTROY event, so I can't close my window (or quit the application or
whatever)!
•In a Frame subclass, implement handleEvent() so that it reacts to the the WINDOW_DESTROY event. You can't catch
WINDOW_DESTROY events in a Panel subclass, for example, since the Frame is above it in the component hierarchy. To quit, use
System.exit(). To destroy the window, you can call dispose() or you can just hide() the Frame and, if you're not going to use it again,
make sure that all references to it are set to null.
* Problem: All your examples are of applets. How do I apply them to applications?
•Except where noted, anywhere in this trail that you see a subclass of the Applet class, you can substitute a subclass of the Panel class or,
if the subclass isn't used as a container, a subclass of the Canvas class. In general, it's easy to convert an applet into an application, as
long as the applet doesn't rely on any special applet abilities (such as using methods defined in the Applet class).
To convert an applet into an application, you need to add a main() method that creates an instance of a Frame subclass, creates an
instance of the Applet (or Panel or Canvas) subclass, adds the instance to the Frame, and then calls the init() and start() methods of the
instance. The Frame subclass should have a handleEvent() implementation that handles WINDOW_DESTROY events in the appropriate
way.
See AnimatorApplet.java and AnimatorApplication.java for examples of an applet and an application that implement the same
functionality.
* Problem: Whenever I execute a Java application with a GUI, I get this annoying error message:
Warning:
Cannot allocate colormap entry for default background
This message occurs only on Motif systems. It occurs when the Motif library is initialized and finds that there's no room in the default
colormap to allocate its GUI colors. The solution is to run fewer "colormap hogging" applications on your desktop. The Java runtime
adapts itself to whatever colors are in the default palette, but the Motif library is less forgiving.

7.4 COMMON LAYOUT PROBLEMS (AND THEIR SOLUTIONS)


* Problem: How do I specify a component's exact size?
•First, make sure that you really need to set the component's exact size. The standard components have different sizes, depending on the
platform they're running on and the font they use, so it usually doesn't make sense to specify their exact size.
For custom components whose contents do not change size (such as images), specifying the exact size makes sense. For custom
components, you need to override the Component getMinimumSize and getPreferredSize methods to return the correct size of the
component. You can also override the getMaximumSize method to return the largest reasonable size of the component. Next, be sure that
your component's container uses a layout manager that respects the specified size of the component.
To change the size of a component that's already been displayed, see the next problem.

Note: All component sizes are subject to layout manager approval. The FlowLayout and GridBagLayout layout managers use the
component's natural size (the latter depending on the constraints that you set), but BorderLayout and GridLayout usually don't. Other
options are writing or finding a custom layout manager or using absolute positioning.
* Problem: How do I resize a component?
•Once a component has been displayed, you can change its size using the Component setSize method. You then need to call the validate
method on the component's container to make sure the container is laid out again.
* Problem: My custom component is being sized too small.
•Does the component implement the getPreferredSize and getMinimumSize methods? If so, do they return the right values? •Are you
using a layout manager that can use as much space as is available? See General Rules for Using Layout Managers for some tips on
choosing a layout manager and specifying that it use the maximum available space for a particular component.

7.5 COMMON GRAPHICS PROBLEMS (AND THEIR SOLUTIONS)


* Problem: I don't know where to put my drawing code.
•Drawing code belongs in the paint() method of a custom component. You can create a custom component by creating a subclass of the
Canvas, Panel, or Applet class. See How to Use Canvases<Image: (in the Creating a User Interface trail)> for information on
implementing a custom component. For efficiency, once you have your drawing code working, you can modify it to go in the update()
method (although you must still implement paint()), as described in Eliminating Flashing.
* Problem: The stuff I draw doesn't show up.
•Check whether your component is showing up at all. Common Component Problems<Image: (in the Creating a User Interface trail)>
should help you with this.
* Problem: I'm using the exact same code as a tutorial example, but it doesn't work. Why?
•Is the code executed in the exact same method as the tutorial example? For example, if the tutorial example has the code in the
example's paint() or update() method, then those two methods might be the only places where the code is guaranteed to work.
* Problem: How do I draw thick lines? patterns?
•The AWT's API for primitive graphics is currently rather limited. For example, it supports only one line width. You can simulate thick
lines by drawing multiple times at one-pixel offsets or by drawing filled rectangles. Also, the AWT doesn't currently support fill or line
pattern.

Prof. Marcellin NKENLIFACK, mars 2013 89


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliographie

Ouvrages
• [RoquesVallee01] Pascal Roques & Franck Vallée, « UML en action: de l’analyse des besoins à la conception en Java », Edition
Eyrolles, Paris, 3ème tirage, 2001, 385 pages, ISBN: 2-212-09127-3
• [Fowler03] Martin FOWLER, UML Distilled: A Brief Guide to the Standard Object Modeling Language, Paperback: 192
pages, Publisher: Addison-Wesley Professional; 3 edition (September 19, 2003), Language: English, ISBN:
0321193687
http://martinfowler.com/books.html#uml
• [Warmer99] J. Warmer, A. Kleppe, “The Object Constraint Language: Precise Modeling with UML”, Addison-Wesley,
1999.
• [Booch 88] Grady Booch. « Ingenierie du logiciel avec le langage ADA. » inter Edition 1988.
• [Booch91] Grady Booch,"Object oriented design with application." The benjamin/commings publishing company Inc ,
1991
• [Bouzegoub94] Bouzegoub M. "The functional Query language Morse." Proc of Trends & Application on Databases, IEE,
Gaithersburg, MD, USA 1984
• [Bouzegoub97] Mokrane BOUZEGOUB, Georges GARDARIN, Patrick VALDURIEZ. "Les Objets" édition Eyrolles 1997.
• [Coad91a] Coad P., Yourdon E. "Object oriented analysis, second edition" Yourdon Press, Prentice-Hall, Inc. 1991
• [Coad91b] Coad P., Yourdon E. "Object oriented Design" Yourdon Press, Prentice-Hall, Inc. 1991
• [Coleman94] Coleman D., Arnold P., Bodoff S. "Object oriented Development: The FUSION method" Prentice-Hall,
Englewood cliffs, NJ,1994
• [Delannoy 01] Claude DELANNOY, « Programmer en Java », Eyrolles, 2001.
• [Delatte93] Delatte B., Heitz M., Muller J.F. "HOOD reference manual 3." Edition Masson 1993.
• [Dorseuil 95] A.DORSEUIL & P.PILLOT. « Le temps réel en milieu industriel: concepts, environnements, multitâches.»
Edition Dunod 1995
• [Gardarin97] Goerges et Olivier GARDARIN. "Le Client-Serveur", édition Eyrolles 1997.
• [Gaudel96] Marie Claude GAUDEL, Bruno MARRE, Françoise SCHLIENGER, Gilles BERNOT. "Précis de Génie
logiciel" Edition Masson 1996.
• [Hirsh 90] ERNEST HIRSH. « Les Transputers. » edition Eyrolles 1990.
• [Jacobson 92] Jacobson I., Christerson M., Jonson P., Övergaard G. "Object oriented software engeneering: A use case driven
approach" Addison-wesley, 1992
• [Leray92] J. LERAY. "Les bases de l'informatique industrielle" Dunod 1992
• [Manhes98] Stéphane MANHES, B. DANO. « La réutilisabilité : Patterns et Frameworks » rapprot complet : « les
patterns métiers : extraction dans l’existant logiciel » rapport de DEA, IRIN, Université de Nantes, sept 1998
• [Nkenlif 99] Marcellin NKENLIFACK, «Spécifications orientées objets de circuits électroniques » Mémoire de fin de 1ère
année doctorat, ENSP, Université de Yaoundé I, Cameroun. 1999.
• [Raise92] The RAISE Language Group "The RAISE Specification Language" . Prentice-Hall International 1992
• [Raise95] The RAISE Method Group "The RAISE Development Method" . Prentice-Hall International 1995
• [Rumbaugh91] Rumbaugh J., Blaha M., Premerlani W., Eddy F. "Object oriented modeling and design." Prentice Hall
International, 1991.
• [Shlaer92] Shlaer S., Mellor S.J. "Object life cycle: Modeling the world in state" Yourdon Press, Prentice-Hall, 1998

Articles
• [Ashenden99] Peter J. ASHENDEN (The university of Adélaïde), «The overview of SUAVE language feature » FDL 1999,
Lyon, France.
• [AshRad99] Peter J. ASHENDEN (The university of Adélaïde), Martin RADETZKI (Oldenburg University). «A
comparison of SUAVE and Objective VHDL » Report for the IEEE-DASC-OOVHDL study group. FDL 1999,
Lyon, France.
• [Nebel98] Wolfgang NEBEL, Martin RADETZKI, Wolfram PUTZKE. « Reuse and Quality estimation : Objective
VHDL language definition » REQUEST/OFFI/D2.1A/01.2. – 09/07/1998
• [Nebel99] Wolfgang NEBEL, Martin RADETZKI, Wolfram PUTZKE. « Reuse and Quality estimation : Demo release
Objective VHDL User’s Manual » REQUEST/OFFI/DEMO/01.1 – 18/01/1999.
• [Otter-H4028] Martine OTTER, « Qualité des logiciel.» article paru dans les techniques de l’ingénieur, Doc H4028
• [Printz-H3208] Jacques PRINTZ, « Génie logiciel » article paru dans les techniques de l’ingénieur, Doc H3208
• [Rollan-H3248] Colette ROLLAND «Conception de bases de données: une méthode orientée objet et événement» article paru
dans les techniques de l’ingénieur, Doc H3248

Sites Internet des Laboratoires de recherche ou possédant des articles


• [wwwJavaMem] http://www.u-picardie.fr/~ferment/java/sommaire.html
Site Web contenant un aide-mémoire des concepts clés du langage JAVA. Consulté le 10-11-07
• [wwwFerber07] http://www.lirmm.fr/~ferber/Java/Introduction_java.ppt.pdf
Jacques Ferber, Introduction aux objets et à Java, LIRMM, France, 2007
• [wwwJavaWiki] http://fr.wikipedia.org/wiki/
site Web présentant les concepts du langage Java. / Consulté le 08-03-09
• [wwwJavaCodes] http://www-igm.univ-mlv.fr/%7Eroussel/vuibert.old/
site Web contenant un ensemble de codes exemples (démonstration) illustrant l’utilisation des classes de la
plateforme Java. Consulté le 10-11-08
• [wwwSWT06] http://www.jmdoudoux.fr/java/dej/chap015.htm
les technologies Java et les composants SWT
consulté le 20-11-06
• [wwwJDBC09] http://www.ac-creteil.fr/util/programmation/java/Welcome.html

Prof. Marcellin NKENLIFACK, mars 2013 90


UDS // IUT FV de Bandjoun // Département d’Informatique 
Développement Orienté Objet / JAVA
Bibliographie
les technologies Java et l’accès aux BD Via l’API JDBC
consulté le 10-09-09
• [wwwSwing06] http://java.sun.com/docs/books/tutorial/uiswing/learn/example2.html#lookandfeel
Les technologies SWING et le Look-andFeel
consulté le 10-09-06
• [wwwJDBCDriver0 http://industry.java.sun.com/products/jdbc/drivers
6] Liste des pilotes d’accès aux BD Via JDBC.
Consulté le 20-11-06
• [wwwPatterns] //www.hillside.net/patterns
Informations actualisées sur l’état de l’art relatif aux Patterns (modèles) / Consulté le 08-09-06
• [LOBJETW] //www.sciences.univ-nantes.fr/info/recherche/mgl/LOBJET/index.html
le site de la revue "l'Objet" / consulté le 15-05-03
• [ObjetsWa] //stm.tj/objet/
les technologies objets + d'autres liens / consulté le 15-05-03
• [ObjetsWb] //www.stm.tj
les technologies objets + d'autres liens / consulté le 18-07-03
• [ObjetsWc] //pages.infinit.net/map/OO.html
les objets / consulté le 24-06-02
• [OOVHDLW] //www.eda.org/oovhdl/
le site du VHDL Orienté Objet / consulté le 17-01-00
• [OutilsW] //atomoptic.iota.u-psud.fr/francais/electronic/froutils.htm
quelques outils utilisés dans la conception et la réalisation de circuits / consulté le 12-09-02
• [Thierry99W] //www-rocq.inria.fr/~sorel/work/fond99.html
Méthodes d'adéquation algorithmes-architectures / consulté le 30-12-99
• [wwwGeneal01] www.irisa.fr/prive/jezequel/enseignement/ao-et-uml.pdf
Méthodes objets, génie logiciel et UML : généalogie / consulté le 30-12-2004
• [WWWJME06] http://defaut.developpez.com/tutoriel/java/j2me/
Concepts sur les Technologies de J2ME / consulté le 20-11-2006
• [wwwSolProb] http://www.science.uva.nl/ict/ossdocs/java/tutorial/getStarted/problems/index.html
Problèmes courants de programmation en Java et solutions / consulté le 10-05-2004
• [wwwMDA06] http://www.mdsd.info/
Processus logiciel basé sur MDA / consulté le 02-12-2006
• [wwwMDASup] http://pparrend.developpez.com/mda-intro/#LIV-A-1
Présentation de MDA / consulté le 02-12-2006

Prof. Marcellin NKENLIFACK, mars 2013 91

Vous aimerez peut-être aussi