L'Altruiste : Le guide des langages Web

Le langage Java

Sommaire
24.2.6/Divers
24.4.1.1/Les règles
33.9.5/Exemple
33.10.1/Exemple
35.1.1.1/Les attributs

1 / Introduction

Java est un langage de programmation créé en 1995 par Sun Microsystems suite aux recherches, débutées en 1990, sur un projet d'environnement indépendant du couple système d'exploitation et matériel.

Profitant de la rapide progression de l'Internet et du facteur inhibiteur que constituait l'hétérogénéité des plateformes dans le secteur, le langage Java s'imposa en acteur incontournable dans la mesure ou il permit d'harmoniser le développement sur le World Wide Web et tous ses dérivées comme les intranet ou les extranet.

De plus, la politique de Sun Microsystems a favorisé l'expansion fulgurante de Java, en fournissant gratuitement les environnements de développement, les fameux JDK (Java Development Kit) et SDK (Software Development Kit) et surtout en favorisant l'octroi de licences d'utilisation à la plupart des intervenants majeurs de l'Internet, tels que Netscape, Microsoft ou encore Opera.

Le but de ce nouveau langage de programmation étant de créer des applications fonctionnant sur des réseaux en architecture client/serveur, nécessite, néanmoins, l'installation préalable d'un environnement applicatif, le JDK , sur un serveur ou sur une station de travail.

La portabilité du langage Java résulte du fait que le code source d'un programme est compilé pour produire un pseudo-code (ou byte-code) contenu dans un fichier classe portant l'extension .class. Ensuite, lors de la phase d'interprétation par la Machine Virtuelle Java (JVM : Java Virtual Machine), ce fichier est soumis à l'éditeur de liaison (linker) afin d'assurer la compatiblité avec le système d'exploitation hôte et mis en relation avec la bibliothèque de classes Java pour finalement être exécuté par la machine cliente. La JVM, l'éditeur de liaison, et la bibliothèques de classes sont des composants de l'environnement d'exécution Java (JRE : Java Runtime Environment) devant être installée sur la plateforme cliente.
Cette faculté d'adaptation permet, donc, à un programme Java de pouvoir être implémenter sur toutes les plateformes comme les ordinateurs personnels équipés de Microsoft Windows ou de Linux, sur des stations de travail Unix ou encore sur des PDA (Personal Digital Assistant), ou encore sur la prochaîne génération de téléphones portables et à condition que le JRE ait été installé au préalable.

Java est un langage orienté objet, c'est-à-dire qu'il possède la faculté, à l'image du C++ ou du Visual Basic, de manipuler des objets ou plus précisément des instances de classes, définies dans les différents package accompagnant un SDK (Software Development Kit).

La fiabilité d'un programme Java tient au fait que certaines fonctionnalités ont été expurgées afin d'éviter certaines erreurs systèmes récurrentes dans la programmation à partir du C++ notamment.
Par exemple, l'allocation de mémoire par des pointeurs a été purement et simplement abandonnée, la gestion de la mémoire étant, désormais, assurée automatiquement par Java.
De cette manière, on évite également, toutes manipulations nuisibles de la mémoire.

D'ailleurs, l'interprétation d'un programme Java fait appel à plusieurs caractéristiques spécifiques et complexes de Java qui se complémentant, assurent aux utilisateurs, une sécurité quasi-absolue. Autrement dit, des programmeurs malveillants ne peuvent s'appuyer sur le langage Java pour concevoir et inoculer des virus sur des stations clientes ou des serveurs d'un réseau.

Non seulement, l'universalité de Java fait de ce langage un support efficace pour tous types d'applications à l'instar du C, mais en plus, dépassant sa mission initiale, le langage Java tend à devenir le fondement d'un nouveau modèle d'architecture des systèmes d'information.

De nombreux éditeurs spécialisés appelés Environnement de Développement Intégré (IDE : Integrated Development Environment), intégrant un compilateur, un débogueur, ainsi qu'une vaste panoplie d'assistants, permettent de créer de puissantes applications Java, en outre, il est également possible d'utiliser notepad ou n'importe quel éditeur de texte pour écrire ses propres programmes Java puis de les compiler (javac.exe) et de les exécuter (java.exe) avec le J2SDK de Sun Microsystems.

2 / Configuration des outils Java

La plateforme Java comprend un certain nombre d'outils dont en particulier le compilateur (javac.exe), la machine virtuelle (java.exe) et le générateur de documentation (javadoc.exe).

Avant de commencer à écrire une seule ligne de code Java, il est nécessaire de connaître certains éléments fondamentaux.

Pour une quelconque opération sur un fichier source Java (NomFichier.java) ou un fichier classe (NomFichier.class), il est nécessaire d'indiquer au système d'exploitation et à fortiori aux applications d'environnement de développement intégré (EDI) où se trouve les différents outils Java.

Le lancement de n'importe lequel des outils nécessite l'apport d'au moins, un élément relativement important. Il s'agît de la variable d'environnement PATH déclarant la localisation des fichiers binaires exécutables du Java 2 SDK.

Sous DOS (cmd.exe)
C:\>path /?
Affiche ou définit un chemin de recherche des fichiers exécutables.

PATH [[lecteur:]chemin[;...][;%PATH%]
PATH ;

Entrez PATH ; pour effacer les chemins de recherche et indiquer à cmd.exe
de ne chercher que dans le répertoire en cours.
Entrez PATH sans paramètres pour afficher le chemin de recherche en cours.
L'ajout de %PATH% dans le paramètre du nouveau chemin permet d'ajouter
celui-ci à l'ancien chemin de recherche.

C:\>path Validez

PATH=C:\j2sdk1.4.1\bin;C:\WINNT\system32;C:\WINNT

Si le répertoire d'installation des fichiers binaires du kit logiciel de développement Java 2 (Java 2 SDK) n'existe pas, alors dans le but d'éviter certains désagréments, il faudra ajouter ce chemin au PATH.

Ajout du chemin
Sous DOS
C:\>path=C:\j2sdk1.4.1\bin;%PATH% Validez

Sous Linux
setenv PATH chemin/j2sdk1.4.1 Validez
ou
PATH = chemin/j2sdk1.4.1
export PATH

De cette manière, chaque fichier exécutable sera directement accessible de n'importe quel répertoire dans la session DOS en cours. Pour conserver ce paramétrage, il suffit de modifier la variable système Path à partir des variables d'environnement des propriétés systèmes (Clic droit sur le Poste de travail -> Propriétés).

Propriétés systèmes, variable d'environement, Path

Le compilateur et la machine virtuelle ont besoin d'un argument fondamental, pour respectivement, construire un fichier classe à partir du source et des éventuelles autres classes importées et lancer une application Java à partir du répertoire contenant les classes appelées.

C:\>javac /? Validez
javac: invalid flag: /~
Usage: javac <options> <source files>
where possible options include:
  -g                        Generate all debugging info
  -g:none                   Generate no debugging info
  -g:{lines,vars,source}    Generate only some debugging info
  -nowarn                   Generate no warnings
  -verbose                  Output messages about what the compiler is doing
  -deprecation              Output source locations where deprecated APIs are us
ed
  -classpath <path>         Specify where to find user class files
  -sourcepath <path>        Specify where to find input source files
  -bootclasspath <path>     Override location of bootstrap class files
  -extdirs <dirs>           Override location of installed extensions
  -d <directory>            Specify where to place generated class files
  -encoding <encoding>      Specify character encoding used by source files
  -source <release>         Provide source compatibility with specified release
  -target <release>         Generate class files for specific VM version
  -help                     Print a synopsis of standard options
  

C:\>java -help Validez
Usage: java [-options] class [args...]
           (to execute a class)
   or  java -jar [-options] jarfile [args...]
           (to execute a jar file)

where options include:
    -client       to select the "client" VM
    -server       to select the "server" VM
    -hotspot      is a synonym for the "client" VM  [deprecated]
                  The default VM is client.

    -cp -classpath <directories and zip/jar files separated by ;>
                  set search path for application classes and resources
    -D<name>=<value>
                  set a system property
    -verbose[:class|gc|jni]
                  enable verbose output
    -version      print product version and exit
    -showversion  print product version and continue
    -? -help      print this help message
    -X            print help on non-standard options
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  enable assertions
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  disable assertions
    -esa | -enablesystemassertions
                  enable system assertions
    -dsa | -disablesystemassertions
                  disable system assertions

Les commandes javac et java possèdent tous les deux, un argument appelé -classpath <chemin vers les classes> permettant de diriger le compilateur ou la machine virtuelle vers le répertoire de classes adéquat.

Compilation du source FichierClasse.java
javac -classpath c:\travail\classes -d c:\travail\classes FichierClasse.java

Dans ce premier cas, le compilateur recherche dans le répertoire spécifiée par -classpath les classes à importer dans le fichier source Java. D'autre part, l'argument -d fournit une destination vers un répertoire, pour le fichier classe généré à partir de cette instruction.

Exécution du fichier classe FichierClasse.class
java -classpath c:\travail\classes FichierClasse

Dans ce second cas, la machine virtuelle tente de lancer un fichier classe à partir de son identificateur (FichierClasse) et de son chemin (c:\travail\classes).

La variable ClassPath indique donc à ces outils la localisation des classes à utiliser. Si cette variable n'est pas renseignée, des classes importées risquent de ne pas être trouvées par les outils Java, et partant, le traitement échouera.

Sous Linux, il faudra créer une variable d'environnement CLASSPATH à l'aide de la commande setenv ou export.

% setenv CLASSPATH chemin/classe:...:chemin/classeN Validez


CLASSPATH = chemin/classe:...:chemin/classeN
export CLASSPATH

La plupart des EDI Java proposent dans leur configuration, différents moyens permettant de régler correctement les variables PATH et CLASSPATH.

En ce qui concerne, le générateur de documentation (javadoc.exe), à l'image du compilateur, peut recevoir un argument de destination (-d <répertoire>) pour les fichiers HTML générés.

javadoc -d c:\travail\docs FichierSource.java

L'installation de cet outil s'effectue assez simplement dans un EDI, en passant en général par les options de configuration. Ces dernières permettent l'intégration d'utilitaires Java avec leurs arguments et leur chemin.

D'autres notions sont nécessaires afin de parvenir à tirer pleinement parti de son environnement de développement. L'espace de travail (workspace) est un conteneur de projets, lesquels contiennent les fichiers sources Java.

Workspace, espace de travail, projet, project

Développer avec un EDI contraint à s'imposer une certaine organisation en l'occurrence, de toujours travailler au sein d'un projet lequel peut être englobé dans un espace de travail.

3 / La structure syntaxique

La syntaxe définit des règles d'écritures sans lesquelles un programme Java ne pourrait fonctionner correctement.

La syntaxe du langage Java s'appuie sur le modèle du C ou du C++.

3.1 / Les caractères

Les programmes Java sont écrits dans le jeu de caractères Unicode.

Néanmoins, les traductions lexicales sont fournies pour que les échappements Unicode soient utiisés pour inclure n'importe quel caractère utilisant seulement les caractères ASCII. Les fins de ligne sont définies afin de supporter une compatibilité avec les différentes normes des systèmes hôtes existants.

Les caractères Unicode résultant d'une traduction lexicale sont réduits à une séquence d'éléments d'entrées, lesquels sont des espaces blancs, des commentaires et des symboles tels que des identificateurs, des mots clés, des littéraux, des séparateurs et des opérateurs de la syntaxe Java.

Le caractère d'échappement antislash '' permet de traduire le code hexadécimal d'un caractère Unicode.

u{Code hexadécimal}

uXXXX

u0061 // correspond à 'a'

u0035 // correspond à '5'

Les espaces blancs sont les caractères ASCII SP (SPace), HT (Horizontal Tabulation), FF (Form Feed) et les caractères de fin de ligne, permettent lors d'une traduction lexicale de décomposer la séquence en plusieurs symboles.

public int x=0, y=0;

public{SP}int{SP}x=0,{SP}y=0;{CRLF}

/* mot clé : 'public'
  identificateurs : 'int', 'x' et 'y'
  opérateurs : '='
  littéraux : '0'
  séparateurs : ',' et ';' */

Les lignes sont terminées par une séquence de deux caractères ASCII, CR (Carriage Return) et LF (Line Feed).

3.2 / Les identificateurs Java

Les identificateurs Java sont des séquences de lettres et de chiffres représentant des variables, des constantes, des méthodes, des classes, des interfaces ainsi que des labels.

Toutefois, un identificateur ne peut commencer que par une lettre Java, un caractère de soulignement _ ou un signe dollar $ et contenir des caractères alphanumériques ainsi que des symboles monétaires.

CONSTANTE

_erreur

W_800
H_600

$monnaie

Evidemment, l'identificateur ne doit pas contenir d'espaces blancs (espace, tabulation, saut de ligne etc.), de caractères de ponctuation (point, deux-points, point-virgule, virgule, etc.) ou de tout autres caractères symboliques.

Les lettres Java
Lettres Codes Unicode
a-z \u0061-\u007a
A-Z \u0041-\u005a
_ \u005f
$ \u0024
Les chiffres Java
Lettres Codes Unicode
0-9 \u0030-\u0039

Les identificateurs ne peuvent avoir la même orthographe que les mots clés, les littéraux prédéfinis, c'est-àdire les valeurs booléennes true et false et la valeur null.

Les mots clés
Les mots clés
abstract
boolean
break
byte
case
catch
char
class
const
continue
default
do
double
else
extends
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
throw
throws
transient
try
void
volatile
while

3.3 / Les littéraux

Les littéraux représentent les valeurs des variables ou des constantes, soit des séquences de caractères digitaux pour les nombres ou n'importe quel caractères alphabétiques, numériques ou de ponctuation pour les chaînes de caractères.

nom_variable = {valeur_littérale};

temp = null;

hauteur_ecran = 600;

prix_produit_x_100 = 159.95;

reussite_operation = true;

designation_produit = 'Cartouche d'encre noire pour imprimante';

Les littéraux textuels doivent être encadrés par des guillemets doubles ou simples, tandis que les valeurs numériques, booléennes ou nulles, n'en ont guère besoin.

Les littéraux entiers peuvent être exprimés en base décimale (0-9), octale (0-7) ou hexadécimale (0-9A-F). Les valeurs octales doivent commencer par un zéro et les valeurs hexadécimales par 0X ou 0x. Les littéraux entiers longs doivent se terminer par un caractère L ou l, le premier étant préféré pour une meilleure lisibilité.

145 //littéral entier décimal
0777 //littéral entier octal
0xFF00FF //littéral entier hexadécimal

16359489123696L

Les littéraux à virgule flottante se caractérisent par deux parties distinctes séparées par un point. La composante décimale se situe à gauche du point, tandis que la composante fractionnaire est à droite. Les valeurs doubles et flottantes (float) se distinguent respectivement par les caractères D ou d et F ou f placés à la fin du nombre. Un caractère E ou e indique un exposant signé représentant la puissance 10 à appliquer au nombre situé à sa gauche.

11.58 //littéral à virgule flottante

648.965148F // littéral flottant 

0.06598E+16 // littéral double avec exposant positif 0.06598*1016

.485e-28F // littéral flottant avec exposant négatif 0.485*10-28

0D // littéral double

Les littéraux booléens représentent les valeurs de bit 0 ou 1 symbolisées par les séquences de caractères true et false.

debut = true;

fin = false;

Les littéraux caractères sont des valeurs ne contenant qu'un unique caractère exprimé normalement, sous sa forme Unicode ou au moyen du caractère d'échappement .

'z' // littéral caractère

'\u0051' // littéral avec valeur Unicode

'\t' // littéral avec valeur d'échappement

Le littéral Unicode doit toujours possèder un caractère u minuscule.

'\uXXXX'

Les séquences d'échappement permettent d'inclure des caractères spéciaux dans des littéraux caractères et chaînes.

Caractère Valeur Unicode Description
 \u0008 effacement en arrière BS (backspace)
\t \u0009 tabulation horizontale HT (horizontal tab)
\n \u000a fin de ligne LF (line feed)
\f \u000c saut de page FF (form feed)
\r \u000d retour chariot CR (carriage return)
" \u0022 guillemet double "
' \u0027 guillemet simple '
\ \u005c anti-slash
\uXXXX \u0000 - \u00ff valeur hexadécimale

Les littéraux chaînes de caractères sont des combinaisons de zéro à plusieurs caractères compatibles à Unicode. Les séquences d'échappement sont également permises dans de tels littéraux. Les chaînes de caractères peuvent être fractionnées sur plusieurs lignes en ajoutant un signe plus (+) au début de chacune des parties.

"Une chaîne" // littéral chaîne

"" // chaîne vide

// littéral chaîne sur deux lignes
"\tS'il\u0020avait\u0020pu\u0020l'obtenir,\u0020nous"
+ "\u0020aurions\u0020été\u0020siu0020heureux\u0020!"

'

Le littéral null représente un type spécial symbolisé par une séquence de caractères null.

nb_achat = null;
nom_variable = {valeur_littérale};

temp = null;

hauteur_ecran = 600;

prix_produit_x_100 = 159.95;

reussite_operation = true;

designation_produit = 'Cartouche d'encre noire pour imprimante';

Les littéraux textuels doivent être encadrés par des guillemets doubles ou simples, tandis que les valeurs numériques, booléennes ou nulles, n'en ont guère besoin.

Les littéraux entiers peuvent être exprimés en base décimale (0-9), octale (0-7) ou hexadécimale (0-9A-F). Les valeurs octales doivent commencer par un zéro et les valeurs hexadécimales par 0X ou 0x. Les littéraux entiers longs doivent se terminer par un caractère L ou l, le premier étant préféré pour une meilleure lisibilité.

145 //littéral entier décimal
0777 //littéral entier octal
0xFF00FF //littéral entier hexadécimal

16359489123696L

Les littéraux à virgule flottante se caractérisent par deux parties distinctes séparées par un point. La composante décimale se situe à gauche du point, tandis que la composante fractionnaire est à droite. Les valeurs doubles et flottantes (float) se distinguent respectivement par les caractères D ou d et F ou f placés à la fin du nombre. Un caractère E ou e indique un exposant signé représentant la puissance 10 à appliquer au nombre situé à sa gauche.

11.58 //littéral à virgule flottante

648.965148F // littéral flottant 

0.06598E+16 // littéral double avec exposant positif 0.06598*1016

.485e-28F // littéral flottant avec exposant négatif 0.485*1028

0D // littéral double

Les littéraux booléens représentent les valeurs de bit 0 ou 1 symbolisées par les séquences de caractères true et false.

debut = true;

fin = false;

Les littéraux caractères sont des valeurs ne contenant qu'un unique caractère exprimé normalement, sous sa forme Unicode ou au moyen du caractère d'échappement .

'z' // littéral caractère

"\u0051" // littéral avec valeur Unicode

"\t" // littéral avec valeur d'échappement

Le littéral Unicode doit toujours possèder un caractère u minuscule.

'\uXXXX'

Les séquences d'échappement permettent d'inclure des caractères spéciaux dans des littéraux caractères et chaînes.

Caractère Valeur Unicode Description
 u0008 effacement en arrière BS (backspace)
\t u0009 tabulation horizontale HT (horizontal tab)
\n u000a fin de ligne LF (line feed)
f u000c saut de page FF (form feed)
\r u000d retour chariot CR (carriage return)
" u0022 guillemet double "
´ u0027 guillemet simple '
\ u005c anti-slash
uXXXX u0000 - u00ff valeur hexadécimale

Les littéraux chaînes de caractères sont des combinaisons de zéro à plusieurs caractères compatibles à Unicode. Les séquences d'échappement sont également permises dans de tels littéraux. Les chaînes de caractères peuvent être fractionnées sur plusieurs lignes en ajoutant un signe plus (+) au début de chacune des parties.

"Un chaîne" // littéral chaîne

"" // chaîne vide

// littéral chaîne sur deux lignes
"S'il\u0020avait\u0020pu\u0020l'obtenir,\u0020nous"
+ "\u0020aurions\u0020été\u0020si\u0020heureux\u0020!"

Le littéral null représente un type spécial symbolisé par une séquence de caractères null.

nb_achat = null;

3.4 / Les caractères de séparation

Plusieurs caractères spéciaux sont utilisés comme séparateur conformément aux spécifications grammaticales du langage Java.

Caractères Description
( ) Les paranthèses sont très largement utilisées, notamment dans des expressions complexes, dans des appels de fonction, ainsi que pour accueillir des expressions dans des instructions conditionnelles, itératives, etc..
{ } Les accolades sont utilisées comme délimiteurs de bloc d'instructions à l'image de celui d'une fonction, d'une classe, de boucles, etc..
[ ] Les crochets sont utilisés pour accueillir les index de tableaux ou encore pour les expressions régulières.
; Le point-virgule permet de terminer une instruction ou bien de séparer des expressions dans une boucle for.
, La virgule est utilisée comme séparateur de valeurs pour les tableaux ou encore pour lister les arguments (appel de la méthode) ou paramètres (déclaration de la méthode) pour les fonctions.
. Le point est utilisé comme séparateur décimal, entre un objet et sa méthode ou sa propriété, etc..
: Le deux-points est utilisé pour débuter un bloc d'instructions dans une commande switch case par exemple.

3.5 / Les expressions

Une expression peut être n'importe quel ensemble valide de littéraux, de variables, d'opérateurs, d'instructions Java et d'autres expressions, qui correspond à une valeur simple.

int i = 0;

i += 5;

String texte = "L'agneau sortit de l'étable alors 
                            que le loup embusqué l'attendait.";

double valeur3 = Math.max(valeur2, Math.pow(valeur1, 10));

String resultat = texte.toLowerCase();

Cette valeur peut être un nombre (42), une chaîne de caractères (olivier), ou encore une valeur logique (true ou false).

Conceptuellement, il y a deux types d'expressions : celles qui assignent une valeur à une variable, et celles qui ont simplement une valeur.

Par exemple, l'expression i = 0 est une expression qui affecte à i la valeur zéro. Cette expression elle-même correspond à zéro.

La plupart des expressions font appel à divers opérateurs pour effectuer des affectations, des calculs arithmétiques ou encore des concaténations.

Ainsi, à partir d'expressions basiques, il est possible de construire des expressions extrêmenent complexes retournant toujours une valeur.

if(x == 1 && y == 0)
    // instructions...

if(x > y || x < 100)
    //instructions...

String ch = x < y ? "x < y" : "x > y";

Une expression est toujours typée, c'est-à-dire, que la valeur résultante possède un certain type primitif, à l'image des valeurs numériques ou un type composite pour notamment les chaînes de caractères.

Les expressions sont la plupart du temps évaluées de la gauche vers la droite et parfois certains membres ne sont pas évalués du tout, dans le cas des opérations logiques avec un OU (||), un ET (&&) ou l'opérateur ternaire (?:).

En outre, une expression suivie du séparateur point-virgule (;) devient une instruction.

3.6 / Les instructions

Les instructions sont des suites de composants Java (les identificateurs, les mots-clefs, les constantes, les opérateurs) terminées par un point-virgule.

System.out.println("Un texte...");

int une_variable = 10, une_autre_variable = 15;

Une ou plusieurs instructions peuvent être rassemblées par des accolades ({...}) pour former une instruction composée ou plus communément, un bloc d'instructions.

if(i < 0) {
  message = "Attention, i ne peut pas être négatif !"; 
  System.out.println(message); 
}

Un bloc d'instruction agît syntaxiquement parlant, comme une seule instruction.

En outre, une instruction composée d'un spécificateur de type, éventuellement précédé de modificateurs d'accès, suivi d'un identificateur et éventuellement d'une affectation et enfin terminé par un point-virgule, s'appelle une déclaration de variable.

3.7 / Les commentaires

Les commentaires permettent de rendre votre code lisible et surtout d'en faciliter ultérieurement la maintenance.

En général, l'insertion de commentaire se fait soit en fin de ligne, soit sur une nouvelle ligne mais en aucun cas au sein d'une ligne de commande.

Il existe deux méthodes permettant d'intégrer des commentaires aux programmes Java.

La première consiste à placer un double slash (//) devant le texte comme dans l'exemple ci-dessous :

image = "fond.gif"; //image de fond

if (x = 2) //redirection vers la seconde page
{
  url = ("page2.html");
}
else
{ //sinon retourne à la page d'accueil
  url = ("accueil.html");
}

La seconde solution est d'encadrer le texte par un slash suivi d'une étoile (/*) et la même séquence inversée (*/) comme le montre l'exemple suivant :

/*Voici un commentaire*/
/*
Encore un autre commentaire
*/
/*Ce commentaire est
écrit sur deux lignes*/

Les programmes Java acceptent également des commentaires de documentation visualisables par des navigateurs Web.
Ces commentaires peuvent contenir du balisage HTML, ainsi que des balises spéciales commençant par une arobasce (@) permettant de documenter un programme Java sous une forme standard.

/**
* <p>Titre : Programme Java</p>
* <p>Description : Mon premier programme...</p>
* <p>Copyright : Copyright (c) 2002</p>
* <p>Société : Ma société</p>
* @author Marc MOLARDI
* @version 1.0
*/

Ce genre de commentaire permet de créer une documentation HTML à partir du fichier source (fichier.java)en utilisant l'utilitaire javadoc.exe du kit de développement Java.

javadoc -d c:\chemin\doc\ fichier_source.java
Les balises Javadoc
BaliseVersion JDK
Description
@author nom prénom1.0
désigne le nom de l'auteur.
@deprecated description1.0
ajoute un commentaire spécifiant la dépréciation du programme.
@exception nom_classe description1.0
indique les exceptions susceptibles de se lancer lors du programme.
{@link ancre}1.2
insère un lien interne qui pointe vers une ancre du document en cours.
@param nom description1.0
ajoute une description de paramètre à la section "Parameters".
@return description1.0
fournit une description dans la rubrique "Returns" à propos du type retourné et de l'intervalle de valeur permis.
@see référence1.0
ajoute des références documentaires à consulter dans un rubrique "See Also".
@serial description1.2
explique la signification d'un champ dit serializable et la liste de ses valeurs autorisées.
@serialData description1.2
fournit une description des séquences et types de données.
@serialField nom_champ type description1.2
permet de documenter un composant ObjectStreamField.
@since texte1.1
spécifie qu'une caractéristique du programme existe depuis une certaine version du logiciel.
@throws nom_classe description1.2
indique les exceptions susceptibles de se lancer lors du programme.
@version texte1.0
spécifie le numéro de version du programme.

4 / Les opérateurs

Les opérateurs permettent d'accéder, de faire référence ou de manipuler les éléments du langage Java tels que des classes ou des variables.

Le langage Java possède, donc, un jeu complet d'opérateurs permettant de multiples combinaisons d'expressions.

4.1 / Les opérateurs d'affectation

Les opérateurs d'affectation permettent l'assignation d'une valeur à une variable.

variable opérateur valeur;

L'opérateur d'affectation de base est le signe d'égalité (=), qui assigne la valeur de son opérande droit à son opérande gauche. C'est-à-dire, droit = gauche assigne la valeur de gauche à droite.

variable = valeur;

Il est également possible de combiner les opérations d'affectation et de calcul par l'intermédiaire d'un opérateur spécial.

variable op= valeur;
// est équivalent à
variable = variable op valeur;

x += 5; // correspond à x = x + 5;

y /= 2; // correspond à y = y / 2;

La promotion arithmétique assure la compatibilité entre le type de chacune des opérandes, par une conversion au type plus large de l'opérande la plus faible si les types sont compatibles, sinon le compilateur génère une erreur si le transtypage doit être explicite.

Pour une affectation simple et combinée de valeurs primitives numériques, le type de l'opérande de gauche doit être identique ou plus large que celui de l'opérande de droite, sinon une erreur de dépassement de capacité peut se produire lors du temps d'exécution.

type_opeD operandeD;
type_opeG operandeG op= operandeD;
// est équivalent à
type_opeG operandeG op= (type_opeG)operandeD;

class op {
  public static void main(String[] args){
  byte   w = 8;
  int  x = 422;
  float  y = 12.4f;
  double z = 448.3641d;

  System.out.println("1 : " + w + " += " + x + " = " + (w += x));
  System.out.println("2 : " + x + " += " + y + " = " + (x += y));
  System.out.println("3 : " + y + " += " + z + " = " + (y += z));
  System.out.println("4 : " + w + " += " + z + " = " + (w += z));
  System.out.println("5 : " + z + " += " + w + " = " + (z += w));
  System.out.println("6 : " + x + " += " + w + " = " + (x += w));
  }
}
// affiche
1 : 8 += 422 = -82 // erreur
2 : 422 += 12.4 = 434
3 : 12.4 += 448.3641 = 460.7641
4 : -82 += 448.3641 = 110 // erreur
5 : 448.3641 += 110 = 558.3641
6 : 434 += 110 = 544

Pour une affectation d'objets, les types références doivent être compatibles entre eux, sinon le compilateur générera une erreur.

interface Inter { ... }
class SuperClasse implements inter { ... }
class Classe extends SuperClasse { ... }

class Affectation {
  public static void main(String[] args){
  Classe RefObjD = new Classe();
  Classe RefObjG = RefObjD;
  // ou
  SuperClasse RefObjG = RefObjD;
  // est équivalent à
  SuperClasse RefObjG = (SuperClasse)RefObjD;

  Object RefObjO = RefObjG;
  // est équivalent à
  Object RefObjO = (Object)RefObjG;

  Inter RefObjI = RefObjG;
  // est équivalent à
  Inter RefObjI = (Inter)RefObjG;
  }
}
Opérateur Equivalent Description
x = y   y est affecté à x
x += y x = x + y y est additionné à x
x -= y x = x - y y est soustrait de x
x *= y x = x * y x est multiplié par y
x /= y x = x / y x est divisé par y
x %= y x = x % y le reste de x/y est affecté à x
x <<= n x = x << n x décalé à gauche de n bits est affecté à x.
x >>= n x = x >> n x décalé à droite en propageant le bit de signe de n bits est affecté à x.
x >>>= n x = x >>> n x décalé à droite de n bits est affecté à x.
x &= n x = x & y x est comparé binairement selon un ET à Y et est affecté à x.
x |= y x = x | y x est comparé binairement selon un OU à Y et est affecté à x
x ^= y x = x ^ y x est comparé binairement selon un OU INCLUSIF à Y et est affecté à x

4.2 / Les opérateurs de signe

Les opérateurs de signe permettent d'indiquer le signe d'une valeur numérique.

Ces opérateurs se placent toujours à la gauche des opérandes.

{[ + ] | - } opérande

Le signe moins (-) est requis pour spécifier qu'un opérande est négatif.

-opérande

int x = -10;
int y = -x;

Le signe plus (+) est optionnel, puisque par défaut tous les opérandes sont positifs.

+opérande
// est équivalent à
valeur_numérique

+10
// est équivalent à
10

double a = +14.62;
double b = a;

Les opérateurs de signe peuvent être appliqués à un opérande de n'importe quel type primitif (byte, short, char, int, long, float et double) à l'exception des booléens.

4.3 / Les opérateurs arithmétiques

Les opérateurs arithmétiques permettent d'effectuer des calculs mathmétiques.

x = 100;
y = 1024;
z = y - x - 16;

Un opérateur arithmétique possède deux opérandes (des littéraux ou des variables), dont les valeurs sont numériques (entier ou à virgule flottante)et renvoient une valeur numérique.

Les opérateurs arithmétiques standards sont l'addition (+), la soustraction (-), la multiplication (*), et la division (/).

Opérateur Description Exemple
x + y L'opérateur permet d'additionner la valeur x à la valeur y. 5 + 6'retourne 11
x - y L'opérateur permet de soustraire la valeur y de la valeur x. 8 - 10'retourne -2
x * y L'opérateur permet de multiplier la valeur x par la valeur y. 4 * 9 'retourne 36
x / y L'opérateur permet de diviser la valeur x par la valeur y en retournant un nombre à virgule flottante. 4 / 16 'retourne 0.25
x % y L'opérateur modulo retourne le reste de la division x/y. 20 % 3 'retourne 2

Les opérateurs arithmétiques peuvent être utilisés avec n'importe quelle combinaison de type de données numériques.

L'exception ArithmeticException est lancée dans le cas d'une division dont le diviseur est un nombre entier nul et le dividende un entier (byte, short, int ou long) ou d'un entier (idem) modulo par un nombre entier nul.

class Division {
  public static void main(String[] args){
  int x = 10;
  int y = 0;
  float z = 0.0f;

  System.out.println(x / y); // provoque une exception
  System.out.println(x % y); // provoque une exception

  System.out.println(x / z);// affiche Infinity
  System.out.println(x % z);// affiche NaN
  }
}

Le type de résultats peuvent varier en fonction du type de chacune des opérandes d'une opération arithmétiques.

type opérande_gauche;
type opérande_droite;
type resultat = opérande_gauche opérateur opérande_droite;
  char byte short int long float double
char int int int int long float double
byte int int int int long float double
short int int int int long float double
int int int int int long float double
long long long long long long float double
float float float float float float float double
double double double double double double double double

Les opérations arithmétiques sur les nombres entiers restent fiables. Par contre, des calculs simples ,dont les opérandes sont des nombres à virgule flottante, se révèlent parfois très approximatifs.

System.out.println(1.1f - 1.0f);
System.out.println(1.1d - 1.0d);
System.out.println(1.1 + 1.0);
System.out.println(1.1 * 0.5);
System.out.println(1.1 / 2.0);
/* Affichent
0.10000000000000009
0.10000000000000009
2.1
0.55
0.55
*/

Face à ces carences possibles dans les opérations arithmétiques et plus particulièrement la soustraction avec des valeurs float ou double, il faut préférer effectuer ces calculs avec la classe BigDecimal qui propose les méthodes add(), substract(), multiply() et divide().

BigDecimal decimal = new BigDecimal("1.1");
System.out.println(
          decimal.subtract(new BigDecimal("1.0")).doubleValue()); 

BigDecimal decimal = new BigDecimal(1.1);
System.out.println(
          decimal.subtract(new BigDecimal(1.0)).doubleValue());

/* Affichent
0.1
0.10000000000000009
*/

Afin de s'assurer de la précision des résultats, il faut créer des objets BigDecimal avec des chaines de caractères plutôt que des nombres décimaux.

4.4 / Les opérateurs d'incrémentation et de décrémentation

Les opérateurs d'incrémentation et de décrémentation permettent respectivement d'augmenter ou de diminuer de un la variable concernée.

i = 0;
i++; //i = 1
i--; //i = 0

Les opérateurs peuvent se placer avant ou après une variable, provoquant une modification respectivement avant ou après que la variable ne soit utilisée. L'expression contenant ce genre d'opérateurs est toujours évaluée avant l'utilisation de la variable concernée.

class Increment {
  public static void main(String[] args){
  int i = 10;
  System.out.println(++i);
  //affiche 11;

  i = 10;
  System.out.println(i++);
  //affiche 10
  }
}

Le type des variables peuvent être de n'importe quel type numérique (byte, short, char, int, long, float et double).

Opérateur Description Exemple
x ++ Cet opérateur unaire permet l'incrémentation de la valeur x i++
//équivaut à i=i+1
x -- Cet opérateur unaire permet la décrémentation de la valeur x i--
//équivaut à i=i-1
++ x Cet opérateur unaire permet l'incrémentation de la valeur x avant son utilisation ++i /*pour i=0,
i++ donnera 0 et
++i donnera 1
équivaut à i=i-1*/
-- x Cet opérateur unaire permet la décrémentation de la valeur x avant son utilisation --i
/*pour i=0, de même que
i-- donnera 0 et
--i donnera -1*/

4.5 / Les opérateurs de comparaisons

Les opérateurs de comparaisons permettent de comparer leurs opérandes et de renvoyer une valeur logique en fonction du résultat.

Tous ces opérateurs renvoient un résultat booléen ; si la comparaison est réussie, la valeur logique true est retournée, dans le cas contraire c'est false.

int x = 12;;
int y = 24;
boolean resultat = x < y;
// resultat = true
a = "bonjour";
b = "hello";
boolean resultat = a == b;
// resultat = false

Les opérandes ne peuvent être que des types numériques soit des nombres entiers (byte, short, int et long) ou à virgule flottante (float et double) ou encore des caractères (char) pour les opérateurs de comparaisons suivants : <, >, <=, >=, ==, !=.

Les deux opérateurs d'égalité (==) et de différence (!=) peuvent également être utilisés sur des références d'objet.
Dans ce cas, l'opération consiste en une comparaison de références et non de types de référence.
Les références sont comparées afin de contrôler si elles désignent le même objet.

public class inst {
  public static void main(String[] args) {
  Classe ref = new Classe();
  Classe x = new Classe();
  Object y = ref;
  Object z = null;
  if (ref == x)
      System.out.println("ref et x sont égales !");
  else
      System.out.println("ref et x ne sont pas égales !");

  if (ref == y)
      System.out.println("ref et y sont égales !");
  else
      System.out.println("ref et y ne sont pas égales !");

  ref = null;
  if (ref == z)
      System.out.println("ref et z sont égales !");
  else
      System.out.println("ref et z ne sont pas égales !");
  }
}

class Classe {
 //Instructions...
}

Au temps d'exécution, les résultats des opérateurs == et != sont respectivement true et false, si les valeurs des opérandes sont nulles ou se référent au même objet ou au même tableau, sinon le résultat est false et true.

Deux instances d'une même classe représentant un même objet possèdent des références différentes.

Une erreur au moment de la compilation se produit, si il est impossible de transtyper le type d'un opérande vers l'autre et réciproquement, les valeurs de ces deux opérandes sont forcément différentes lors du temps d'exécution.

Pour une comparaison de deux références d'objet, il est préférable d'utiliser plutôt la méthode equals() définie dans la classe java.lang.Object.

Opérateur Description Exemples
x == y Si la valeur y est égale à x, l'opérateur retourne true. Dans ce cas, si le type de donnée ne correspond pas alors Javascript tentera de convertir les opérandes dans le type approprié afin d'effectuer la comparaison. if (choix == 1)
x != y Si la valeur y est différente de x, l'opérateur retourne true if (valeur != prix)
x > y Si la valeur de y est supérieure à x, l'opérateur retourne true if (montant > 1500)
x >= y Si la valeur de y est supérieure ou égale à x, l'opérateur retourne true if (hab >= pop)
x < y Si la valeur de y est inférieure à x, l'opérateur retourne true if (numero < page)
x <= y Si la valeur de y est inférieure ou égale à x, l'opérateur retourne if (fin <= premier)

La promotion arithmétique se charge de convertir un des opérandes vers le type le plus large des deux pour effectuer la comparaison.

int x = 16;
byte y = 32;
resultat = x > y;
// y est transtypé à int pour effectuer la comparaison

4.6 / L'opérateur ternaire

L'opérateur ternaire permet de poser une structure conditionnelle compacte à trois opérandes.

Type variable
variable = Condition ? Expression_1 : Expression_2;
// est équivalent à 
if (Condition) 
  { Expression_1; }
else
  { Expression_2; }

L'opérateur ternaire utilise l'expression conditionnelle retournant true ou false, pour déterminer laquelle des deux expressions doit être exécutée.

L'opérateur ternaire fonctionne comme une instruction if... else. Si la condition initiale renvoie true, alors la première instruction est éxécutée sinon la deuxième est activée.

String message = (jour == "Lundi") ? "Bonne reprise du travail !"
                         : "Bonne continuation !";

float Prix;
float difference = (Prix >= 100) ? Prix - 100 : 100 - Prix;

Le type du résultat de l'instruction ternaire est du même type que celui des expressions sous certaines conditions :

SuperClasse obj_1 = new SuperClasse();
Classe obj_1 = new Classe();
SuperClasse res = i > 0 ? obj_1 : obj_2;

byte taille_1;
short taille_2;
short res = t == 100 ? taille_1 : taille_2;

4.7 / Les opérateurs au niveau du bit

Les opérateurs au niveau du bit agissent sur les valeurs binaires consituées des nombres 0 et 1.

Dans le langage Java, le signe de la valeur binaire est préservé.

Ces opérateurs sont classés selon trois catégories :

Ces opérateurs agissent essentiellement sur des opérandes de types booléens ou numériques intégraux (byte, short, char, int et long) pour respectivement les opérations logiques ou de décalage.

L'opérateur unaire d'inversion (~) ne peut être appliqué qu'à des opérandes de type numérique intégral (byte, short, char, int et long). Dans ce dernier cas, une inversion de l'ensemble des bits est accomplie avec y compris le signe de la valeur s'il existe.

La promotion arithmétique assure la conversion d'une des opérandes vers le type le plus large d'entre eux afin d'effectuer l'opération de décalage et produit toujours un résultat entier int ou long.

Opérateur Usage Description Exemple
AND x & y Chaque position binaire de l'opérande x est comparée avec la position correspondante de l'opérande y. Dans ce cas, si un 1 est trouvé dans l'une ou l'autre des opérandes, alors l'opérateur retourne un 1, sinon il renvoie un 0.
1101 & 0111 //retourne 0101
0001 & 1000 //retourne 0000
1001 & 0001 //retourne 0001
OR x | y Chaque position binaire de l'opérande x est comparée avec la position correspondante de l'opérande y. Dans ce cas, si un 1 est trouvé dans les deux opérandes soit dans l'une, soit dans l'autre, alors l'opérateur retourne un 1, sinon il renvoie un 0.
1101 | 0111 //retourne 1111
0001 | 1000 //retourne 1001
1001 | 0001 //retourne 1001
XOR x ^ y Cette opérateur OU EXCLUSIF fonctionne comme le précédent à la seule exception que le 1 ne doit se trouver que dans l'une ou l'autre des opérandes pour produire le résultat 1 sinon il renvoie un 0.
1101 ^ 0111 //retourne 1010
0001 ^ 1000 //retourne 1001
1001 ^ 0001 //retourne 1000
NOT ! a L'opérateur unaire NOT retourne un 0 lorsque l'opérande contient un 1 et un 1 pour un 0.
!1101 //retourne 0010
!0001 //retourne 1110
!1001 //retourne 0110
Inversion ~ a L'opérateur unaire d'inversion retourne un 0 lorsque l'opérande contient un 1 et un 1 pour un 0.
~x // équivalent à (-x)-1
(~x)+1 // équivalent à -x
Décalage à gauche x << n Cet opérateur déplace la représentation binaire de x de n bits à gauche. La valeur de ces n bits est de zéro.
15 << 2 
/*0000 1111 décalé de 2 bits produit 
0011 1100 et donc retourne 60*/
Décalage à droite avec préservation du signe x >> n Cet opérateur déplace la représentation binaire de x de n bits à droite en propageant le bit de signe.
10 >> 1 
/*0000 1010 décalé de 2 bits produit 
0000 0101 et donc retourne 5*/
-16 >> 2 /*1111 0001 décalé de 2 bits produit
1111 1100 et donc retourne -4*/
Décalage à droite avec extension de zéros x >>> n Cet opérateur décale la première opérande du nombre n indiqué de bits vers la droite. Des bits excédents décalés en dehors vers la droite sont rejetés. Les bits à zéro sont décalés vers la gauche.
14 >>> 1
/*0000 1110 décalé de 1 bits produit 
0000 0111 et donc retourne 7*/

Les opérations de décalage à gauche et à droite sont équivalent respectivement à multiplier ou à diviser par 2n.

3 << 2 // retourne 12 soit 3 * 22

32 >> 3 // retourne 4 soit 32 / 23

4.8 / Les opérateurs logiques

Les opérateurs logiques permettent de comparer des expressions booléennes et retournent des valeurs booléennes.

boolean variable = expression_1 opérateur expression_2;

boolean variable = (x >= y) && (y < z);

Les opérateurs logiques && et || (appelés parfois opérateurs de court-circuit) évaluent le premier opérande, puis si cela est nécessaire, le second.

Il est également possible d'utiliser les opérateurs logiques &, | et ^ pour effectuer des comparaisons. Dans ce cas, l'opérateur effectuera dans tous les cas l'évaluation des deux opérandes.

Les opérateurs & et | sont couramment utilisés pour obliger Java à calculer une variable présente dans l'opérande de droite.

var = (j++ < 0) && (i-- > 0);
Opérateur Usage Description Exemple
AND x&&y
L'opérateur renvoie True si les deux opérandes sont vraies; autrement, il retourne False.
(a < 10) && (b > 10) 
/*Si a et b sont inférieures à 10,
l'opérateur retourne True*/
OU x || y L'opérateur renvoie True si l'une ou l'autre des opérandes est vraie ou si toutes les deux sont fausses, sinon il retourne False.
(a >= 1) || (b == "fin") 
/*Si a est supérieur ou 
égal à 1 ou/et si b est égal
à fin alors l'opérateur renvoie
true, sinon il retourne false*/
NOT ! x L'opérateur renvoie false si son unique opérande peut être convertie en true, sinon il retourne false.
!(a <= 100) 
/*Si a est inférieur ou égal à 100
alors l'opérateur retourne false,
sinon il renvoie true*/
.
AND (évaluation) x & y L'opérateur retourne True si les deux opérandes sont égales à True, sinon il renvoie False.
(a < 10) & (b > 10) 
/*Si a et b sont inférieures à 10,
l'opérateur évalue True & True
et retourne True*/
OR (évaluation) x | y L'opérateur retourne True si les deux opérandes ou l'une des deux sont égales à True, sinon il renvoie False.
(a >= 1) | (b == "fin") 
/*Si a est supérieur ou 
égal à 1 et si b n'est pas égal
à fin alors l'opérateur évalue
True | False et retourne True*/
XOR (évaluation) x ^ y Cette opérateur OU EXCLUSIF retourne True si l'une des deux opérandes vaut True, sinon il renvoie False.
(a > 1) ^ (b != 10) 
/*Si a est supérieur à 1
et si b est différent 10
alors l'opérateur évalue True ^ True
et retourne False*/

4.9 / Les opérateurs de concaténations

L'opérateur d'enchaînement + permet de concaténer deux chaînes de caractères, en retournant une autre qui est le résultat de la concaténation des deux opérandes.

String Resultat = Chaine_1 + Chaine_2;

L'opérataur de concaténation peut également s'appliquer à des valeurs de type char.

class Concatenation {
  char[] tab = {'b','o','n','j','o','u','r'};
  public static void main(String[] args){
  String = res = "";
  for(int i = 0; i < tab.length; i++){
      res = res + tab[i];
  }
  System.out.println(res);
  }
}

L'opérateur d'affectation += peut également être utilisé pour enchaîner des chaînes de caractères en boucle.

String Chaine = "Les sanglots longs ";
Chaine += "de l'automne.";
// Chaine = Chaine + "de l'automne.";
// Chaine = "Les sanglots longs de l'automne."
"mon" + " " + "programme"
// retourne "mon programme"

texte = "Un programme";
texte_2 = "Java&trade;";
resultat = texte . " " . texte_2;
// retourne "Un programme Java&trade;"

4.10 / L'opérateur de transtypage

L'opérateur de transtypage () (appelé également transtype) permet de convertir à un nouveau type une référence d'objet ou une donnée primitive.

Le compilateur Java transforme automatiquement un type dans un autre lorsque cela s'avère nécessaire. Le transtypage (cast en anglais) permet d'effectuer explicitement cette conversion.

(type) expression;

byte nb = 16;
int nombre = (int)nb;

Le transtypage peut être réalisé sur tous les types primitifs à l'exception du type booléen.

Néanmoins, il est possible d'être confronter à une perte d'information lorsque le type de transtypage est inférieur à celui d'origine.

class TransType {
  static int nb = 192;
  static byte nombre = (short)nb;
  public static void main(String[] args){
  System.out.println("Nombre entier = " + nb);
  System.out.println("Nombre entier court = " + nombre);
  // affiche :
// Nombre entier = 192
// Nombre entier court = -64
} }

Lorsqu'une donnée est transtypée dans un type moins large, le nombre de bits excédentaires à gauche est supprimé, engendrant une dégradation de la valeur initiale comme dans l'exemple précédent.

Bien que cela provoque une erreur pouvant être conséquente pour un programme, aucune exception n'est lancée pour avertir le programmeur de ce risque.

Par contre à l'inverse, lorsqu'un transtypage "implicite" illégal est tenté, alors une exception est lancée indiquant une incompatibilité de type.

double nb = 1.56;
int entier = nb;

Les références d'objet peuvent également être transtypés à l'intérieur d'une famille de types.

Il est possible de convertir une référence d'objet d'une certaine classe en une référence d'objet d'une autre classe seulement si les classes sont en relation par l'intermédiaire d'un héritage.

interface Inter { ... }

class Classe extends I { ... }

class Derivee extends A { ... }

Derivee obj_enfant = new Derivee();
// Conversion implicite
Classe obj_parent = (Classe)obj_enfant;
// équivaut à Classe obj_parent = obj_enfant;
Inter obj_interface = (Inter)obj_parent;
// équivaut à Inter obj_interface = obj_parent;
Inter obj_interface = (Inter)obj_enfant;
// équivaut à Inter obj_interface = obj_enfant;

// Conversion explicite
Derivee obj_enfant = (Derivee)obj_parent;
Classe obj_parent = (Classe)obj_interface;
Derivee obj_enfant = (Derivee)obj_interface;

Le transtypage de référence d'objet n'est pas permis dans toute les situations, un type parent pouvant être incompatible avec une partie de sa descendance.

class Personne { ... }
class SalariePublique extends Personne { ... }
class SalariePrivee extends Personne { ... }

SocietePrivee oPSPri = new SocietePrivee();
Personne oP = oPSPri;
// Erreur puisque oP n'est pas forcément un oPSPub
// dans ce cas il est une instance de la classe SalariePrivee

SocietePublique oPSPub = (SocietePublique)oP;

Il n'est pas permis de transtyper une donnée primitive vers une référence d'objet et réciproquement.

4.11 / L'opérateur instanceof

L'opérateur instanceof permet de vérifier si une référence d'objet est une instance d'une certaine classe ou interface.

boolean resultat = reférence_objet instanceof {Classe | Interface};

L'opérateur instanceof s'applique aux références d'objets mais ne sert pas à comparer deux objets entre eux mais simplement à en déterminer la classe d'instanciation ou l'interface d'implémentation.

L'opérateur retourne true si l'objet désigne effectivement une instance de la classe ou d'une classe dérivée de cette dernière, sinon il retourne toujours false.
Si la référence d'objet implémente l'interface spécifiée, alors l'opérateur renvoie également true, sinon false.

Toutes les classes héritant de Object et partant tous les objets étant des instances d'une classe dérivée de Object, l'expression ref_objet instanceof Object vaut toujours True.

Si l'objet est égal à null, dans tous les cas, le résultat est false.

Si le transtypage de l'opérande de gauche vers le type de référence n'est pas autorisé lors de la compilation, le compilateur indiquera une erreur semblable pour la tentative de comparaison avec l'opérateur instanceof.

class Classe {
  ...
}

class Classe_Etendue extends Classe {
  ...
}

class Autre_Classe{
  ...
}

class Programme {
  void methode(){
  Classe objet_1 = new Classe_Etendue();
  Classe objet_2 = new Classe();
  Object objet_3 = new Classe();
  Object objet_4 = new Autre_Classe();
  Object objet_5 = null;
  Object objet_6 = new Object();
  objet_6 = objet_1;

  boolean resultat = objet_1 instanceof Classe_Etendue;
  // resultat = True
  boolean resultat = objet_1 instanceof Classe;
  // resultat = true
  boolean resultat = objet_2 instanceof Classe_Etendue;
  // resultat = false
  boolean resultat = objet_3 instanceof Classe;
  // resultat = true
  boolean resultat = objet_4 instanceof Object;
  // resultat = false
  boolean resultat = objet_5 instanceof Classe;
  // produit une erreur de compilation.
  boolean resultat = objet_5 instanceof Object;
  // resultat = true
  boolean resultat = objet_6 instanceof Classe_Etendue;
  // resultat = true
  boolean resultat = objet_6 instanceof Classe;
  // resultat = true
  }
}

Pour une comparaison de types de référence, il est préférable d'utiliser plutôt la méthode isAssignableFrom() définie dans la classe java.lang.Class.

4.12 / L'opérateur new

L'opérateur new est utilisé pour créer un objet (ou une instance de classe).

Classe reference_objet = new Constructeur([Arguments...]);

String texte = new String("Une chaîne de caractère");

ClassePerso objet = new ClassePerso();

La création d'un objet peut être réalisée à partir d'une classe prédéfinie dans Java ou d'une classe conçue par un utilisateur.

L'objet résidant en mémoire, est accessible dans le programme par l'intermédaire d'une référence d'objet. Souvent, une utilisation impropre de ce vocabulaire est commise, conduisant parfois à des confusions.

Lors de la création d'un objet, deux types distincts sont affectés :

SuperClasse ref_obj = new constructeur_ClasseDerivee();

Object chaine = new String("Un texte...");
// type référence : Object
// type runtime : String

Cependant, les classes représentées par ces types doivent être liées par une relation d'héritage, sinon une exception relatant une incompatibilité de type sera lancée par le compilateur.

class type {
  public static void main(String[] args){
    Boolean valeur = new String("true");
  }
}
// type référence : Object
instance.java:3: incompatible types
found : java.lang.String
required: java.lang.Boolean
Boolean valeur = new String("true");
^

4.13 / La priorité des opérateurs

La priorité des opérateurs détermine l'ordre dans lequel les expressions sont exécutées dans une déclaration.

Il est possible d'ignorer la priorité d'opérateur en utilisant des parenthèses.

L'associativité détermine également un ordre d'exécution pour des opérateurs d'une priorité égale.

Un opérateur associatif à gauche signifie que l'opérande de gauche est d'abord calculée.

int resultat = a + b - c;
// équivaut
int resultat = (a + b) - c;

Un opérateur associatif à droite signifie que l'opérande de droite est d'abord calculée.

int resultat = a += b -= c = a + b;
// équivaut
int resultat = (a += (b -= (c = (a + b))));

double resultat = x * -y - 42 / z % --x + 2;
// équivaut
double resultat = (((x * (-y)) - ((42 / z) % (--x))) + 2);

La table suivante décrit la priorité des opérateurs, du moins élevé vers le plus élevé, ainsi que leur associativité.

Priorité Opérateurs Associativité
1 = += -= *= /= %= <<= >>= >>>= &= |= ^= De gauche à droite
2 ? : De droite à gauche
2 || De gauche à droite
4 && De gauche à droite
5 | De gauche à droite
6 ^ De gauche à droite
7 & De gauche à droite
8 == != De gauche à droite
9 < <= > >= instanceof De gauche à droite
10 << >> >>> De gauche à droite
11 + - De droite à gauche
12 * / % De gauche à droite
13 (type) new De droite à gauche
14 unaire : + -
préfixe : ++ --
~ !
De gauche à droite
15 () [] . suffixe ++ suffixe -- De gauche à droite

5 / Les instructions conditionnelles

Les instructions conditionnelles permettent de poser une condition avant d'exécuter un bloc d'instructions.

L'instruction conditionnelle la plus répandue dans les scripts demeure la fameuse structure if.

if (condition_booleenne){
  // bloc d'instructions...
}
if (y != 0)
  System.out.println("x / y = " + x / y);

La condition de l'instruction if doit toujours retourner un type booléen.

if (y)
  // y n'étant pas booléen, la condition est erronée
  System.out.println("x / y = " + x / y);

if (y != 0)
  // y étant pas booléen, la condition est correcte
  System.out.println("x / y = " + x / y);

Lorsque la commande if ne comporte qu'une seule instruction dans son bloc, alors les accolades deviennent facultatives.

L'instruction if peut être accompagnée de else, voire d'une combinaison else if afin de formuler une alternative par défaut (sinon) ou une ou plusieurs conditions différentes (sinon si).

if (Première_condition){
  // Premier bloc d'instructions...
}
else if(Seconde_condition){
  // Second bloc d'instructions...
}
...
else if(Nième_condition){
  //Nième bloc d'instructions...
}
else{
  //bloc d'instructions par défaut...
}

if (journee == "matin")
  System.out.println("C'est le matin !");
else if (journee == "après-midi")
  System.out.println("C'est l'après-midi !");
else if (journee == "soirée")
  System.out.println("C'est la soirée !");
else
  System.out.println("C'est la nuit !");

Cette structure conditionnelle fonctionne de la façon suivante en sachant que si une condition est vraie, le bloc d'instructions correspondant est exécuté puis la sortie de la structure complète est opérée :

Une structure conditionnelle if...else if...else peut être remplacée par une instruction switch dont le fonctionnement est sensiblement similaire et en outre la syntaxe est bien plus compacte.

Toutefois, une instruction switch n'accepte dans ses différents cas (case) que des valeurs entières (int, short, byte) et des caractères (char), les autres (long, float, double, boolean, Object) n'étant pas autorisés.

switch (variable){
  case valeur_1:
  //Premier bloc d'instructions...
  break;
  case valeur_2:
  //Second bloc d'instructions...
  break;
  ...
  case valeur_N:
  //Nième bloc d'instructions...
  break;
  default:
  //bloc d'instructions par défaut...
  break;
}

switch (int heure)
{
  case 6:
  System.out.println("C'est le matin !");
  Break;
  ...
  case 14:
  System.out.println("C'est l'après-midi !");
  Break;
  ...
  case 21:
  System.out.println("C'est la soirée !");
  Break;
  ...
  default:
  System.out.println("C'est la nuit !");
  Break;
}

La variable entière heure est comparée successivement à chacune des valeurs explicitée par l'instruction case. Si la comparaison est bonne, le bloc d'instructions correspondant est exécuté.
L'instruction break est nécessaire afin de quitter la structure conditionnelle immédiatement après que la condition adéquate eut été trouvée. Dans le cas contraire, les autres instructions case seraient également évaluées.
Par ailleurs, correspondant à else, l'instruction default fournit une alternative par défaut à switch.

L'instruction ternaire offre une structure plus compacte sous réserve de ne proposer que deux possiblités selon une condition spécifiée.

resultat = condition ? première_alternative : seconde_alternative;

Si la condition est vraie alors la première alternative est retournée, sinon c'est la seconde.

6 / Les boucles

Les boucles permettent de répéter des opérations jusqu'à ce qu'une ou plusieurs conditions soient réunies.

Le langage Java possède plusieurs structures itératives, ayant la même fonction mais possédant des caractéristiques différentes.

D'autre part, ces boucles peuvent ête utilisées avec des instructions de sortie : break et continue avec des possibilités de labélisation.

6.1 / La boucle for

La boucle for se démarque par sa compacité puisqu'elle contient entre parenthèses trois expressions permettant de l'initialiser (ex : i = 0;) de poser une condition à son terme (ex : i > 10) et de l'incrémenter ou de décrémenter automatiquement (ex : i++).

for (initialisation; condition_booléenne; incrémentation){
  // bloc d'instructions...
}

L'expression d'initialisation peut être une simple affectation mais aussi une déclaration de variable.
Dans ce dernier cas, l'argument d'itération ne sera accessible que dans l'instruction for et dans son bloc d'instructions.

int i;
for (i = 0; i < 10; i++)
  System.out.println("\ni = " + i);

for (int i = 0; i < 10; i++)
  System.out.println("i = " + i);

Le bloc d'instructions à exécuter dans une boucle for doit être contenu à l'intérieur d'accolades, s'il n'y a qu'une seule instruction, les accolades sont facultatives.

for (int i = 0; i < 10; i++)
  System.out.println(i + "\r\n");

La boucle for peut aussi bien utiliser des variables de type entier qu'à virgule flottante comme argument.

for (float i = 0; i < 10; i += 0.5)
  System.out.println(i + "\r\n");

Littéralement, cette boucle accomplit des opérations à partir d'un état initial et jusqu'à une certaine condition par le pas indiqué par l'incrémentation.

Il est possible de placer plusieurs instructions d'initialisation et d'itérations dans une boucle for en les séparant par des virgules, mais, il sera alors interdit de déclarer des variables.

class BoucleFor {
  public static void main(String[] args){
  int i, j;
  for(i = 0, j = 0; i + j < 10; i++, j += i)
      System.out.println("i = " + i + " / j = " + j + "\r\n");
  }
}

// résultat de la boucle
i = 0 / j = 0
i = 1 / j = 1
i = 2 / j = 3
i = 3 / j = 6

class AutreBoucleFor {
  public static void main(String[] args){
  int i, j;
  for(i = 0, j = 0; i < 10; ++i, j += i)
      System.out.println("i = " + i + " / j = " + j + "\r\n");
  }
}

// résultat de la boucle
i = 0 / j = 0
i = 1 / j = 1
i = 2 / j = 3
i = 3 / j = 6
i = 4 / j = 10
i = 5 / j = 15
i = 6 / j = 21
i = 7 / j = 28
i = 8 / j = 36
i = 9 / j = 45

Les boucles for peuvent s'imbriquer permettant par exemple d'explorer un tableau multidimensionnel.

import java.math.*;

class BoucleFor {
  static double[][] tailles = {{1.82, 1.65, 1.78, 2.01, 1.98},
                                    {2.11, 1.62, 1.78, 1.84},
                                    {2.01, 1.85, 2.36, 1.61, 1.67}};
  static double total = 0.0d;
  static int longueur_total;

  public static void main(String[] args){
  for(int i = 0; i < tailles.length; i++) {
      longueur_total += tailles[i].length;
      for(int j = 0; j < tailles[i].length; j++) {
        total += tailles[i][j];
        System.out.println(i + " et " + j + " : " 
                           + tailles[i][j] + "\n");
      }
  }
  System.out.println("        -----\n");
  BigDecimal moyenne = new BigDecimal(total / longueur_total);
  System.out.println("Moyenne: " + moyenne.setScale(2, 1));
  }
}}

La boucle de Djikstra est un artifice algorithmique utilisant une instruction for sans fin, contenant une structure conditionnelle d'arrêt en son sein. Cette boucle est souvent utilisée pour la validation de saisie d'un utilisateur.

class BoucleDjikstra {
    public static void main(String args[]){
        try{
            char lettre;
            for(;;){
                lettre = (char)System.in.read();
                if(lettre == 'f') break;
                System.out.println("Saisissez un caractere 'f' pour terminer !");
            }
        }
        catch(Exception e){
            System.out.println("Une exception d'entrée/sortie "
                                               + "s'est produite !");
        }
    }
}

6.2 / La boucle For-Each

La boucle for-each, introduite à partir du JDK 1.5, permet d'utiliser une boucle for spécifique pour itérer une collection Java.

Collection collection = new Vector();
for(Object valeur : collection){
  System.out.println(valeur.toString());
}
//équivaut à
for (Iterator ite = collection.iterator(); ite.hasNext(); )
  System.out.println(ite.next().toString());
}
//équivaut à
for (int i = 0; i < collection.size(); i++)
  System.out.println(collection.get(i).toString());
}

La boucle for est capable de parcourir n'importe quelle collection Java, soit des listes (List), des ensembles (Set) ou des associations clé/valeur (Map). Dans ce dernier type de collection, la boucle for doit déclarer un objet Map.Entry représentant une paire clé/valeur.

TreeMap associations = new TreeMap();
for (Map.Entry entree : associations){
  System.out.println(entree.getKey() + " " + entree.getValue());
}

Désormais, les collections Java peuvent expliciter le type des valeurs contenues dans une collection. Evidemment la boucle for-each prend en compte cette caractéristique. Pour cela, il suffir d'indiquer le type de la valeur à exploiter dans la boucle.

ArrayLIst<String> liste = new ArrayList<String>();
for(String valeur : liste){
  System.out.println(valeur);
}

HashTable<String, ZipFile> associations = 
                        new Hashtable<String, ZipFile>();
for(Map.Entry entree : associations){
  String cle = entree.getKey();
  ZipFile archive = entree.getValue();
}
public class Videos {
  private ArrayList liste;
  public Videos(){
    liste = new Videos();
  }
  public void enregistrer(){
    liste.put(new Video("Voyage au bout de l'enfer", "Michael Cimino", 1978));
    liste.put(new Video("Le jour le plus long", "Ken Annakin", 1962));
    liste.put(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    liste.put(new Video("Platoon", "Oliver Stone", 1986));
    liste.put(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    liste.put(new Video("La ligne rouge", "Terrence Malick", 1998));
    liste.put(new Video("The patriot", "Roland Emmerich", 2000));
    liste.put(new Video("Outrages", "Brian De Palma", 1990));
    liste.put(new Video("Paris brûle-t-il ?", "René Clément", 1966));
    liste.put(new Video("Tora ! Tora ! Tora !", "Richard Fleischer", 1970));
    liste.put(new Video("Guerre et Paix", "King Vidor", 1956));
    liste.put(new Video("Apocalypse now", "Francis Ford Coppola", 1979));
  }
  public String lister(){
    StringBuffer sb = new StringBuffer();
    for(Video video : videos){
      sb.append(video.toString());
      sb.append(System.getProperty("line.separator"));
    }
  }
}

public class Video {
  private String titre;
  private String realisateur;
  private int annee;
  public Video(
              String titre,
              String realisateur,
              int annee){
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  public String toString(){
    StringBuffer sb = new StringBuffer();
    sb.append(this.titre);
    sb.append(";");
    sb.append(this.realisateur);
    sb.append(";");
    sb.append(this.annee);
    return sb.toString();
  }
}

6.3 / Les boucles while et do...while

La différence principale entre les boucles while et do...while est que la seconde structure effectuera quelque soit la condition initiale, une première itération, soit exécutera une première fois le bloc d'instructions.

La boucle while contient essentiellement comme argument une condition d'arrêt toujours évaluée avant chaque itération.

L'initialisation et l'incrémentation devront être explicitées respectivement avant et à l'intérieur de la boucle.

initialisation;
while (condition_booléenne){
  bloc d'instructions...
  incrémentation;
}

int i = 0;
while (i < 10){
  System.out.println(i + "\r\n");
  i++;
}

la boucle do...while contrairement à while... évalue la condition après chaque itération.

initialisation;
do{
  bloc d'instructions...
  incrémentation;
}
while (condition_booléenne);

int i = 0;
do{
  System.out.println(i + "\r\n");
  i++;
}while (i < 10);

Littéralement, ces boucles accomplissent des opérations tant qu'une condition est vraie :

Contrairement à la boucle for, ces boucles nécessitent une initialisation des éventuels variables incrémentables avant la structure.

La condition des structures itératives, soit l'expression se trouvant immédiatement après while entre paranthèses, doit fournir une valeur du type booléen : true ou false.

Dans les deux cas, il est possible d'omettre les accolades délimitant le bloc d'instructions si ce dernier ne contient qu'une seule instruction.

class Boucles {
  static String[] jour_semaine = {"lundi", "mardi", "mercredi", "jeudi", 
                                       "vendredi", "samedi", "dimanche"};
  public static void main(String[] args){
  int i = 0;

  do {
      System.out.println("Jour de la semaine : " 
                                + jour_semaine[i] + "\n");
      i++;
   } while(i < jour_semaine.length);

  System.out.println("------------------------");

  while(--i >= 0) {
      System.out.println("Jour de la semaine : " 
                                + jour_semaine[i] + "\n");
  }
  }
}

6.4 / Les instructions break et continue

Les instructions break et continue facilitent respectivement la sortie complète et l'arrêt pour l'itération en cours d'une boucle suite à une condition particulière nécessitant une action précise.

while(condition){
  // Bloc d'instructions...
  break;
  /* sortie de la boucle avant la prochaîne itération
et passage à la prochaine instruction après la boucle
*/
// Bloc d'instructions... } // Prochaines instructions... while(condition){ // Bloc d'instructions... continue; /* arrêt de la boucle à l'itération en cours
mais passage à l'itération suivante
*/
// Bloc d'instructions... }

Il est possible d'utiliser des étiquettes (ou labels) avec les instructions continue et break afin d'indiquer au programme le début de l'instruction à reprendre après la sortie d'une itération.

break label;
continue label;
premiereBoucle: for(i = 0; i < 10; i++) {
  boucleExterne: for(int j = 0; j <= 4; j++) {
    if (j == 4) {
      break premiereBoucle;
    }
    for(k = 0; k < 3; k++) {
      System.out.println('('i + ', ' + j + ', ' + k + ')rn');
      continue boucleExterne;
    }
  }
}

Les deux instructions étiquetées permettent de reprendre les itérations à la première boucle for si j est égal à 4, et à la seconde boucle après l'impression des valeurs i, j et k.

Evidemment, les instructions d'arrêt étiquetées doivent être placées à l'intérieur des boucles désignées par les labels.

int a = 0;
Exterieur: for(int i = 0; i < 10; i++){
  int j = 0;
  while(j < 1000){
    a++;
    j++;
    if(i == 5){
      continue Exterieur;
    }
  }
}
System.out.println("a = " + a);

Les labels sont particulièrement utiles lors de l'utilisation de boucles imbriquées dans un programme.

class Boucles {
  public static void main(String[] args){
    premiere_boucle: for(int i = 0; i < 10; i++) {
      seconde_boucle: for(int j = 0; j < 10; j++) {
        troisieme_boucle: for(int k = 0; k < 10; k++) {
          if((i * j * k) == 9) {
            System.out.println("Sortie Première boucle " 
                                             + (i * j * k));
            continue premiere_boucle;
          }
          if((i * j * k) == 125) {
            System.out.println("Sortie Seconde boucle " 
                                             + (i * j * k));
            continue seconde_boucle;
          }
          if((i * j * k) == 343) {
            System.out.println("Sortie Troisième boucle " 
                                             + (i * j * k));
            continue troisieme_boucle;
          }
        }
      }
    }
  }
}

7 / Les types de données

Le langage Java reconnaît plusieurs types de données permettant de différencier les informations utilisées par un programme.

En premier lieu, les types de données sont classées selon deux catégories distinctes :

Les types de données primitifs regroupent les valeurs numériques entières ou décimales, les caractères simples et Unicode ainsi que les booléens true et false.

Type Intervalle Description
byte -27 - 27-1
(-128 - 127)
représente un type de données de nombres entiers binaires 8 bits.
short -215 - 215-1
(-32768 - 32767)
représente un type de données de nombres entiers courts sur 16 bits.
int -231 - 231-1
(-2147483648 -
2147483647
représente un type de données de nombres entiers sur 32 bits.
long -263 - 263-1
(-9223372036854775808 -
9223372036854775807)
représente un type de données de nombres entiers longs sur 64 bits.
float -3.4*1038
- +3.4*1038
représente un type de données de nombres à virgule flottante sur 32 bits.
double -1.8*10308
- +3.4*10308
représente un type de données de nombres à virgule flottante double sur 64 bits.
char '\u0000' - '\uFFFF'
soit de 0 à 65535
représente un type de données de caractères Unicode sur 16 bits.
boolean true OU false représente un type de données booléen sur 1 bit.
null null représente un type de données spécial.

Les types de données composites sont des structures composées de plusieurs informations de types primitifs ou composites comme les classes, les tableaux et les chaînes de caractères provenant plus exactement de la classe String.

La conversion des types de données permet de modifier le type initial d'une valeur en un autre en respectant toutefois certaines contraintes. Par exemple, il n'est pas possible de convertir une valeur en type booléen, un objet en un objet de classe sans corrélation. De même, si le transtypage d'un nombre en un type supérieur est permis comme un entier court en un type long, l'inverse comme un nombre décimal simple en un entier long, peut produire des erreurs et donc Java tentera d'empêcher ce type de conversion.

byte -> short -> int -> long -> float -> double

La conversion de type de données de la gauche vers la droite (le sens de l'élargissement) s'effectue automatiquement, tandis que dans le sens inverse (ou sens de la restriction), il est nécessaire de passer par un transtypage explicite.

// transtypage explicite
int x = 10;
int y = 3;

valeur = x / y; // retourne 3

valeur = (float)x / y // retourne 3.33...

// transtypage automatique
float x = 10;
int y = 3;

valeur = x / y // retourne 3.33...

Il est également possible de placer des caractères spéciaux (l, f, et d) immédiatement après le littéral numérique afin d'effectuer une opération de transtypage.

// Conversion d'un valeur numérique en type long
long a = 199999999999999999L;

// Conversion d'un valeur numérique en type float
float b = 3.0F;

float x = b + 24F;

// Conversion d'un valeur numérique en type double
double c = 15D;

double y = c / x * 12D;

Dans le langage Java, tous les littéraux entiers sont de type int. De la même façon, tous les littéraux à virgule flottante sont de type double.

8 / La promotion numérique

La promotion numérique permet de rendre compatible le type des opérandes avant qu'une opération arithmétique ne soit effectuée.

int a = 12;
short b = 15;
int resultat = a + b;
// Promotion numérique
int resultat = a + (int)b;

Une conversion (cast) vers le type le plus large de l'une des opérandes est appliquée implicitement à l'opérande possèdant le type le moins large.

Un type large est déterminé en fonction :

Type Codage
byte 8 bits
short 16 bits
char 16 bits
int 32 bits
long 64 bits
float 32 bits
double 64 bits

Le résultat d'une opération binaire ou unaire est toujours un nombre de type int, long, float ou double.

typeG opérandeG;
typeD opérande_droite;

typeR resultat = opérandeG opérateur;
// ou
typeR resultat = opérateur opérandeG;

typeR resultat = opérandeG opérateur opérandeD;
Opération unaire
typeG char byte short int long float double
typeR int int int int long float double

Une opération unaire sur des nombres de type int, long, float ou double ne nécessite aucune promotion numérique puisque le type résultant est identique.

Opération binaire
  char byte short int long float double
char int int int int long float double
byte int int int int long float double
short int int int int long float double
int int int int int long float double
long long long long long long float double
float float float float float float float double
double double double double double double double double

Les types byte et short ne sont pas compatibles avec le type char bien que les premiers soient inférieurs ou égaux en terme de largeur, mais ne font pas partis de la même gamme de types.

byte a = 10;
short b = 12;

char c = a; 
char d = b;
// produisent une erreur de compilation
// possible loss of precision

char a = 'c';
int b = a;
// est équivalent à
int b = (int)a;
// b = 99;
Les gammes des types
Gamme Types
Caractères char
Nombres entiers byte, short, int, long
Nombres à virgule flottante float, double

En résumé, le type plus large conserve toujours la prédominance sur l'autre type dans une opération arithmétique binaire.

9 / Les tableaux

Les tableaux sont des structures de données regroupant plusieurs valeurs de même type.

Les tableaux constituent des collections d'informations homogènes, c'est-à-dire, de valeurs primitives ou d'objets de même type.

Les éléments d'un tableau peuvent être :

La taille d'un tableau est fixée d'une façon permanente suite à la déclaration du tableau et à l'allocation de ressources systèmes pour ce dernier. Un tableau est donc non-mutable.

Une alternative à ce type de tableaux est représentée par les vecteurs, pouvant être réalloués dynamiquement et de plus possédant la capacité de contenir des collections d'objets disparates.

9.1 / Les tableaux unidimensionnels

La déclaration des tableaux s'effectuent par l'intermédiaire de crochets ([...]).

type identificateur[];

type[] identificateur;

double resultats[];

char[] lettres;

String[] employes;

Il est possible de placer les crochets après l'identificateur ou après le type pour obtenir une déclaration de tableau.

La taille d'un tableau n'est spécifié qu'à partir du moment de son utilisation dans le programme. Ainsi, la mémoire ne sera allouée que lorsque cela sera nécessaire.

La définition d'une référence d'un tableau, c'est-à-dire la spécification de la taille du tableau référencé par la variable, s'accomplit en utilisant l'opérateur new.

identificateur = new type[taille];

notes = new int[10];
// la variable notes fait référence à
// un tableau de 10 valeurs entières.

La déclaration peut se combiner à la définition du tableau produisant une instruction plus compacte.

long[] idClient = long[100000];

Par défaut, les valeurs de chaque élément d'un tableau sont égales à :

Les tableaux peuvent être initialisés par l'intermédiaire d'une liste de valeurs séparées par une virgule et compris entre des accolades.

type[] identificateur = {valeur, ..., valeurN};

type identificateur[] = {valeur, ..., valeurN};

int[] notes = {10, 9, 12, 14, 16, 15, 17, 20, 19, 18};

int notes[] = {10, 9, 12, 14, 16, 15, 17, 20, 19, 18};

Un tableau existant peut être référencé par une autre variable par le biais d'une simple affectation.

int[] resultats = int[10];

int[] resultats = notes;
// Les deux variables notes et resultats
//référencent désormais le même tableau

Dans ce cas de figure, lorsque le contenu du tableau aura subi une modification quelconque par le truchement de l'une des variables, l'autre répercutera évidemment les différences induites puique leur point commun est justement l'objet tableau et son contenu.

class Tableau {
  public static void main(String args[]) {
    int[] notes = {10, 15, 12, 10, 9, 19, 13, 5, 7, 20};
    int[] copie = notes;
    for(int i = 0; i < notes.length; i++)
      if(notes[i] < 10) notes[i] = 10;
    System.out.println ("NOTES :");
    for(int i = 0; i < copie.length; i++)
      System.out.println ("Note n°" + i + " : " + notes[i]);
    System.out.println ("COPIE :");
    for(int i = 0; i < copie.length; i++)
      System.out.println ("Note n°" + i + " : " + copie[i]);
  }
}

L'accès aux éléments d'un tableau est réalisé en utilisant ses indices, soit les numéros de chacun de ses éléments, en sachant que le premier commence à l'indice 0.

valeur = identificateur[indice];

premiereNote = notes[0]; // = 10

sixiemeNote = notes[5]; // = 15

dixiemeNote = notes[9]; // = 18

La redéfinition d'un tableau entraîne la perte de l'ancienne structure avec toutes ses valeurs.

notes = int[50];
// Création d'un nouveau tableau de 50 valeurs entières
// initialisées par défaut à 0,
// et entraînant la suppression de celui de 10 valeurs

La boucle for permet de parcourir un tableau d'une manière automatique.

int total = 0;
for(i = 0; i < 10; i++) {
  total += notes[i];
  System.out.println(notes[i] + "rn");
}
System.out.println("----rn");
System.out.println(total / 10);

D'autre part, la propriété length associée à un objet de type Array, fournit la taille d'un tableau.

int taille = notes.length; // taille = 10

En conséquence, dans une boucle for, la valeur conditionnelle peut être remplacée par cette propriété.

class BoucleFor {
  static int notes[] = {10, 9, 12, 14, 16, 15, 17, 20, 19, 18};
  static int total = 0;
  public static void main(String[] args){
    int i, j;
    for(i = 0; i < notes.length; i++) {
      total += notes[i];
      System.out.println("note  " + i + " : " + notes[i] + "n");
    }
    System.out.println("         ----n");
    System.out.println("Moyenne : " + total / notes.length);
  }
}

9.2 / Les tableaux multidimensionnels

Les tableaux multidimensionnels sont des structures complexes possédant plusieurs indices.

Les dimensions dans ces tableaux sont en fait des références vers de simples tableaux. Un tableau à trois dimensions contiendra un premier tableau référençant plusieurs autres tableaux, référençant eux mêmes encore d'autres tableaux qui contiennent des valeurs.

La création de tels tableaux s'effectue en posant autant de crochets qu'il est nécessaire, à la suite de son type ou de son identificateur.

type[][]... identificateur;

type identificateur[][]...;

// Déclaration correcte mais peu claire
type[][] identificateur[];

double[][] remuneration;
// Définition d'un tableau à deux dimensions

double[][][] remuneration;
// Définition d'un tableau à trois dimensions

La définition des tailles d'un tableau multidimensionnel utilise, à l'instar des tableaux simples, l'opérateur new.

identificateur = new type[taille_1][taille_2];

remuneration = new double[20][12];
// Tableau de 20 tableaux de 12 éléments primitifs

remuneration = new double[3][20][12];
// Tableau référençant 3 tableaux de 
// 20 autres de 12 éléments primitifs

Les tableaux multidimensionnels acceptent les variations dans leur dimension. Le tableau remuneration à trois dimensions représentant respectivement les succursales, les employés et le nombre de mois, pourraient ne pas avoir le même nombre d'employés par succursale, si bien qu'il faudrait modifier la définition du tableau pour que cela soit pris en compte.

remuneration = new double[3][][];

remuneration[0] = new double[20][12];
remuneration[0] = new double[15][12];
remuneration[0] = new double[11][12];

L'initialisation de ce genre de tableau nécessite l'utilisation d'accolades imbriquées.

identificateur[][] = {{Valeur, ..., ValeurN}, 
                             ...,
                             {Valeur, ..., ValeurN}};
...
Identificateur[][][] = {{{Valeur, ...}, ..., {Valeur, ...}},
                                ...,
                                {{Valeur, ...}, ..., {Valeur, ...}}};

remuneration[][] = {{1351.02, 1410.85, ..., 1519.36},
                           ...,
                           {2085, 1810.85, ..., 2519.36}};
// Initialisation de 12 valeurs dans
// chaque ligne d'un tableau bidimensionnel.

Dans un tableau bidimensionnel, la variation du second indice avec une valeur fixe pour le premier, permet d'accéder aux valeurs présentes dans une ligne, l'inverse permettant l'accès aux valeurs dans une colonne.

valeur_ligne = identificateur[i_fixe][j_variable];

valeur_colonne = identificateur[i_variable][j_fixe];

for(j = 0; j < 12; j++)
  paie_1 += remuneration[0][j];
// total sur une ligne

for(i = 0; i < 20; i++)
  paie_total_fev += remuneration[i][0];
// total sur une colonne

La taille d'une dimension d'un tableau peut être récupérée par la propriété length.

int taille_i = identificateur.length;

int taille_j = identificateur[i].length;

int taille_k = identificateur[i][j].length;
...

int taille = identificateur[0].length;
// taille = 12

Le parcours automatique de tous les éléments d'un tableau multidimensionnel, nécessite l'emploi de plusieurs boucles imbriquées.

class BoucleFor {
  static double[][] remuneration = {{1351.02, 1410.85, 1519.36},
                                    {1501.21, 1610.62, 1908.78, 1930.84},
                                    {2085.01, 1810.85, 2519.36}};
  static double total = 0.0d;
  public static void main(String[] args){
    for(int i = 0; i < remuneration.length; i++) {
      for(int j = 0; j < remuneration[i].length; j++) {
        total += remuneration[i][j];
        System.out.println(i + " et " + j + " : " 
                           + remuneration[i][j] + "n");
      }
    }
    System.out.println("        --------n");
    System.out.println("total  : " + total);
  }
}

10 / Les chaînes de caractères

Les chaînes de caractères permettent de stocker n'importe quelle séquence de caractères alphanumériques.

Le type de données String provient en réalité de la classe String, et partant, les chaînes de caractères sont des objets String.

Tous les caractères Unicode, tels que les lettres, les chiffres, les espaces, les signes de ponctuation et tous les autres sont acceptés du moment que l'ensemble est encadré par des guillemets doubles ("...")ou simples ('...').

"Une chaîne de caractères..."

Pour les caractères spéciaux, il existe des séquences d'échappement Unicode permettant de les intégrer dans une chaîne de caractères.

\' // apostrophe
\" // guillemet double

\n // nouvelle ligne
\r // retour chariot
\t // tabulation
\/ // barre oblique
\\ // barre oblique inversée
\f // saut de page

\ooo // octal
\xhh // hexadécimal
\udddd // caractère unicode

"\tL\'île fût submergée par les eaux !\r\n"

La déclaration d'une chaîne de caractères s'effectue en posant le nom de la classe suivie d'un identificateur.

String identificateur;

String texte;

Suite à la déclaration, une affectation à une valeur permet d'initialiser la variable.

identificateur = "Chaîne de caractères...";

String autre_texte = null;
// variable de type String sans référence

texte = "Le sommet de la terre de Johannesbourg a été un échec !";

Les objets String sont inaltérables (ou non-mutables), c'est-à-dire que les chaînes de caractères ne peuvent être modifiées. Lors de la réaffectation d'une valeur, la variable détruit l'ancienne chaîne de caractères et en référence une nouvelle.

String texte = "Le vilain ogre";

texte += " a tout fait capoter !";
// provoque la suppression de "Le vilain ogre"
// texte référence le nouveau littéral
// "Le vilain ogre a tout fait capoter !"

La concaténation des chaînes de caractères s'accomplit au moyen du signe plus (+).

String resultat = "chaîne 1" + "chaîne 2";

resultat += "autre chaîne...";
// resultat = "chaîne 1chaîne 2autre chaîne..."

10.1 / Les objets StringBuffer

Les objets StringBuffer sont des chaînes de caractères mutables, c'est-à-dire, dont la taille et le contenu peuvent être modifiés dynamiquement.

Dans le cas des objets StringBuffer, il est nécessaire de créer des instances de la classe StringBuffer par le biais de l'opérateur new.

StringBuffer chaine = new StringBuffer("Chaîne initiale");

Ainsi contrairement aux objets String, il devient possible de supprimer, d'ajouter, d'insérer ou de remplacer de nouvelles données directement dans la chaîne de caractères d'origine par l'intermédiaire de méthodes spécialisées telles que respectivement delete(), append(), insert() ou replace().

class TestStringBuffer {
  public static void main(String args[]) {
    StringBuffer ch = new StringBuffer();
    System.out.println("Capacite : " + ch.capacity());
    ch = ch.append("Confucius :\n");
    ch = ch.append("Quand on est capable d'accomplir la justice,"
                                  + " il faut tenir sa parole.");
    System.out.println (ch);
    System.out.println("Capacite : " + ch.capacity());
    ch = ch.insert(ch.indexOf("la justice"), 
                                   "sa promesse sans manquer a ");
    System.out.println (ch);
    System.out.println("Capacite : " + ch.capacity());
    ch = ch.replace(ch.indexOf("on ")
                                  + "on ".length(), ch.indexOf("accomplir"), "peut ");
    System.out.println (ch);
    System.out.println("Capacite : " + ch.capacity());
  }
}

La méthode toString() est appelée implicitement lors d'une tentative d'affichage de l'objet StringBuffer. Ainsi dans ce cas, on peut se passer de l'écriture ci-dessous :

System.out.println(ch.toString());

A partir de cet objet, des méthodes diverses peuvent être appliquées afin de consulter ou de modifier l'état de l'objet.

import specialIO.*;
/**
* Cette application permet de crypter et de décrypter
* une chaine de caractères à l'aide de l'algorithme de César
*/
class CryptageChaine { static public String chaine; static public StringBuffer copieChaine; static public int ecart = 1; /**
* Cette méthode permet d'exécuter le programme et
* de lancer une saisie de l'opérateur puis de crypter
* et de décrypter une chaîne de caractères.
*/
public static void main(String args[]) { System.out.print ("Veuillez saisir une chaine de caracteres : "); chaine = Console.in.readLine(); copieChaine = new StringBuffer(chaine); System.out.println ("*** CRYPTAGE ***"); cryptage(); System.out.println ("*** DECRYPTAGE ***"); decryptage(); } /**
* Cette méthode permet de crypter une chaîne de caractères.
*/
public static void cryptage(){ for(int i = 0; i < chaine.length(); i++){ char car = chaine.charAt(i); if(car > (char)('z'-ecart)) copieChaine.replace(i, i+1, ecart == 1 ? "a" : "" +(char)('a'+ecart-1)); else if(chaine.charAt(i) == ' ') copieChaine.replace(i, i+1, "$"); else copieChaine.replace(i, i+1, ""+(char)(car+ecart)); } System.out.println("Chaine d'origine : " + chaine); System.out.println("Chaine cryptee : " + copieChaine); } /**
* Cette méthode permet de décrypter une chaîne de caractères.
*/
public static void decryptage(){ for(int i = 0; i < copieChaine.length(); i++){ char car = copieChaine.charAt(i); if(car < (char)('a'+ecart)) copieChaine.replace(i, i+1, ecart == 1 ? "z" : "" +(char)('z'-ecart-1)); else if(copieChaine.charAt(i) == '$') copieChaine.replace(i, i+1, " "); else copieChaine.replace(i, i+1, ""+(char)(car-ecart)); } System.out.println("Chaine d'origine : " + chaine); System.out.println("Chaine decryptee : " + copieChaine); } }

Un objet StringBuffer n'est pas directement compatible avec son homologue String. La conversion de l'une vers l'autre et réciproquement contraint à utiliser :

Les objets StringBuffer sont utilisés par le compilateur pour implémenter l'opérateur de concaténation '+'.

String ch1 = "La Justice";
String ch2 = "vitesses";
String resultat = ch1 + "fonctionne à deux " + ch2 + " !";
// Compilation
String resultat = new StringBuffer().append(ch1)
                                .append("fonctionne à deux ")
                                .append(ch2).append(" !").toString();

Une nouvelle instance vide de la classe StringBuffer est créée, puis chaque chaîne de caractères de l'expression initiale est ajoutée à l'objet, par le biais des méthodes append() et enfin la méthode toString() se charge de retourner un objet String conforme au type de l'expression.

Tant que la longueur d'une séquence de caractères contenue dans l'objet StringBuffer n'excède pas la capacité initiale, il n'est pas nécessaire d'allouer de nouvelles ressources à l'objet. Par contre, lorsque la mémoire tampon interne de l'objet ne suffit plus, alors de nouvelles ressources systèmes nécessaires sont allouées automatiquement à l'objet.

10.2 / La méthode equals()

La méthode equals() déterminant une égalité d'objet, permet de comparer deux références d'instance de classe par rapport à leur valeur.

boolean resultat = ref_obj1.equals(ref_obj2);

L'égalité d'objet est obtenue lorsque deux objets distincts contiennent une valeur identique, à ne pas confondre avec l'égalité de référence, obtenue si deux références d'objets pointent vers un même objet.

class equal {
  public static void main(String[] args){
  String ref_obj1 = new String("Un texte.");
  String ref_obj2 = new String("Un texte.");
  if(ref_obj1.equals(ref_obj2))
      System.out.println("Réussi");
  else System.out.println("Echec");

  ref_obj1 = "Une autre chaîne !";
  if(ref_obj1.equals(ref_obj2))
      System.out.println("Réussi");
  else System.out.println("Echec");
  }
}
//affiche
Réussi
Echec

La méthode equals() est définie dans la superclasse java.lang.Object. Elle est outrepassée dans des sous-classes telles que java.lang.String, java.lang.Boolean, java.util.Vector, etc..

Le comportement de la méthode equals() varie selon la classe qui l'invoque.

La méthode equals() invoquée par une référence d'instance de la classe Object effectue un comparaison d'égalité de référence avec un argument d'un type quelconque.

Object ref_obj1 = new Object();
Object ref_obj2 = new Object();
UneClasse ref_obj3 = new UneClasse();
Object ref_obj4 = ref_obj1;

boolean resultat = ref_obj1.equals(ref_obj2);
// resultat = false;

boolean resultat = ref_obj1.equals(ref_obj3);
// resultat = false;

boolean resultat = ref_obj1.equals(ref_obj4);
// resultat = true;

Par contre, lorsque deux références pointent vers des objets d'un type identique, elles sont effectivement comparés par rapport à leur valeur.

Boolean ref_obj1 = new Boolean(true);
Boolean ref_obj2 = new Boolean(true);

boolean resultat = ref_obj1.equals(ref_obj2);
// resultat = true;

boolean resultat = ref_obj1.equals(ref_obj3);
// resultat = true;

Si un objet d'un type quelconque est comparé à un autre objet de type Object, alors si les deux objets sont des instances d'une même classe, une comparaison de valeur devient possible, sinon la méthode equals() retourne false.

UneClasse ref_obj1 = new UneClasse();
UneClasse ref_obj2 = new UneClasse();
Object ref_obj3 = new Object();
Object ref_obj4 =  = new UneClasse();

boolean resultat = ref_obj1.equals(ref_obj3);
// resultat = false;

boolean resultat = ref_obj1.equals(ref_obj4);
// resultat = true;

ref_obj3 = ref_obj2;
boolean resultat = ref_obj1.equals(ref_obj3);
// resultat = true;

Dans tous les cas, si les types du temps d'exécution sont différents et même si les types références sont identiques, la méthode equals() retourne toujours false.

class equal {
  public static void main(String[] args){
  String ch = new String("Un texte.");
  String ch2 = new String("Un texte.");
  Boolean log = new Boolean(true);
  Boolean log2 = new Boolean(true);
  Object obj = new Object();
  Object obj2 = new Object();
  String ch3 = new String("U");
  Character car = new Character('U');
  Object obj_car = new Character('U');
  Object obj_ent = new Integer(10);
  Object obj_ent2 = new Long(10);

  if(obj.equals(obj2)) System.out.println("Obj(obj) : Réussi");
  else System.out.println("Obj(obj) : Echec");

  if(obj.equals(log2)) System.out.println("Obj(log) : Réussi");
  else System.out.println("Obj(log) : Echec");

  if(obj.equals(ch2)) System.out.println("Obj(ch) : Réussi");
  else System.out.println("Obj(ch) : Echec");

  if(ch.equals(obj2)) System.out.println("ch(obj) : Réussi");
  else System.out.println("ch(obj) : Echec");

  if(ch.equals(ch2)) System.out.println("ch(ch) : Réussi");
  else System.out.println("ch(ch) : Echec");

  if(ch.equals(log2)) System.out.println("ch(log) : Réussi");
  else System.out.println("ch(log) : Echec");

  if(log.equals(obj2)) System.out.println("log(obj) : Réussi");
  else System.out.println("log(obj) : Echec");

  if(log.equals(log2)) System.out.println("log(log) : Réussi");
  else System.out.println("log(log) : Echec");

  if(log.equals(obj2)) System.out.println("log(obj) : Réussi");
  else System.out.println("log(obj) : Echec");

  if(car.equals(ch3)) System.out.println("car(ch) : Réussi");
  else System.out.println("car(ch) : Echec");

  if(ch3.equals(car)) System.out.println("ch3(car) : Réussi");
  else System.out.println("ch3(car) : Echec");

  if(car.equals(obj_car))
      System.out.println("car(obj_car) : Réussi");
  else System.out.println("car(obj_car) : Echec");

  if(obj_ent.equals(obj_ent2))
      System.out.println("obj_ent(obj_ent2) : Réussi");
  else System.out.println("obj_ent(obj_ent2) : Echec");

  if(obj_ent2.equals(obj_ent))
      System.out.println("obj_ent2(obj_ent) : Réussi");
  else System.out.println("obj_ent2(obj_ent) : Echec");

  obj = log;
  if(log2.equals(obj))
      System.out.println("log(obj=log) : Réussi");
  else System.out.println("log(obj=log) : Echec");

  if(obj.equals(log2))
      System.out.println("obj=log(log) : Réussi");
  else System.out.println("obj=log(log) : Echec");
  }
}

Par ailleurs, l'égalité d'objet est vraie dans les deux sens.

11 / Les constantes

Les constantes contiennent une valeur fixe et sont caractérisées par un identficateur et un type de données à l'instar des variables.

Les constantes peuvent être déclarées dans les classes ou dans les méthodes en utilisant le mot-clé final.

final String COULEUR_NOIRE = "#000000";

final int CODE = 1537503;

final double PI = 3.14;

Par convention, le nom des constantes est toujours en majuscules afin de les distinguer sans équivoques des variables.

La tentative de modifier une constante dans le programme entraînera une erreur lors de la compilation.

12 / Les variables

Les variables permettent de stocker dans une zone mémoire des informations utilisables dans un programme Java.

Il est nécessaire de déclarer le nom et le type des variables avant de pouvoir leur affecter une valeur.

modificateur type identificateur [= valeur];

Les modificateurs peuvent apparaître dans n'importe quel ordre.

public int hauteur = 100;

static String unite = "mètres";

long population = 6000000000;

boolean reussite = false;

final char CR = '\r';

float = 10.87E5;

URL adresse = new URL("http://java.sun.com/");

private String[] tableau;

transient private long code_secret;

Il est interdit de définir deux fois la même variable au sein d'une même portée.

12.1 / La portée

La portée détermine le partie d'un programme, dans laquelle une variable peut être utilisée.

La portée des variables diffère selon leur emplacement au sein du code Java. En fait, lorsqu'une variable est déclarée au sein d'un bloc de code comme une classe ou une méthode, elle ne peut être utilisée que dans ce même bloc.

public class classe_comptage {
  /* i est utilisable dans toute la classe 
      y compris dans ses méthodes */
  int i = 0;

  public void compteur(){
  // pas est seulement utilisable
// dans la méthode compteur
int pas = 5 while(i <= 100){ system.out.println(i + 'rn'); i += 5; } } }

Par défaut, les variables possèdent une portée essentiellement locale dans dans leurs blocs respectifs délimités par des accolades.

{
  int x = 1;
  // seul x est accessible à cet endroit
  {
    // x est accessible à cet endroit,
// y n'est pas accessible puisque la
// variable n'est pas encore déclarée
int y = 2; // x et y sont accessibles } // y n'est pas accessible,
// x est accessible à cet endroit
}

En se fondant sur cette règle, une variable définie dans une classe peut être accèdée dans toute la classe et une autre définie dans une méthode restera accessible dans cette seule méthode.

public class calcul {
  int a = 10;
  public static void main(String[] args){
    int b = 4;
    System.out.println("resultat : " + a * b);
  }
}

Il est possible de déterminer la portée des variables plus précisément, par le truchement d'un modificateur d'accès.

Les variables peuvent avoir une portée globale, soit une accessibilité entre toutes les classes de tous les paquetages, à condition d'utiliser le modificateur d'accès public lors de leur déclaration.

public class affichage {
  public String texte = 'Un texte...';

  public void affiche(){
    system.out.printl(texte);
}

public class modification {
  public void ajout(){
    texte += 'Un second paragraphe...';
  }
}

La portée entre classe peut être limitée aux seules sous-classes, en déclarant une variable avec le modificateur d'accès protected.

Les variables déclarées avec le modificateur d'accès private ne peuvent être accédées que dans la classe elle-même.

private string chaine = "Une chaîne de caractères...";

Un programme reposant sur des variables globales peut être à l'origine de bogues difficiles à détecter. C'est pourquoi, il est préférable d'utiliser des variables locales offrant plus de sûreté avec une durée de vie limitée.

Exemple
class calcul{
  int a = 1;
  void addition(){
    int b = 1;
    b += a;
    // a = 2
  }
  void soustraction(){
    int c = 1;
    c -= a + b;
    /* provoque une erreur car b n'est
        accessible que dans addition() */
  }
}

12.2 / Utilisation des variables

Les variables peuvent être utilisées de différentes manières dans un programme, toutefois toutes doivent être impérativement initialisées avant leur utilisation.

Type Valeur
initiale
Exemple
byte
short
int
0 byte var = 0;
short var = 0;
int var = 0;
long 0L long var = 0L;
float 0.0f float var = 0.0f;
double 0.0d double var = 0.0d;
char 'u0000' char var = 'u0000';
boolean false boolean var = false;
Objet null String var = null;

Les variables déclarées dans les méthodes doivent être initialisées manuellement.
Les variables déclarées dans les classes et les tableaux sont initialisés automatiquement à une valeur nulle dépendant de leur type de données.

Une variable peut être manipulée directement à partir de sa classe d'appartenance, voire d'autres classes, il s'agît des variables membres.

class UneClasse {
  static int nombre;
  private float prix;
  public String nom_article = "DVD";
    ...
    static public void UneMethode(int nb){
    nombre = nb;
    ...
  }

  public int UneAutreMethode(String article){
    if(nom_article == article)
      prix = 14.99f;
    ...
  }
  ...
}

Cette catégorie de variables se divisent en deux parties :

Par conséquent, à l'instar d'une méthode, il est possible d'appeler une variable suite à l'instanciation de sa classe d'appartenance.
Dans ce cas, le modificateur d'accès n'a pas d'importance puisqu'il s'intéresse au niveau de classe et non au niveau d'instance. Ainsi, une variable déclarée avec le modificateur le plus restrictif, private pourra être accédée par un objet.

public static void main(String[] args){
  UneClasse objet = new UneClasse();
  objet.prix = 18.55;
  objet.nom_article = "pantalon";
  ...
}

Une variable peut être utilisée seulement à partir de sa méthode d'appartenance, c'est le cas des variables locales ou également appelées automatiques.
Elles ont une durée de vie limitée, le temps d'exécution d'une méthode.
Par ailleurs, le seul modificateur accepté pour ces variables, est final.

Exemple
public class Variable {
  static String chaine;
  private String chaine2;
  public String chaine3;

  public static void main(String[] args){
    int i;
    String valeur, temp = "";
    Variable objet = new Variable();

    if(args.length > 0)
      for(i = 0; i < args.length; i++)
        temp += " " + args[i];
    else
      temp = "Valeur par defaut";

    // La variable statique chaine est exploitable
// par toutes les méthodes de la classe
chaine = temp; // chaine2 ne peut être utilisé directement dans
// une méthode statique comme suit chaine2 = temp;,
// par contre suite à l'instanciation de sa classe,
// la variable devient utilisable par le biais de son objet.
objet.chaine2 = temp; // Par l'intermédiaire des arguments, les valeurs
// de variables locales peuvent être transmises à des
// méthodes, lesquels peuvent renvoyer d'autres valeurs.
valeur = objet.affecte(temp); System.out.println("Variable statique : " + chaine); System.out.println("Variable privée : " + objet.chaine2); System.out.println("Variable locale : " + valeur); // Par l'intermédiaire des arguments, les valeurs
// de variables locales peuvent être transmises à des méthodes,
// lesquels peuvent renvoyer d'autres valeurs.
objet.affiche(); } private void affiche(){ String chaine3 = chaine; System.out.println("Variable publique : " + chaine3); } public String transmet(String argument){ String chaine4 = argument; return chaine4; } }

13 / Les modificateurs

Les modificateurs permettent d'affecter un comportement spécifique à une classe, une méthode ou une variable.

Il existe deux catégories de modificateurs :

13.1 / Les modificateurs d'accès

Les modificateurs d'accès déterminent la visibilité des classes, méthodes ou variables par rapport aux autres membres et aux autres classes, ainsi qu'entre les paquetages.

Dans la plupart des cas, il est préférable de restreindre autant que possible la portée des éléments d'un programme Java, dans la mesure où, l'encapsulation est un des concepts fondamentaux de la programmation orientée objet.

En effet, une classe peut être complétement encapsulées en déclarant toutes ses variables privées, mais en permetant aux accesseurs d'accèder à ces dernières et aux mutateurs de les modifier, créant ainsi une interface publique (voir les méthodes d'accès).
De plus, un membre privé peut être accédé par n'importe quel instance de sa classe parente.

Les modificateurs d'accès
Modificateur Description
default Si aucun modificateur d'accès n'est déclaré, le membre ou la classe interne sera accessible pour l'ensemble des classes et sous-classes situées dans le paquetage parent, mais en aucun cas, à l'extérieur de ce dernier.
Une classe est également accessible par toutes les classes d'un même paquetage.
public Un membre public est accessible par tous les membres, y compris ceux hors de sa portée, et tant que la classe parente est elle-même visible.
Une classe interne peut être accédée par toutes les classes dérivées de sa classe mère, y compris celles d'un paquetage différent.
Une classe publique est accessible par toutes les classes de tous les paquetages.
private Un membre ou une classe interne privé est uniquement accessible par sa classe parente.
protected Un membre protégé est seulement accessible par les membres de sa classe parente et par ceux du paquetage parent et tant que la classe parente est elle-même accessible.
Une classe interne protégée est accessible pour toutes les classes étendues de la classe mère, y compris celles d'un paquetage différent.

Les classes ne peuvent être ni privées et ni protégées, hormis les classes internes, celles définies au sein d'une classe.

Le modificateur d'accès par défaut est parfois appelé Friendly (Appellation non-officielle provenant du langage C++).

Les modes d'accès par élément
  Par défaut Privé Protégé Public
Classes Oui Non Non Oui
Classes internes Oui Oui Oui Oui
Interfaces Oui Non Non Oui
Méthodes Oui Oui Oui Oui
Constructeurs Oui Oui Oui Oui
Variables Oui Oui Oui Oui
Membres abstraits Oui Non Non Oui

Ce tableau décrit les modificateurs d'accès possibles pour chaque élément principal d'un programme Java.

En l'absence d'un modificateur, Les constructeurs sont par défaut uniquement accessibles dans le paquetage de la classe parente.
Le modificateur private appliqué au constructeur entraîne l'impossibilité d'instancier sa classe.

Les accès dans les membres d'interfaces (abstraits) ne peuvent être que publiques, et par voie de conséquence, l'accès par défaut est également publique.

interface UneInterface {
  public String uneMethode();
  boolean uneAutreMethode();
  // Les deux méthodes sont publiques
}
Accessibilité depuis un paquetage
Modificateur d'accès Intérieur Extérieur
Héritage Accessible Héritage Accessible
Par défaut Oui Oui Non Non
Private Non Non Non Non
Protected Oui Oui Oui Non
Public Oui Oui Oui Oui

Ce tableau indique comment les autres membres d'un même paquetage ou d'un autre différent, sont capables d'accèder aux membres d'une classe et d'en hériter.

A l'intérieur d'un paquetage, seuls les membres et les classes internes privés ne peuvent être accessibles pour d'autres éléments de ce même paquetage. De même, il est impossible pour ces derniers, d'en hériter.

Depuis l'extérieur d'un paquetage, une des différences concerne les éléments protégés, puisque tout en étant inaccessibles, ils peuvent être hérités par d'autres (classes dérivées) situés dans un paquetage distinct.

package package1; public class UnePremiereClasse { type var_pardefaut; public type var_publique; protected type var_protegee; private type var_privee; public void uneMethode(){ var_pardefaut = valeur; var_publique = valeur; var_protegee = valeur; var_privee = valeur; } } public class UneSecondeClasse { UnePremiereClasse UnObjet = new UnePremiereClasse(); public void uneMethode(){ UnObjet.var_pardefaut = valeur; UnObjet.var_publique = valeur; UnObjet.var_protegee = valeur; } } public class UneSousClasse extends UnePremiereClasse { public void uneMethode(){ var_pardefaut = valeur; var_publique = valeur; var_protegee = valeur; } }
package package2; public class UneQuatriemeClasse { public void uneMethode(){ // Aucun accès à UnePremiereClasse... } } import package1.UnePremiereClasse; public class UneTroisiemeClasse { UnePremiereClasse UnAutreObjet = new UnePremiereClasse(); public void uneMethode(){ UnAutreObjet.var_publique = valeur; } } public class UneAutreSousClasse extends UnePremiereClasse { public void uneMethode(){ var_publique = valeur; var_protegee = valeur; } } public class UneDerniereSousClasse extends UneAutreSousClasse { public void uneMethode(){ var_publique = valeur; var_protegee = valeur; } }

13.2 / Le modificateur abstract

Le modificateur abstract est utilisé dans le but d'identifier des classes et des méthodes abstraites.

[modificateurs] abstract class NomClasse {
  ...
}

L'implémentation d'une classe abstraite est remise à ses sous-classes.

Une classe abstraite ne peut seule, avoir d'instances puisqu'elle ne contient que des informations incomplètes.

Une méthode abstraite ne possède pas de bloc d'instructions encadré par des accolades, lequel est remplacé par un séparateur point-virgule (;).

abstract Type uneMethode([Type Argument...]);

Une méthode abstraite peut posséder un à plusieurs arguments.

Lorsqu'une classe étend une classe abstraite, elle doit implémenter toutes les méthodes abstraites de cette dernière en les outrepassant (overriden), soit de redéclarer la méthode avec les mêmes arguments mais en lui fournissant un bloc d'instructions. Sinon, elles doivent être à nouveau déclarées comme abstraites dans la classe étendue.

Le modificateur final ne peut être utilisé avec des classes ou des méthodes abstraites, sans quoi il serait impossible d’étendre les classes et d’outrepasser les méthodes.

Pour en savoir plus, consultez le chapître Les classes abstraites.

13.3 / Le modificateur final

Le modificateur final est utilisé pour éviter une extension des classes ou une modification des méthodes ou des variables.

Lorsque le modificateur final apparaît dans une déclaration de classe, cela signifie que la classe ne peut être étendue.

final class NomClasse {
  ...
}

Une méthode portant le modificateur final ne peut pas être remplacée dans une sous-classe.

final Type nomMethode {
  ...
}

En outre, une méthode finale pourra être optimisée par le compilateur, puisqu'elle ne peut être sous-classée.

Par ailleurs, les méthodes déclarées avec le modificateur static ou private sont implicitement finales.

Une variable dont le modificateur est final, signifie que cette variable sera une constante aussitôt après son affectation.

final Type nomVariable;
nomVariable = valeurConstante;

final Type nomVariable = valeurConstante;

Le modificateur final peut être appliqué aux arguments d'une méthode, ainsi qu'aux variables locales.

void uneMethode(final char unArgument) {
  final int variableLocale = 10;
  for(int i = 0; i < variableLocale; i++) {
    System.out.println(i + " - " + unArgument + "rn");
  }
}

Ce type de déclaration permet l'accès des variables locales ou arguments finaux par des classes intérieures locales.

13.4 / Le modificateur native

Le modificateur native est utilisé dans le but d'identifier une déclaration de méthode native, c'est-à-dire écrite dans un autre langage que Java.

[modificateurs] native Type nomMethode([Arguments]) 
                                                                    throws TypeException;

A l'instar des méthodes abstraites, une méthode native remplace son bloc d'instructions par un point-virgule.

Une méthode native ne peut pas être déclarées avec le modificateur abstract.

Les méthodes natives présentes dans les bibliothèques dynamiques partagées propre à la plateforme de développement, peuvent être accédées par un programme Java à l'aide de l'interface JNI.

Evidemment, en raison de sa connexité avec la plateforme cible, une méthode native n'est pas portable.

13.5 / Le modificateur static

Le modificateur static permet de déclarer une variable, une méthode de classe ou un intialisateur statique, c'est-à-dire que le membre demeure disponible dans une classe entière plutôt que dans un objet spécifique.

Une déclaration de méthodes et de variables de classe permet également de rendre ces derniers, exploitables même si la classe n'a pas été instanciée.

Une variable statiques peuvent être référencées par toutes les instances de sa propre classe ou par l'identificateur de sa classe ele-même.

static type identificateur;

static int nombre = 3;

static String chaine = "Une chaîne de caractères...";

Par exemple, une classe Classe possède une variable statique var et RefClasse1 et RefClasse2 sont des références à des instances de Classe. La variable statique var peut être référencée comme RefClasse1.var, RefClasse2.var et Classe.var. Toutes ces références pointent la même valeur ou le même objet.

Les méthodes statiques sont utilisées uniquement pour accéder aux variables statiques et appeler les méthodes statiques, de sa classe d'appartenance.

public class calcul{
  static int nombre = 0;
  public void calcul(valeur1, valeur2){
    i = valeur1;
    j = valeur2;
  }

  static int compteur(){
    return nombre++;
  }
}

les variables et les méthodes non statiques ne peuvent être respectivement ni accédées et ni appelées par des méthodes statiques.

Une méthode portant le modificateur static ne peut pas être outrepassée.

Les initialisateurs statiques sont des blocs d'instructions encadrées par des accolades sans identificateur, destinés à être exécutés lorsque leur propre classe d'appartenance est chargée et après que les variables statiques soient allouées et initialisées.

static {
  // Bloc d'instructions...
}

public class Increment {
  static int i = 0;
  static int j = 0;
  static int k = 0;

  // Déclaration d'un initialisateur statique
  static {
    System.out.println("Exemple de membres statiquesrn");
    for(;i < 5; i++) {
      System.out.println("i = " + i + "rn");
      j++;
    }
  }

  public static void main(String[] args) {
    for(;j < 10; j++)
      System.out.println("j = " + j + "rn");
    for(;k < 10; k++)
      System.out.println("k = " + k + "rn");
  }
  // A la fin des boucles :
  // j aura parcouru de 0 jusqu'à 4
  // j aura parcouru de 5 jusqu'à 9
  // k aura parcouru de 0 jusqu'à 9
}

Il n'est pas possible d'utiliser la référence this dans les méthodes statiques et encore moins dans les initialisateurs.

13.6 / Le modificateur synchronized

Le modificateur synchronized permet de contrôler l'accès aux objets partagés dans un environnement multi-threads.

Ce modificateur permet d'éviter que plusieurs unités d'exécution (ou threads) puissent accéder simultanément au même objet.

Pour qu'une classe Java soit utilisable en multi-tâches, il est nécessaire qu'elle possède des méthodes synchronized.
En fait, toutes les méthodes de tous les objets doivent être synchronisées pour une utilisation correcte de l'objet dans un environnement multi-threads.

synchronized objet

synchronized (expression){
  ...
}

public void nomMethode(String[] tableau) {
  synchronized (tableau){
    // Instructions...
  }
  ...
}

Dans le cas d'un bloc d'instructions synchronisé, l'objet adéquat est l'argument entre les paranthèses.

Une méthode synchronisée permet d'appliquer un dispositif de verrouillage sur un objet ou sur une classe à partir duquel, elle est appelée.

void synchronized nomMethode(){
  ...
}
//est équivalent à
void nomMethode(){
  synchronized (this){
    ...
  }
}

Dans le cas d'une méthode d'instance synchronisée, l'objet adéquat est représenté par le mot-clé this.

Lorsqu'une thread veut exécuter une méthode d'instance portant le modificateur synchronized, Java verrouille l'instance de classe.
Subséquemment, une autre thread invoquant une méthode synchronisée sur ce même objet, sera bloquée tant que que le verrou ne sera pas levé.

class Calculatrice {
  int x;
  int y;
  ...
  // Ces méthodes synchronisées garantiront que
// les variables x et y ne seront pas modifiées
// durant l'une des opérations
public synchronized float addition(){ return x + y; } public synchronized float soustraction(){ return x - y; } public synchronized float multiplication(){ return x * y; } public synchronized float division(){ return x / y; } ... }

De la même façon, si une thread veut exécuter une méthode de classe (static) portant le modificateur synchronized, Java pose un verrou empêchant un autre thread de solliciter une méthode synchronisée de la même classe.

Dans le cas d'une méthode statique synchronisée, l'objet de classe adéquat est l'instance de java.lang.Class définissant cette méthode de classe.

Les méthodes synchronisées ne peuvent pas s'exécuter en concurrence, leur permettant ainsi de maintenir un état stable dans l'entité partagée.

Lorsque l'exécution d'une méthode synchronized se termine de n'importe quelle manière, le verrou est levé et une autre méthode synchronisée peut alors à son tour être exécutée.

class UniteExecution extends Thread {
  static String message[] = {"Ceci","est","une",
                               "demonstration","de",
                               "Thread","dans","Java."};

  public static void main(String args[]){
    UniteExecution UE1 = new UniteExecution("Premier Thread : ");
    UniteExecution UE2 = new UniteExecution("Second Thread : ");
    UE1.start();
    UE2.start();
    boolean UE1_actif = true;
    boolean UE2_actif = true;
    while(UE1_actif || UE2_actif) {
      if(UE1_actif && !UE1.isAlive()){
        UE1_actif = false;
        System.out.println("UE 1 est inactif.");
      }
      if(UE2_actif && !UE2.isAlive()){
        UE2_actif = false;
        System.out.println("UE 2 est inactif.");
      }
    }
  }

  public UniteExecution(String chaine){
    super(chaine);
  }

  public void run(){
    synchronized(System.out){
      System.out.print(getName());
      for(int i = 0; i < message.length; i++) {
        temporisation();
        System.out.print(message[i]);
        if(i == message.length - 1)
          System.out.println("n");
        else
          System.out.print(" ");
      }
    }
  }

  void temporisation(){
    try {
      sleep(800);
    }
    catch (InterruptedException x){
      System.out.println("Un problème s'est produit !");
    }
  }
}

13.7 / Le modificateur transient

Le modificateur transient permet de déclarer qu'une variable ne peut pas être sérialisée.

transient Type nomVariable;

Ainsi, les méthodes gérant la persistance d'un objet ne prennent pas en compte ce type de variable.

Ce modificateur est particulièrement adapté pour la protection de données sensibles, dans la mesure ou il empêche leur écriture dans un flux.

D'autre part, les variables transientUn champ transient sert à indiquer aux méthodes qu'elle ne fait pas partie de la persistance de l'objet. Cette fonctionnalité n'a été mise en oeuvre qu'à partir de Java 1.1, et sert à éviter de sauvegarder des champs ne servant qu'à des calculs intermédiaires (indices par exemple).

13.8 / Le modificateur volatile

Le modificateur volatile indique qu'une variable de classe ne peut être modifiée de manière asynchrone dans un environnement multiprocesseur.

volatile nomVariable;

Les variables volatiles sont préservées d'une certaine dégradation sous des conditions multichaînées.

Le modificateur volatile permet de s'assurer d'un accès ordonné des unités d'exécutions (ou threads) sur une variable.

Une variable volatile ne peut utiliser le modificateur final.

13.9 / Le modificateur strictfp

Le modificateur strictfp permet de contrôler le comportement de la virgule flottante par rapport au standard IEEE 754 (Standard for Binary Floating-Point Arithmetic).

Le modificateur strictfp ne peut être appliqué qu'à :

Par défaut, les calculs sur les nombres de type double ou float sont effectués d'une façon non stricte dans une classe, une interface ou une méthode. Pour éviter cela, il suffit d'utiliser le modificateur strictfp dans leur déclaration.

strictfp class NomClasse {...}

strictfp interface INomInterface {...}

strictfp type méthode(){...}

L'entité déclarée avec le modificateur strictfp est alors dite FP-strict.

Si une classe est FP-strict, cela implique que ses méthodes sont également FP-strict.

Toutefois, le modificateur strictfp ne peut s'appliquer ni aux méthodes d'interfaces, ni aux constructeurs de classes.

Le modificateur strictfp permet de garantir les mêmes rendus de calculs, quelle que soit la machine virtuelle Java (JVM) sur laquelle l'opération est effectuée.

public strictfp class FPStrict {
  public static void main(String[] args){
    double nb_double = 1e+307;
    System.out.println("nb_double = " + nb_double);

    System.out.println("32.0 * nb_double * 1.0 / 2.0 = " 
                          + 32.0 * nb_double * 1.0 / 2.0);
    // (((32.0 * nb_double) * 1.0) / 2.0)
// ((Infinity * 1.0) / 2.0)
// affiche Infinity en ignorant le reste du calcul
// pourtant l'expression est égale à 16 * nb_double
// soit 1.6e+308
System.out.println("32.0 / 2.0 * nb_double = " 32.0 / 2.0 * nb_double); // ((32.0 / 2.0) * nb_double)
// 16 * nb_double
// affiche 1.6e+308
} }

En principe, le modificateur strictfp devrait conraindre la JVM à évaluer la première expression de telle sorte qu'elle retourne une valeur identique à celle de la seconde expression.

14 / Les méthodes

Les méthodes Java, équivalentes aux fonctions ou aux procédures présentes dans d'autres langages, sont utilisées dans les classes et permettent de définir des opérations à accomplir sur un objet ou dans une classe.

Une méthode est un sous-programme destiné à exécuter un bloc d'instructions suite à son appel dans un programme principal.

Il existe plusieurs types de méthodes dans Java. Elles sont chargées à différentes étapes du déroulement d'un programme, d'effecuer des tâches précises, comme l'initialisation d'un objet nouvellement créé ou l'accès et la manipulation de membres spécifiques.

14.1 / Déclaration et utilisation

Les méthodes sont composées d'un modificateur d'accès optionnel, d'un type de retour, d'un identificateur, d'éventuels arguments entre paranthèses et surtout d'un bloc d'instructions compris entre des accolades.

[modif_acces] type_retour nom_methode([arguments])
                             [throws Classes_Exceptions...]
{
  // Bloc d'instructions...
  [return ValeurDeRetour;]
}

La partie déclarative d'une méthode, soit l'ensemble des éléments précédant le bloc d'instructions délimités par des accolades, s'appelle la signature de la méthode. Cette dernière contient toutes les caractéristiques permettant d'utiliser convenablement les méthodes. Ainsi, on distingue :

Le modificateur d'accès (public, private ou protected) détermine la visibilité de la méthode dans sa propre classe, ainsi que dans d'autres classes et également à l'intérieur ou à l'extérieur de paquetages.

Les méthodes peuvent être également :

Le type permet de spécifier le type de données retourné par la méthode au moyen de l'instruction return. Si cette dernière ne renvoie aucune valeur, alors le mot-clé void devra être indiqué.

void affichage(){
  System.out.println("Une chaîne de caractères...");
}

String concatenation(String chaine){
  chaine += chaine;
  return chaine;
}

Le nom de la méthode correspond aux règles des identificateurs Java.

Les arguments sont facultatifs. Il est possible de passer à une méthode, un à plusieurs arguments (correspondants aux paramètres listés dans la signature de la méthode) pouvant être une constante, une variable, une expression ou encore un appel de méthode retournant une valeur.

L'instruction throws permet de déclarer les classes d'exceptions susceptibles de se produire dans la méthode.

Le bloc d'instructions peut contenir n'importe quelles commandes Java à l'exception d'autres méthodes, mais doit être impérativement terminé par une instruction return, dans le cas ou la méthode renverrait une valeur de retour.

L'utilisation des méthodes d'une classe passe par leur appel dans un programme Java.

Avant tout appel d'une méthode d'instance, il faut instancier la classe concernée afin de produire un objet. Ensuite, cet objet doit être joint par un point au nom de la méthode suivi de ses éventuels arguments entre paranthèses.

// instance de classe
nom_classe nom_objet = new nom_classe();

// appel d'une méthode
nom_objet.nom_methode([arguments...]);

Les méthodes de classe peuvent être accédées directement dans une classe par d'autres méthodes statiques.

14.2 / Le passage des valeurs

Les méthodes peuvent accepter des données provenant de l'extérieur par l'intermédiaire des paramètres, lesquels sont listés entre des parenthèses suivant l'identificateur de la méthode.

modif type méthode([liste_des_paramètres])
{ ... }

Les paramètres sont séparés par des virgules et énoncent pour chacun d'eux, un type et un identificateur.

type méthode(type id, ..., type idN)
{ ... }

Subséquemment, des arguments peuvent être passés si nécessaire à la méthode, lors de son appel dans un programme.

méthode(arg, ..., argN);

Le passage d'arguments devra respecter le sens de l'élargissement des types de données.

class Calculatrice {
  static short arg_a = 10;
  static short arg_b = 25;

  public static void main(String[] args){
    Calculatrice obj = new Calculatrice();
    // appel de la méthode avec passage d'arguments
    //respectant le sens de l'élargissement short -> int
    int res = obj.addition(arg_a, arg_b);
    System.out.println(res);
  }

  // définition de la méthode avec paramètres
  public int addition(int param_a, int param_b){
    return (param_a + param_b);
  }
}

Dans ce cas de figure, les méthodes peuvent recueillir des données de deux façons différentes :

Toutes les données de type primitif (byte, short, char, int, long, float et double) sont passées à une méthode par valeur, c'est-à-dire qu'une copie de la donnée est mise à disposition de la méthode et non l'original.

class Arg {
  int a = 10;
  int b = 20;

  public static void main(String[] args){
    Arg obj = new Arg();
    int resultat = obj.uneMethode(a, b);
    // a vaut toujours 10
    // b vaut toujours 20
  }

  int uneMethode(int x, int y){
    // x vaut 10
    // y vaut 20
    return (++x - ++y);
    // x vaut 11
    // y vaut 21
  }
}

Par conséquent, une méthode ne peut modifier que la copie d'une donnée, sans pour autant affecter la valeur de l'original.

Pour le passage par référence, la méthode reçoit dans ce cas, une copie d'une référence vers un objet.
Mais, cette copie de la référence originale pointe précisément sur le même objet. De cette manière, toutes les opérations produites par la méthode réceptrice, affecte l'objet référencé également par l'argument transmis. Cela peut, donc, conduire à la modification potentielle d'une ou plusieurs valeurs d'attribut de l'objet en cours par la méthode réceptrice.

class Arg {
  String ch = new String("Un texte");
  String ch2 = new String("très bien présenté !");

  public static void main(String[] args){
    Arg obj = new Arg();
    System.out.println("Valeur de l'objet original (avant) : " + obj.ch);
    concatener(obj);
    // ch vaut "Un texte très bien présenté !"
    // ch2 vaut toujours "très bien présenté !"
    System.out.println("Valeur de l'objet original (après) : " + obj.ch);
  }

  static void concatener(Arg objet){
    objet.ch += " " + objet.ch2;
    // objet.ch vaut "Un texte très bien présenté !"
    // objet.ch2 vaut toujours "très bien présenté !"
    System.out.println("Copie d'objet : "+ objet.ch);
  }
}

Toutes les modifications apportées à l'objet passé en argument à une méthode sont permanentes et se répercutent donc dans le reste du programme et cela même si la méthode en question a cessé son activité.

En outre, des méthodes peuvent utiliser des variables définies dans une classe.

Les variables publiques, protégées, privées et par défaut peuvent être accédées de façon directe par n'importe quel méthode, à l'exception des méthodes statiques.

Les variables statiques peuvent être utilisées directement par toutes les méthodes et en particulier par les méthodes statiques.

Toutes les variables accédées de cette manière peuvent subir des modifications directes et permanentes depuis le bloc d'instructions des méthodes.

14.3 / La valeur de retour

Une méthode est capable de retourner une valeur fabriquée localement, d'un type quelconque exploitable à l'endroit où l'appel s'est produit, en général une méthode d'un niveau supérieur.

[modif] type_retour nomMethode([liste_params]){
  // instructions...
  return valeur;
}

A cet effet, une méthode dispose de :

class UneClasse {
  public static void main(String[] args){
    double r = 10;
    double resultat = surface(r);
    System.out.println("Surface d'un cercle de "+ r + "cm : " + resultat);
  }
  public static double surface(double rayon){
    return (Math.pow(rayon, 2) * Math.PI) / 2;
  }
}

L'évaluation de l'instruction return par la Machine Virtuelle Java, entraîne l'arrêt immédiat de l'exécution de la méthode courante, ainsi que le transfert le résultat de l'expression à l'appelant.

Il est possible de placer plusieurs instructions return dans une méthode, mais à l'unique condition que chaque commande de ce type soit placée dans une structure conditionnelle.

class UneClasse {
  public static void main(String[] args){
    double v = 10;
    char t = 'd';
    System.out.println("Surface d'un cercle d'un " 
                       + (t == 'r' ? "rayon" : "diametre") 
                       + " de " + v + "cm : " + surface(v, t) + "cm2");
  }
  public static double surface(double val, char type){
    if(type == 'r')
        return (Math.pow(val, 2) * Math.PI) / 2;
    else if(type == 'd')
        return (Math.pow(val, 2) * 2 * Math.PI) / 4;
    else
        System.out.println ("Le type de la valeur n'a pas été spécifiée !");
        return 0.0;
  }
}

Une méthode peut retourner aussi bien une valeur primitive (char, int, double, etc.) qu'un objet (String, Vector, File, etc.).
Dans le premier cas, une copie de valeur est réalisée entre le résultat produit par la méthode appelée et l'éventuelle variable, méthode ou expression destinée à recevoir ce résultat.
Dans le second cas, c'est une copie de la référence de l'objet résultant qui est accomplie. De cette manière, lorsque la méthode appelée cesse son activité, la référence d'origine est détruite, mais l'objet reste disponible dans le programme par l'intermédiaire de la copie de référence.

import java.net.*;
import java.io.*;
public class UneClasse {
  public static void main(String[] args) throws IOException {
    URL resCon = saisieAdresse();
    System.out.println ("Protocole : " + resCon.getProtocol() 
              + "\nHote : " + resCon.getHost() 
              + "\nChemin : " + resCon.getPath() 
              + "\nFichier : " + resCon.getFile() 
              + "\nRequete : " + resCon.getQuery());
  }
  public static URL saisieAdresse() throws IOException {
    String url = "http://www.unsite.com/rep/fichier.html?requete=valeur";
    URL adresse = new URL(url);
    return adresse;
  }
}

Il est tout à fait possible de ne pas utiliser la valeur de retour d'une méthode. Cela est souvent le cas dans les méthodes qui ne retourneraient qu'une valeur booléenne indiquant la réussite (true) ou l'échec (false) du traitement.

import java.net.*;
import java.io.*;
public class UnClass {
  public static void main(String[] args) throws IOException {
    URL resCon = saisieAdresse();
    affichage(resCon);
  }
  public static URL saisieAdresse() throws IOException {
    String url = "http://www.unsite.com/rep/fichier.html?requete=valeur";
    URL adresse = new URL(url);
    return adresse;
  }
  public static boolean affichage(URL adr) throws IOException {
    if(!adr.equals("")){
      System.out.println ("Protocole : " + adr.getProtocol() 
                + "\nHote : " + adr.getHost() 
                + "\nChemin : " + adr.getPath() 
                + "\nFichier : " + adr.getFile() 
                + "\nRequete : " + adr.getQuery());
      return true;
    }
    else {
      System.out.println ("L'adresse URL est vide !");
      return false;
    }
  }
}

Si une méthode retourne une valeur, il faut impérativement spécifier un type de retour dans la signature de la méthode, sinon une erreur de compilation se produira indubitablement.

A l'inverse, si une méthode ne renvoie aucune valeur, alors le mot-clé spécial void doit être spécifié afin d'indiquer explicitement cette caractéristique.

14.4 / Les méthodes d'accès

L'encapsulation est un concept fondamental de la programmation orientée objet en fournissant aux classes l'entière responsabilité de la représentation interne de leurs propres données tout en autorisant la manipulation de ces dernières par des méthodes spéciales dites d'accés.

Les méthodes d'accès, appelées accesseur (getter) ou mutateur (setter), fournissent une interface publique permettant de manipuler les membres encapsulés, c'est-à-dire ceux possédant un modificateur d'accès private à partir d'autres classes.

La méthode dite accesseur, permettant de retourner la valeur d'un membre privé, doit avoir comme type de retour, le spécificateur de type de la variable à renvoyer.

Par ailleurs, l'accesseur, en général, ne nécessite pas d'arguments et doit toujours posséder un modificateur publique.

public TypeVariable getNomVariable()
{...}

public class UneClasse {
  public static void main(String[] argv){
    AutreClasse obj = new AutreClasse();
    int nb_AC = obj.getNombre();
  }
}

class AutreClasse {
  private int nombre;
  public int getNombre(){
    return nombre;
  }
}

Une méthode dite mutateur, permettant la modification de la valeur d'un membre privé, doit posséder un paramètre correspondant à la valeur à affecter au membre concerné. En outre, le paramètre doit avoir le même type que le membre privé.

D'autre part, le mutateur, en général, ne retourne pas de valeur et doit toujours posséder un modificateur publique à l'instar de l'accesseur.

public void setNomVariable(TypeVariable ValeurVariable)
{...}

public class UneClasse {
  public static void main(String[] argv){
    AutreClasse obj = new AutreClasse();
    int nouv_nb = 100;
    obj.setNombre(nouv_nb);
  }
}

class AutreClasse {
  private int nombre;
  public void setNombre(int nouveau_nombre){
    nombre = nouveau_nombre;
  }
}

Par convention, il est préférable de nommer spécifiquement les méthodes en les faisant précéder du préfixe get pour un accesseur et du préfixe set pour un mutateur comme dans les exemples précédents.

Si la représentation interne de la classe subit des modifications, c'est-à-dire si les données sont modifiées comme le type ou l'identificateur d'un membre concerné, il est impérativement nécessaire de répercuter les éventuels changements au niveau des méthodes d'accès.

public class UneClasse {
  public static void main(String[] argv){
    AutreClasse obj = new AutreClasse();
    int nouv_nb = 100;
    obj.setNombre(nouv_nb);
    int nb_AC = obj.getNombre();
  }
}

class AutreClasse {
  private int nb_personnels;
    public int getNombre(){
    return nb_personnels;
  }

  public void setNombre(int nouveau_nombre){
    nb_personnels = nouveau_nombre;
  }
}

Les modifications apportées à la classe encapsulée ne peuvent et souvent ne doivent avoir aucun effet sur son utilisation par d'autres classes devant continuer à fonctionner correctement, à condition de ne pas toucher les identificateurs des méthodes d'accès et de vérifier la compatibilité des types des variables, paramètres et arguments concernés.

14.5 / La méthode main

La méthode main constitue la partie principale du programme, permettant l'exécution d'une application Java.

public static void main(String[] args){
  //instructions...
}

public indique que la méthode peut être appelée par n'importe quel objet.

static indique que la méthode est une méthode de classe, c'est-à-dire qu'elle restera accessible même s'il n'existe aucune instance de la classe.

void indique qu'aucune valeur ne sera retournée par la méthode.

L'argument de la méthode main est un tableau d'éléments textuels fournissant le moyen de passer des informations à l'application. Chaque chaîne de caractères du tableau est appelée un argument de ligne de commande.

public class AfficheArguments {
  public static void main (String[] args){
  for (int i = 0; i < args.length; i++)
      System.out.println('args[' + i + '] : ' + args[i]);
  }
}

// Lancement de la classe en ligne de commande
java AfficheArguments Le langage de programmation Java
/* Affichage des arguments de la ligne de commande
args[0] : Le
args[1] : langage
args[2] : de
args[3] : programmation
args[4] : Java */

Les arguments de ligne de commande sont tous les éléments suivants l'identificateur de classe. Ce dernier, les options et la commande java n'en font pas partie.

java [-options] identificateur_classe arguments...

java -verbose:class UneClasse Un argument
/* deux arguments 
args[0] : Un
args[1] : argument */

Lorsque la méthode main est trouvée dans une classe, elle devient la méthode à partir de laquelle démarre automatiquement le programme.

Public class Repetition {
  String balise = "<br>";
  public static void main(String[] args){
    for(int i = 0; i < 10; i++)
      System.out.println(balise);
  }
}

Un programme Java simple ne pourrait contenir qu'une seule classe renfermant une méthode main regroupant les instructions destinées à être exécutées.

D'autre part, il est permis d'utiliser une méthode main() avec un type de retour, mais elle ne sera pas appelée lorsque la classe sera invoquée.

public static String main(String[] args){
  ...
}

14.6 / Les constructeurs

Le constructeur est une méthode spéciale d'une classe, permettant d'initialiser les membres de cette classe et également, d'exécuter différentes opérations initiales définies par le programmeur.

L'instanciation d'une classe (ou la création d'un objet) nécessite l'utilisation de l'opérateur new appelant un constructeur.

NomClasse ref_objet = new Constructeur();

L'identificateur du constructeur doit être en tout point identique à l'identificateur de la classe.

IdentificateurClasse ref_objet = new IdentificateurClasse();

En l'absence d'une déclaration de constructeur dans une classe, le compilateur Java en génère automatiquement un par défaut, lequel n'aura pas d'argument et aucune autre fonction que de créer un objet.

public class UneClasse {
  // Aucun constructeur défini
  ...
}
// est équivalent à
public class UneClasse {
  // Génération automatique de ce constructeur
  public UneClasse(){
    super();
  }
  ...
}

Le modificateur d'accès du constructeur par défaut, est toujours le même que celui de sa classe.

Afin d'éviter cette création automatique, il peut être parfois préférable de déclarer un constructeur mieux adapté aux besoins de la classe.

class NomClasse {
  // méthode constructeur
  modificateur NomClasse([type Paramètre, ...])
                         [throws ClasseExceptions...] {
  // Bloc d'instructions...
  }
}
...
//Instanciation de la classe
NomClasse ref_objet = new NomClasse([Arguments]);

Le constructeur doit avoir un identificateur en tout point semblable à celui de sa classe.

Les constructeurs peuvent être déclarés avec un modificateur d'accès public, protected, par défaut ou private.
Les constructeurs sont par défaut uniquement accessibles dans le paquetage de la classe parente.
Le modificateur private entraîne l'impossibilité d'instancier la classe du constructeur et également de l'étendre.

Un constructeur ne peut être déclaré avec les modificateurs suivants : abstract, static, final, native, synchronized, ou strictfp.
Si la classe est FP-Strict, le constructeur l'est également implicitement.

Le constructeur ne peut retourner une valeur, et donc, sa déclaration ne contient aucun type de retour. En fait, l'instance de l'objet est toujours le type retourné par un constructeur.

Le constructeur peut posséder un à plusieurs paramètres permettant notamment l'affectation des champs de l'objet avec des valeurs fournies par l'utilisateur.

class Article {
  int idProduit;
  float prix;
  float reduction;

  Article(int idProduit, float prix, float reduction) {
    this.idProduit = idProduit;
    this.prix = prix;
    this.reduction = reduction;
  }
}

Article livre = new Article(9782212075021, 55.0, 5.0);

La clause throws optionnelle permet d'indiquer que le constructeur peut déclencher les exceptions spécifiées.

La définition d'un constructeur doit apparaître au moins une fois dans une classe, mais n'est en aucun cas une nécessité absolue, dans la mesure où aucune initialisation particulière ne serait nécessaire au démarrage de l'objet.

Parfois, il est utile de définir dans une classe, plusieurs constructeurs avec des signatures distinctes (voir La surcharge des méthodes). Cela permet d'initialiser un objet de plusieurs façons différentes.

class Article {
  String nomProduit;
  int idProduit;
  float prix;
  float reduction;

  public Article(int idProduit, float prix, float reduction) {
    this.idProduit = idProduit;
    this.prix = prix;
    this.reduction = reduction;
  }

  public Article(String nomProduit, float prix, float reduction) {
    this.nomProduit = nomProduit;
    this.prix = prix;
    this.reduction = reduction;
  }
}
...
Article livre = new Article(9782744090004, 329.0, 0.0);

Article livre = new Article("Maîtrisez Java 2", 329.0, 0.0);

Utilisé avec des constructeurs multiples, le mot clé this contient la liste des arguments correspondant à la liste des paramètres d'un des constructeurs de la classe en cours, permettant d'abréger la rédaction des affectations dans les définitions suivantes.

import java.util.*;
import java.text.*;

class UneClasse {
  String date_envoi;
  String expediteur;

  String destinataire;

  public UneClasse(String dest, String exp){
    Date date_actuelle = new Date();
    DateFormat formatage =
             DateFormat.getDateInstance(DateFormat.FULL, Locale.FRANCE);
    date_envoi = formatage.format(date_actuelle);
    expediteur = exp;
    destinataire = dest;
    System.out.println("nUneClasse(String String)");
    System.out.println("Date : " + date_envoi);
    System.out.println("Expéditeur : " + expediteur);
    System.out.println("destinataire : " + destinataire);
  }
  public UneClasse(int jm, int mm, int aaaa,
                            String dest, String exp){
    this(dest, exp);
    date_envoi = jm + "/" + mm + "/" + aaaa;
    System.out.println("nUneClasse(int int int String String)");
    System.out.println("Date : " + date_envoi);
    System.out.println("Expéditeur : " + expediteur);
    System.out.println("destinataire : " + destinataire);
  }
  public UneClasse(String js, int jm, String mm, int aaaa,
                            String dest, String exp){
    this(dest, exp);
    date_envoi = js + " " + jm + " " + mm + " " + aaaa;
    System.out.println("nUneClasse(String int String int String String)");
    System.out.println("Date : " + date_envoi);
    System.out.println("Expéditeur : " + expediteur);
    System.out.println("destinataire : " + destinataire);
  }
  public UneClasse(int jm, String mm, int aaaa,
                            String dest, String exp){
    this(dest, exp);
    date_envoi = jm + " " + mm + " " + aaaa;
    System.out.println("nUneClasse(int String int String String)");
    System.out.println("Date : " + date_envoi);
    System.out.println("Expéditeur : " + expediteur);
    System.out.println("destinataire : " + destinataire);
  }
  public UneClasse(String dest){
    this(4, 11, 2002, dest, "ADV Consulting");
    System.out.println("nUneClasse(String)");
    System.out.println("Date : " + date_envoi);
    System.out.println("Expéditeur : " + expediteur);
    System.out.println("destinataire : " + destinataire);
  }

  public static void main(String[] args){
    UneClasse obj1 = 
        new UneClasse("adresse destinataire", "adresse expéditeur");
    UneClasse obj2 = 
        new UneClasse(2, 11, 2002, 
                          "adresse destinataire", "adresse expéditeur");
    UneClasse obj3 = 
        new UneClasse("Samedi", 2, "Novembre", 2002, 
                          "adresse destinataire", "adresse expéditeur");
    UneClasse obj4 = new UneClasse("adresse destinataire");
  }
}

Dans des conditions similaires, le mot clé super contient la liste des arguments correspondant à la liste des paramètres d'un des constructeurs de la superclasse, permettant d'invoquer directement ce constructeur à partir de la classe étendue.

import java.util.*;
import java.text.*;

class SousClasse extends SuperClasse {
  String date_envoi;
  String destinataire;

  public SousClasse(String date_complete, String exp){
    this("Madame","MALLET", "Carole", 
                  "1 allee d'Artois", 
                  93330, "Neuilly-sur-Marne");
    date_envoi = date_complete;
    expediteur = exp;
    System.out.println("Date : " + date_envoi);
    System.out.println("Expéditeur : " + expediteur);
    System.out.println("destinataire : " + destinataire);
  }

  public SousClasse(String civilite,
                                String nom,
                                String prenom,
                                String adresse,
                                int code_postal,
                                String ville){
    super(nom, prenom, adresse, code_postal, ville);
    Date date_actuelle = new Date();
    DateFormat formatage = 
             DateFormat.getDateInstance(DateFormat.FULL, Locale.FRANCE);
    this.date_envoi = formatage.format(date_actuelle);
    this.destinataire = 
                       civilite + " " + super.adresse_expedition;
    System.out.println("Date : " + date_envoi);
    System.out.println("destinataire (SousClasse) :n" 
                             + destinataire);
  }

  public SousClasse(int date_complete, String exp){
    super("144 avenue Saint Antoine", 13015);
    Integer dd = new Integer(date_complete);
    date_envoi = dd.toString();
    expediteur = exp;
    this.destinataire = super.adresse_expedition;
    System.out.println("Date : " + date_envoi);
    System.out.println("Expéditeur : " + expediteur);
    System.out.println("destinataire : " + destinataire);
  }

  public static void main(String[] args){
    SousClasse obj =
                  new SousClasse("Mademoiselle", "DUBOIS", "Laure", 
                                              "99 cours Vitton", 
                                              69006, "Lyon");
    SousClasse obj4 = new SousClasse("02/11/2002", "M. Jean SOUPIR");
    SousClasse obj3 = new SousClasse(29102002, "M. Marc MILLAUD");
  }
}

class SuperClasse {
  static String adresse_expedition;

  public SuperClasse(String nom, 
                                  String prenom, 
                                  String adresse, 
                                  int code_postal, 
                                  String ville){
    adresse_expedition = nom + " " + prenom + "n" 
                             + adresse + "n" 
                             + code_postal + " " + ville;
    System.out.println("Adresse d'expédition (SuperClasse) :n" 
                             + adresse_expedition);
  }

  public SuperClasse(String adresse, int code_postal){
    adresse_expedition = "Societe ADV Internet Consuting" 
                             + adresse + "n" 
                             + code_postal + " " + "Marseille";
    System.out.println("nAdresse d'expedition (SuperClasse) 
                             + adresse_expedition);
  }
}

Si this et super doivent être utilisés dans des constructeurs, il faut qu'ils apparaissent en tant que première instruction. Par voie de conséquence, il n'est possible d'utiliser qu'un seul de ces mots clés dans une définition de constructeur.

La liste des arguments du mot-clé this ou super provoquera respectivement l'appel du constructeur de la classe ou de la superclasse possédant les paramètres appropriés.

D'autre part, la liste des arguments présentées par les mots clés this et super, doit correspondre parfaitement à l'énumération des paramètres du constructeur référence (types, nombre et séquence des paramètres).
L'identificateur de chaque paramètre n'a aucune importance.

Un appel explicite du constructeur d'une superclasse doit être effectué avec le mot clé super dans les constructeurs des classes étendues, si cette superclasse ne possède pas de constructeur sans arguments.

14.7 / La surcharge des méthodes

Le polymorphisme consituant un concept majeur de la programmation orientée objet, la surcharge (overload) des méthodes est l'une des représentantes de cette particularité dans le langage Java.

Si deux méthodes possédent un nom semblable mais différentes signatures, le nom de ces méthodes est dit surchargé.

Chaque méthode se distingue par une signature spécifique, c'est-à-dire :

modif type_retour nom(type param, ..., type paramN)
{ ... }
int calculer(float somme, int pourcentage)
{ ... }

Le type de retour ne fait pas partie de la signature d'une méthode car lors de l'appel d'une méthode, rien ne suggère au compilateur quel est le type de retour attendu.

class UneClasse {
  public int uneMethode(int un_parametre){
    // Bloc d'instructions...
  }
  public long uneMethode(int un_parametre){
    // Bloc d'instructions...
  }
}
...
UneClasse obj = new UneClasse();
System.out.println(obj.uneMethode(100));
// Quelle méthode est attendue ?
// De plus, une erreur se produit lors de la
// compilation de la classe UneClasse.

Il n'existe aucune contrainte à propos des types de retour à condition que les méthodes aient des signatures strictement différentes, sinon le compilateur générera une erreur.

Les clauses d'exceptions throws des deux méthodes surchargées n'ont aucune incidence sur la validité de la surcharge.

Les méthodes peuvent être déclarées dans une même classe ou provenir de l'héritage d'une superclasse, ou l'une est déclarée dans une classe et l'autre héritée d'une superclasse.

Ainsi dans une classe ou dans une hiérarchie de classes, plusieurs méthodes peuvent posséder un nom identique si leurs paramètres sont différents.
Si des méthodes possèdent des paramètres identiques mais sont déclarées dans des classes distinctes, les méthodes sont dites outrepassées (voir L'outrepassement des méthodes).

void calcul()
{ // instructions... }

void calcul(int valeur, int autre_valeur)
{ // instructions... }

void calcul(float valeur, int autre_valeur)
{ // instructions... }

// Appels des méthodes
operation.calcul();

operation.calcul(100);

operation.calcul(12.3, 4);

Les méthodes surchargées peuvent avoir un type de retour et des modificateurs distincts à condition que leurs paramètres soient différents.

void calcul()
{ // instructions... }

public int calcul(int parametre)
{ // instructions... }

protected double calcul(int argument, double autre_argument)
{ // instructions... }

Toutefois, deux méthodes ne peuvent avoir un nom et des paramètres identiques avec un type de retour différent. Dans ce cas, le compilateur Java générera une erreur.

int calcul(int parametre)
{ // instructions... }

double calcul(int parametre)
{ // instructions... }
// Ceci entrainerait une erreur de compilation !

Dans sa propre classe, une méthode privée peut être surchargée sans problème. De même, une méthode de même nom peut être créée dans une classe héritée sans provoquer d'erreur de compilation ou d'exécution.

class Prog {
  static String l_argument = "";
  static char caracteres[];
  public static void main(String[] args){
    if(args.length > 0)
      for(int i = 0; i < args.length; i++)
        l_argument += args[i] + " ";
    else
        l_argument = "Les arguments sur la ligne de commande !";
    caracteres = l_argument.toCharArray();
    UneClasse ref_obj = new UneClasse();
    ref_obj.uneMethode(l_argument);
    ref_obj.setMethodeCl(caracteres[0]);
    // erreur de compilation due à un
// appel directe d'une méthode privée
ref_obj.uneMethode(caracteres[0]); } } class SuperClasse { private void uneMethode(String un_parametre){ System.out.println("Methode privee(SuperClasse) : " + un_parametre); } private void uneMethode(char un_parametre){ System.out.println("Methode privee(SuperClasse) : " + un_parametre); } public void setMethodeS1(String param){ uneMethode(param); } public void setMethodeS2(char param){ uneMethode(param); } } class UneClasse extends SuperClasse { public void uneMethode(String un_parametre){ System.out.println("Methode privee(UneClasse) : " + un_parametre); super.setMethodeS1(un_parametre); } private void uneMethode(char un_parametre){ System.out.println("Methode publique(UneClasse) : " + un_parametre); super.setMethodeS2(un_parametre); } public void setMethodeCl(char un_parametre){ uneMethode(un_parametre); } }

D'ailleurs, les méthodes statiques peuvent également être surchargées sans aucune contrainte.

La surcharge des méthodes s'applique de la même façon aux constructeurs. Ainsi, il devient possible à une classe de posséder plusieurs constructeurs permettant de paramétrer différemment un objet lors de sa création.

class Article {
  int idProduit;
  float prix = 0.0f;
  float reduction = 0.0f;

  Article(int idProduit, float prix, float reduction) {
    this.idProduit = idProduit;
    this.prix = prix;
    this.reduction = reduction;
  }
  Article(int idProduit) {
    this.idProduit = idProduit;
  }
}

Dans le cas des constructeurs, il n'existe pas de type de retour. Donc, la surcharge ne tient compte que du nom et des paramètres de ce genre particulier de méthodes.

14.8 / L'outrepassement des méthodes

L'outrepassement (overriding) des méthodes représente l'autre mode d'implémentation du polymorphisme dans le langage Java, permettant la redéfinition du comportement d'une ou plusieurs méthodes d'une superclasse, à partir d'une classe étendue.

Une méthode d'instance (public, protected ou par défaut) déclarée dans une superclasse peut être outrepassée (override) dans une autre classe :

Une méthode statique déclarée dans une superclasse ou une interface peut être cachée (hide) par une autre méthode statique :

Une méthode de classe cache donc toutes les méthodes statiques de même signature déclarées en amont de la classe en cours.

Malgré la différence précitée entre les méthodes d'instance et de classe, les règles d'outrepassement sont exactement les mêmes dans les deux cas.

Une erreur de compilation se produit si une méthode d'instance tente d'outrepasser une méthode statique et inversement.

class SuperClasse {
  static void methodeClasse(){
    ...
  }
}
class ClasseDerivee extends SuperClasse {
  // erreur de compilation
  public void methodeClasse(){
    ...
  }
}

L'outrepassement (parfois remplacement) est autorisé si les deux méthodes possèdent un nom, une liste de paramètres et un type de retour identiques, mais l'une (méthode d'origine) doit être localisée dans une superclasse et l'autre (méthode outrepassée) dans une classe dérivée.

class UneClasse {
  modificateur type uneMethode(type un_parametre)
                                  [throws ClasseException] {
    ...
  }
}

class UneClasseEtendue extends UneClasse {
  modificateur type uneMethode(type un_parametre)
                                  [throws ClasseException] {
    ...
  }
}

Les identificateurs des paramètres peuvent être différents dans les deux méthodes sans avoir aucune incidence sur le bon fonctionnement du programme.
Par contre, les paramètres doivent posséder exactement les mêmes types et le même ordre que dans la méthode à outrepasser.

Le modificateur d'accès de la méthode outrepassée ne doit pas être plus restrictif que celui de la méthode de la superclasse.

Méthode d'origine Méthode outrepassée
par défaut par défaut, protected ou public
protected protected ou public
public public

Sémantiquement, une méthode de superclasse privée entraîne une impossiblité d'appliquer une surcharge ou un outrepassement à partir d'une classe étendue puisqu'elle ne peut être héritée par une sous-classe.
Cependant techniquement, une sous-classe peut parfaitement posséder une méthode d'une signature identique à une autre déclarée avec le modificateur d'accès private dans une superclasse sans engendrer d'erreur. Mais dans ce cas, aucune relation n'existe entre les deux méthodes.

En outre, une méthode de superclasse ne peut être outrepassée pour devenir privée dans une classe étendue.

De même, une méthode finale ne peut être outrepassée car elle ne peut être modifiée.

Par ailleurs, s'il existe une clause throws dans la déclaration de la méthode d'origine, celle outrepassée doit obligatoirement spécifier les mêmes types d'exceptions afin d'éviter tout conflit conduisant fatalement à une erreur de compilation.

Parfois, il peut être utile de pouvoir appeler la méthode de la superclasse, outrepassée dans la classe en cours. Cela est possible en utilisant le mot-clé super faisant référence à la superclasse.

class SuperClasse {
  public void uneMethode(String un_parametre){
    System.out.println("SuperClasse : " + un_parametre);
  }
}

class UneClasse extends SuperClasse {
  public void uneMethode(String un_parametre){
    System.out.println("UneClasse : " + un_parametre);
  }
  public void uneMethodeDeSuperClasse(String un_parametre){
    super.uneMethode(un_parametre);
  }
}

class Prog {
  public static void main(String[] args){
    String l_argument = "";
    if(args.length > 0) {
      for(int i = 0; i < args.length; i++){
        l_argument += args[i] + " ";
      }
    }
    UneClasse ref_obj = new UneClasse();
    ref_obj.uneMethode(l_argument);
    ref_obj.uneMethodeDeSuperClasse(l_argument);
    // affiche :
    //  UneClasse : argument...
    //  SuperClasse : argument...
  }
}

Le mot-clé super ne peut être utilisé que pour appeler une méthode dans la classe immédiatement supérieure. Par exemple, si une troisième classe héritait de la classe UneClasse, le mot-clé super ne pourrait être utilisé deux fois (super.super.methode()) pour appeler directement la méthode de la classe SuperClasse.

class UneTroisiemeClasse extends UneClasse {
  public void uneMethode(String un_parametre){
    System.out.println("UneTroisiemeClasse : " + un_parametre);
  }
  public void uneMethodeDeSuperSuperClasse(String un_parametre){
    // formulation incorrecte
    super.super.uneMethode(un_parametre);
    // formulation correcte
    super.uneMethodeDeSuperClasse(un_parametre);
  }
}

15 / Référence à l'objet courant

Les mots clés This et Super sont utilisés pour faire référence à un membre courant, respectivement dans la classe et dans la superclasse en cours.

Ces mots-clés permettent de manipuler des membres ou des méthodes provenant d'une classe courante ou d'une classe parente.

15.1 / Le mot clé this

Le mot clé this permet de faire référence à l'objet en cours.

Le mot clé this permet de désigner des variables définies dans une classe, à partir d'une méthode.

this.nomVariable;

public class NomClasse{
  int x = 10;
  public void methode(int x){
    /* affecte la valeur de l'argument 'x' de 
      la méthode à la variable de classe 'x' */
    this.x = x;
    System.out.println(this.x);
  }
}

Il n'est pas nécessaire d'utiliser le mot clé this, lorsque les identificateurs de variables et d'arguments ne présentent aucune équivoque.

En fait, le mot clé this, constituant une variable système, est passé subrepticement en argument, à chaque méthode d'une classe, si bien qu'implicitement, chaque variable définie dans la classe porte la variable this.

15.2 / Le mot clé super

Le mot clé super permet de faire référence à l'objet parent.

Le mot-clé super permet de désigner des membres de la superclasse, et partant de manipuler ces derniers à partir d'une sous-classe.

super.nomVariable

super.nomMethode()

Ce mot clé peut également être utilisé avec une liste d'arguments optionnels pour appeler le constructeur de superclasse.

super(Arguments, ...);

16 / Les intialisateurs

Un intialisateur (ou initialiseur) est un bloc d'instructions encadré par des accolades, destiné à être exécuté juste avant le constructeur d'une classe.

{
  // Bloc d'instructions...
}

class NomClasse {
  String a, b, c, d, resultat;

  {
      a = "Initialisation";
      b = "avant";
      c = "le";
      d = "constructeur";
  }

  public NomClasse(){
    resultat = a + " " + b + " " + c + " " + d + " ";
  }

  public static void main(String[] args) {
    NomClasse objet = new NomClasse();
    objet.affiche(objet.resultat);
  }

  static void affiche(String chaine){
    System.out.println(chaine);
  }
}

Lors d'une instanciation de classe, les initialisateurs de cette dernière sont exécutés immédiatement avant le constructeur.

Un initialisateur statique est un bloc d'instructions encadré par des accolades possédant un modificateur static.

static {
  // Bloc d'instructions...
}

Les initialisateurs statiques ne s'intéressent qu'à des variables ou des méthodes portant le modificateur static.

class NomClasse {
  static String a = "variable statique a.";
  static String b;
  String c = "Variable par défaut c";
  String d;

  // Exécuté en premier
  static {
    b = "variable b initialisee dans l'initialisateur statique.";
    affiche(b);
  }

  // Exécuté en troisième
  public NomClasse(){
    d = "variable initialisee dans le constructeur";
    System.out.println(d);
  }

  public static void main(String[] args) {
    // Exécuté en second
    affiche(a);
    NomClasse objet = new NomClasse();
    // Exécuté en quatrième
    objet.affiche(objet.c);
    NomClasse objet2 = new NomClasse();
    // Exécuté en dernier
    objet2.affiche(objet2.d);
  }

  static void affiche(String chaine) {
    System.out.println(chaine);
  }
}

Lors d'une instanciation de classe, les initialisateurs statiques sont exécutés après que les données statiques soient allouées et avant le constructeur.

Les intialisateurs statiques permettent de lancer des traitements uniquement pour la première instance d'une classe, car ils ne sont exécutés qu'une seule fois.

Les initialisateurs statiques se révélent également utiles pour l'initialisation complexes de variables statiques.

17 / Les classes

Les classes constituent le fondement de la programmation Java. Toutes les méthodes et les variables sont contenues à l'intérieur de classes et existent dans un programme au travers des objets résultant d'instanciations de classes.

Une classe est un modèle qui décrit les données et les comportements associés aux instances de ces classes.

Les données associées à une classe ou à un objet sont stockées dans des variables et le comportement associé à une classe ou à un objet est défini par des méthodes.

Une instanciation de classe permet de créer un objet possédant des aspects et des perceptions semblables aux autres instances de la même classe. Une instance de classe constitue un synonyme d'objet.

17.1 / Déclaration de classe

La déclaration d'une classe constitue une étape essentielle de la programmation orientée objet, et partant, du développement en langage Java.

La déclaration d'une classe s'effectue par l'intermédiaire du mot clé class.

modificateur class Identificateur {
  //Bloc d'instructions...
}

Les modificateurs possibles pour une classe de haut niveau ne peuvent être que :

Le modificateur d'accès public permet de rendre la classe accessible à travers toutes les classes de tous les paquetages. Une seule et unique classe peut être publique dans un fichier source.

D'autres modificateur d'accès sont possibles comme private, protected ou friendly rendant la classe visible uniquement dans son propre paquetage.

Le modificateur final indique que la classe ne peut être étendue.

Le modificateur abstract indique que la classe est abstraite.

Le mot-clé class permet de commencer la définition d'une classe.

Un nom est spécifié à la classe afin de pouvoir l'identifier dans un programme.

Les accolades délimitent le bloc d'instructions définissant les variables, les méthodes et les éventuelles sous-classes de la classe.

import java.io.*;
import java.lang.*;
import java.util.*;

public class Annuaire {

  public static void main(String[] args) {
    String nomFichier = "annuaire.txt";
    String ligne = null;
    String nom = null
    String prenom = null;
    int telephone = 0;
    try {
      FileReader flux = new FileReader(fichier);
      BufferedReader tampon = new BufferedReader(flux);

      while ( (ligne = tampon.readLine()) != null ){
        StringTokenizer st = new StringTokenizer(ligne, ",");
        nom = st.nextToken();
        prenom = st.nextToken();
        try {
          telephone = new Integer(st.nextToken()).intValue();
        }
        catch (NumberFormatException e) {
          System.out.println("Une exception s'est produite ! : " 
                          + e.getMessage());
          System.out.println("Affichage de la pile :n");
          e.printStackTrace();
        }
        System.out.println(nom + " " + prenom + " : " + telephone);
      }
      tampon.close();
      flux.close();
    }
    catch (IOException e) {
      System.out.println("Une exception s'est produite ! : " 
                        + e.getMessage());
      System.out.println("Affichage de la pile :n");
      e.printStackTrace();
    }
  }
}

17.2 / Conception de classe avec is a et has a

La conception de classe peut recourir à des artifices grammaticaux telles que is a (est un/une) et has a (a un/une ou possède un/une) utilisés dans des descriptions de classes.

La relation is a sous-entend un héritage entre deux classes.

Le chêne est un arbre.
(The oak is a tree.)

La classe chêne hérite de la classe arbre.

class Arbre {
  ...
}
class Chene extends Arbre {
  ...
}

La relation has a sous-entend la possession d'une variable par une classe.

L'arbre a une consommation en eau, une taille,
un nombre de branches et un nombre de feuilles.
(The tree has a water consumption, a size,
a number of branches and a number of sheets.)

La classe Arbre possède quatre variables :
  • consommation_eau en litres,
  • taille en mètres,
  • nombre_branches,
  • nombre_feuilles.
class Arbre { float consommation_eau; float taille; int nombre_branches; int nombre_feuilles; ... }

Les deux artifices peuvent évidemment se combiner pour donner des énoncés plus ou moins complexes.

Le chêne est un arbre qui a une consommation
en eau, une taille, un nombre de branches
et un nombre de feuilles.
(The oak is a tree which has a water consumption,
a size, a number of branches and a number of sheets.)
class Arbre { float consommation_eau; float taille; int nombre_branches; int nombre_feuilles; ... } class Chene extends Arbre { ... }

17.3 / Les objets

Le langage Java permet d'accomplir une programmation orientée objets. Effectivement, un programme Java constitue un groupe d'objets, lesquels possèdent chacun des caractéristiques propres et se complémentent dans le but d'accomplir un travail.

Tous les objets sont issus de classes créées par l'intermédiaire de l'instruction class suivi d'un identificateur.

public class nom_classe{
  //instructions...
}

Un objet est caractérisé par des attributs le décrivant et des comportements représentant ces actions.

Les attributs sont en fait les variables contenues déclarées dans la classe de l'objet.

Les comportements sont les méthodes figurant dans cette même classe.

public class calcul{
  int i = 10;
  int j = 12;
  public void multiplication(){
    System.out.println(i + " * " + j " = " + i * j);
  }
}

/*
  Deux attributs i et j
  Une méthode multiplication
*/

L'utilisation d'un objet dans un programme est possible à condition de déclarer une instance d’un type de classe. Cette opération s'effectue à partir de l'opérateur new affectant une instance de classe à une variable.

nom_classe nom_objet = new nom_classe();

calcul operation = new calcul();

A partir de là, il devient possible d'utiliser les variables et les méthodes de la classe à partir de l'objet.

//premiere_operande = 10
int premiere_operande = operation.i;
//seconde_operande = 12
int seconde_operande = operation.j;
//affiche 10 * 12 = 120
operation.multiplication();

//seconde_operande = 12
operation.j = 24;
//affiche 10 * 24 = 240
operation.multiplication();

Chaque classe contient une méthode spécialisée dénommée constructeur, lequel possède toujours un nom semblable à celui de sa classe et ne peut renvoyer une valeur de retour.

Lors de l'utilisation de l'opérateur new, le constructeur est automatiquement appelé afin d'affecter des ressources telles que la définition et l'initialisation de variables, nécessitées par l’objet.

public class calcul{
  int i = 10;
  int j = 12;
  public void calcul(int val1, int val2){
    i = val1;
    j = val2;
  }
  public void multiplication(){
    System.out.println(i + " * " + j " = " + i * j);
  }
}

calcul operation = new calcul(250, 100);
//affiche 250 * 100 = 25000
operation.multiplication();

17.4 / L'héritage de classe

L'héritage est un concept fondamental de la programmation orientée objet car il permet la création d'une nouvelle classe à partir d'une classe existante.

Dans le langage Java, l'héritage multiple n'est pas possible, puisqu'une classe ne peut posséder qu'une seule et unique superclasse. Par contre, une classe parente peut avoir une à plusieurs sous-classes.

Les classes héritant d'autres classes sont dites dérivées ou étendues, voire même directement appelées des sous-classes et la classe parente est parfois appelée superclasse ou générique.

Le mot-clé extends est utilisé dans une déclaration de classe dérivée, pour spécifier une superclasse.

modificateur_acces SuperClasse {
  //...
}

modificateur_acces class ClasseDerivee extends SuperClasse{
  //...
}

Par défaut, toutes les classes héritent de la superclasse la plus élevée dans la hiérarchie, c'est à dire de la classe Object.

//Hiérarchie de classes pour la classe Applet
java.lang.Object
  |
  +--java.awt.Component
        |
        +--java.awt.Container
            |
            +--java.awt.Panel
                  |
                  +--java.applet.Applet

Une classe dérivée hérite de toutes les méthodes et propriétés de la superclasse. La sous-classe peut ainsi définir de nouveaux membres qui ajouteront de nouvelles fonctionnalités à celles existantes, mais aussi de redéfinir des membres hérités à l'aide de la surcharge des méthodes, du mot clé super ou de la réaffectation des variables.

class super_classe {
  // Déclarations des attributs
  type attribut_1;
  type ...
  type attribut_N;

  // Déclarations des fonctions
  public type nom_methode_1 (type param_1, ..., type param_N){
    //Bloc d'instructions...
  }
  ...
  public type nom_methode_N (type param_1, ..., type param_N){
    //Bloc d'instructions...
  }
}

class nouvelle_classe extends super_classe {
  // Déclarations des nouveaux attributs
  type attribut_1;
  type ...
  type attribut_N;

  // Déclarations des nouvelles fonctions
  public type nom_methode_1 (type param_1, ..., type param_N){
    //Bloc d'instructions...
  }
  ...
  public type nom_methode_N (type param_1, ..., type param_N){
    //Bloc d'instructions...
  }
}

Un mécanisme spécifique appelé liaison dynamique (ou liaison tardive) détermine à l'exécution d'un programme (runtime) quelles sont les méthodes les plus appropriées à appeler, lorsque ces dernières ont été surchargées. Ces méthodes doivent possèder un modificateur d'accès soit public, soit protected. Si les méthodes sont privées, statiques ou finales alors elles sont directement invoquées sans utiliser la liaison dynamique.

class Animal {
  public void manger(){
    //...
  }
  public void seDeplacer(){
    //...
  }
}
class Bison extends Animal {
  public void manger(){
    //...
  }
  public void seDeplacer(){
    //...
  }
  public void brouter(){
    //...
  }
  public void transhumer(){
    //...
  }
}
class Tigre extends Animal {
  public void manger(){
    //...
  }
  public void deplacer(){
    //...
  }
  public void devorer(){
    //...
  }
}
Animal animal = new Animal();
Tigre tigre = new Tigre();
Bison bison = new Bison();

//Appel de la méthode déclarée au sein de la superclasse Animal
animal.manger();

//Appel des méthodes surchargées déclarées au sein des sous-classes
bison.manger();
tigre.manger();

//Appel de la méthode surchargée déclarée au sein de la sous-classe Tigre
animal = tigre;
animal.manger();

//Appel de la méthode surchargée déclarée au sein de la sous-classe Bison
animal = new Bison();
animal.manger();

La JVM se fonde sur le type dynamique d'un objet pour déterminer les méthodes à invoquer et non sur son type référence.

En ce qui concerne les propriétés surchargées, le fonctionnement est radicalement différent.

class Animal {
  public float poids = 0;
}
class Bison extends Animal {
  public float poids = 400;
}
class Tigre extends Animal {
  public float poids = 250;
}
Animal animal = new Animal();
Tigre tigre = new Tigre();
Bison bison = new Bison();

//Appel du champ déclaré au sein de la superclasse Animal
System.out.println(animal.poids;); //0

//Appel des champs surchargés déclarés au sein des sous-classes
System.out.println(bison.poids;); //400
System.out.println(tigre.poids;); //250

//Appel du champ déclaré au sein de la superclasse Animal
animal = tigre;
System.out.println(animal.poids;); //0

//Appel du champ surchargé déclaré au sein de la superclasse Animal
animal = new Bison();
System.out.println(animal.poids;); //0

Lors du processus de compilation, le mécanisme de typage statique contraint les propriétés d'un objet à suivre le type référence de ce dernier.

17.5 / Les classes abstraites

L'utilisation du modificateur abstract dans une déclaration de classe signifie qu'une ou plusieurs des méthodes à l'intérieur du corps de la classe sont déclarées comme abstraites.

abstract modificateur NomClasse {
  modificateur Type NomMethode();
  ...
}

Si une méthode à l'intérieur de la classe est déclarée avec le modificateur abstract, alors cette classe doit être définie explicitement comme abstraite.

abstract modificateur NomClasse {
  abstract modificateur Type nomMethode([Type Arguments, ...]);
  ...
}

Les classes déclarées avec le modificateur abstract ne peuvent être instanciées. Les classes abstraites contraignent à fournir un bloc d'instructions pour chacune de leurs méthodes abstraites à l'intérieur d'une nouvelle classe dérivée, laquelle pourra être instanciée.

abstract modificateur NomClasse {
  modificateur NomMethode();
  ...
}

modificateur_acces ClasseDerivee extends NomClasse {
  modificateur_acces Type nomMethode() {
  // Bloc d'instructions...
  }
  ...
}

Une classe dérivée d'une classe abstraite doit impérativement implémenter toutes les méthodes abstraites de cette dernière, sinon elle doitporter le modificateur abstract dans sa déclaration.

Une interface pouvant être considérée comme étant une classe abstraite, une classe qui en implémente une doit être déclarée abstraite si toutes les méthodes de l'interface n'y sont pas implémentées.

Les classes abstraites sont utilisées pour fournir des méthodes et des variables communes à l'ensemble de leurs sous-classes.

18 / Les interfaces

Une interface est un modèle d'implémentation, permettant de mettre en relation des entités sans rapports.

Dans le langage de programmation Java, une interface, définissant un protocole de comportement, est un élément que des objets sans liens utilisent pour interagir entre eux.

La déclaration d'une interface s'effectue par l'intermédiaire de l'instruction interface.

modificateur_acces interface NomInterface {
  //...
}

Une interface déclarée avec un modificateur d'accès public peut être implémentée par n'importe quelle classe intérieure ou extérieure à son paquetage. A défaut, elle ne pourra être utilisée que dans le paquetage parent.

Par ailleurs, toutes les interfaces portent implicitement le modificateur abstract.

Une interface peut être déclarée avec le modificateur strictfp permettant de contrôler le comportement de la virgule flottante.

Il ne peut exister qu'une seule et unique interface publique par fichier source, à l'instar des classes publiques. Par convention, une interface publique donne son nom au fichier source.

De plus, Java ne permettant pas l'héritage multiple, l'utilisation des interfaces permet de palier à cette carence dans la mesure où une classe peut désormais implémenter plusieurs interfaces.

L'instruction implements permet d'indiquer que la classe fournit une implémentation pour une ou plusieurs interfaces. Ce mot clé doit toujours être placé après la clause d'extension introduite par extends.

class NomClasse implements NomInterface, ..., NomInterfaceN {
  //...
}

Les interfaces possèdent en général dans leur bloc d'instructions, des déclaration de méthodes sans corps ainsi que des déclaration de variables.

// Déclaration de méthode
modificateur_acces Type nomMethode();
// Déclaration de variable
modificateur_acces Type nomVariable = ValeurConstante;

public interface ValidationEnvoi {
  final float TIMBRE = 0.46f;

  public void Poste(float timbre, String adr_exp);
  public boolean PossedeUnTimbre();
  public boolean PossedeUneAdressedExpedition();
  public boolean Envoi();
}

Toutes les méthodes contenues dans une interface sont implicitement déclarées publiques et abstraites.

Les méthodes ne peuvent être déclarées avec les modificateurs final, native, static, et synchronized.

Toutes les variables, en fait des constantes, contenues dans une interface sont implicitement déclarées publiques, statiques et finales et doivent avoir une valeur constante d'affectation.

Les constantes ne peuvent être déclarées avec les modificateurs transient et volatile.

Afin d'éviter une redondance dans les déclarations de méthodes et de constantes, il est inutile de spécifier explicitement les modificateurs par défaut précités.

Toutes les classes implémentant une interface doivent possèder les méthodes déclarées dans cette dernière en y ajoutant toutefois un bloc d'instructions.

public class Lettre implements ValidationEnvoi {
  int nb_timbres = 0;
  String adr_exp = null;
  boolean valide_timbre = false;
  boolean valide_adresse = false;

public void Poste(int timbre, String adr_exp) {
    this.nb_timbres = timbre;
    this.adr_exp = adr_exp;
    System.out.println("Timbre : " + this.timbre + "n" +
                        "Adresse : " + this.adr_exp);
  }

public boolean PossedeUnTimbre() {
    if (nb_timbres > 0)
      return valide_timbre = true;
    else
      return valide_timbre = false;
  }

  public boolean PossedeUneAdressedExpedition() {
    if (adr_exp != null)
      return valide_adresse = true;
    else
      return valide_adresse = false;
  }

  public boolean Envoi() {
    if (valide_timbre && valide_adresse)
      return true;
    else
      return false;
  }

  public float PrixTimbres() {
      return this.nb_timbres * TIMBRE;
  }
}
  
public class Appli {
  public static void main(String args[]) 
    String adresse = "Mlle Julie LAMYrn"
                   + "10 Allée d'Artoisrn"
                   + "93330 Neuilly Sur Marne";
    int affranchissement = 1;

    Lettre envoiLettre = new Lettre();

    envoiLettre.Poste(affranchissement, adresse);

    System.out.println("Adresse d'expedition : " +
        (envoiLettre.PossedeUneAdressedExpedition() ? "Oui" : "Non"));

    System.out.println("Affranchissement : " +
        (envoiLettre.PossedeUnTimbre() ? "Oui" : "Non"));

    System.out.println("Montant de l'affranchissement : " +
        envoiLettre.PrixTimbres() + " €");

    System.out.println("Procedure d'envoi validee : " +
        (envoiLettre.Envoi() ? "Oui" : "Non"));
  }
}

Les interfaces ne peuvent implémenter d'autres interfaces. Par contre, elles peuvent hériter de plusieurs autres interfaces.

public interface NomInterface 
              extends AutreInterface, ..., AutreInterface 
...

Le bloc d'instructions des interfaces contient essentiellement des déclarations de constantes et de méthodes abstraites.

Les interfaces constituent une catégorie particulière des classes abstraites.

19 / Les classes ou interfaces internes

Les classes internes (inner classes) peuvent être situées à différent niveau d'une classe normale. Elles représentent une particularité intéressante et subtile de la programmation avec le langage Java.

class ClasseParente {
  modificateur class ClasseInterne 
                          [extends SuperClasse] 
                          [implements ListeInterfaces] {
    // Instructions...
  }

  modificateur interface InterfaceInterne {
    // Instructions...
  }

  // Instructions...
}

Il existe quatre types de classes imbriquées :

Les interfaces peuvent être également déclarées à n'importe quel endroit d'une classe.

Une classe interne peut définir de la même manière, une à plusieurs autres classes internes.

Les classes internes après la compilation sont enregistrées dans un fichier .class particulier.

ClasseParente$ClasseInterne.class

Les fichiers stockant des classes locales possèdent un format différent incluant un identificateur numérique représentant la méthode d'inclusion.

ClasseExterne$1$ClasseLocale.class

Les classes anonymes sont stockées dans un format distinct incluant, lui aussi, un identificateur numérique représentant l'instance d'inclusion.

ClasseExterne$1.class

De cette façon, le nom d'une classe interne peut être identique à celui d'une autre sans pour autant créer d'ambiguités, lors de l'emploi de l'une ou l'autre des classes.

Chaque type de classes ou interfaces intérieures possèdent des spécifités programmatiques propres.

19.1 / Les classes internes simples

Les classes internes simples sont définies au sein des classes. Elles constituent des membres à part entière des classes d'inclusions au même titre que des variables ou des méthodes.

class ClasseParente {
  ...
  modificateur class ClasseInterne {
    // instructions...
  }
  ...
}

Une classe interne peut être déclarée avec n'importe lequel des modificateurs d'accès (public, protected, par défaut ou private) et les modificateurs spéciaux abstract, final ou static. Les classes possèdant le modificateur static deviennent des classes internes statiques.

Une classe interne déclarée avec le modificateur d'accès private implique que cette classe ne pourra être utilisée que dans sa classe parente.

Les classes internes ne peuvent pas être déclarées à l'intérieur d'initialisateurs statiques ou de membres d'interface.

Les classes internes ne doivent pas déclarer de membres statiques, hormis s'ils comportent le modificateur final, dans le cas contraire, une erreur de compilation se produit.

class Classeinterne {
  static final x = 10; // constante statique
  static int y = 12; // erreur de compilation
  ...
}

Toutefois, les membres statiques de la classe externe peuvent être hérités sans problème par la classe interne.

Les classes imbriquées sont capables d'accéder à toutes les variables et méthodes de la classe parente, y compris celles déclarées avec un modificateur private.

class ClasseParente {
  int x = 10;
  int y = 12;
  private int addition(){
    return (x + y);
  }
  class ClasseInterne {
    void verification(){
      if((x + y)== addition())
        System.out.println("La classe interne a bien accédé "
                          + "aux membres de sa classe parente.");
    }
  }
  public static void main(String[] args){
    ClassParente obj_out = new ClasseParente();
    ClasseInterne obj_in = obj_out.new ClasseInterne();
    obj_in.verification();
  }
}

Cette notation particulière spécifie que l'objet créé est une instance de la classe interne associée à l'objet résultant de l'instanciation d'une classe de plus haut niveau.

L'instanciation de la classe interne passe obligatoirement par une instance préalable de la classe d'inclusion.
La classe parente est d'abord instanciée, puis c'est au tour de la classe interne de l'être par l'intermédiaire de l'objet résultant de la première instance.

ClassParente obj_out = new ClasseParente();
ClasseInterne obj_in = obj_out.new ClasseInterne();
// est équivalent à
ClasseInterne obj_in = (new ClassParente()).new ClasseInterne();

Il est possible d'utiliser une méthode de la classe parente pour créer directement une instance de la classe interne. Toutefois, lors de l'appel de la méthode, il sera nécessaire de créer une instance de la classe d'inclusion.

class ClasseParente {
  int x = 10;
  int y = 12;
  private int addition(){
    return (x + y);
  }
  class ClasseInterne {
    public void verification(){
      if((x+y)== addition())
        System.out.println("La classe interne a bien accédé "
                          + "aux membres de sa classe parente.");
    }
  }
  void rendDisponible(){
    // Création d'une instance de la classe interne
    ClasseInterne obj_in = new ClasseInterne();
    // Appel d'une méthode de la classe interne
    obj_in.verification();
  }
  public static void main(String[] args){
    // Création préalable d'une instance de la classe parente
    ClasseParente obj_out = new ClasseParente();
    // Appel de la méthode instanciant la classe interne
    obj_out.rendDisponible();
  }
}

Cette manière de créer une instance de la classe interne est possible grâce à la référence d'objet this désignant une instance de la classe parente.

ClasseInterne obj_in = new ClasseInterne();
// est équivalent à
this.ClasseInterne obj_in = this.new ClasseInterne();

L'utilisation implicite du mot-clé this permet au constructeur de la classe parente de créer une instance de la classe interne. Le constructeur de cette dernière pourra alors exécuter ses propres instructions.

class ClasseParente {
  int x = 10;
  int y = 12;
  // constructeur externe
  ClasseParente(){
    // Création d'une instance de la classe interne
    new ClasseInterne();
  }
  public static void main(String[] args){
    // Création préalable d'une instance de la classe parente
    new ClasseParente();
  }
  private int addition(){
    return (x + y);
  }
  class ClasseInterne {
    // constructeur interne
    ClasseInterne(){
      if((x + y)== addition())
        System.out.println("La classe interne a bien accédé "
                          + "aux membres de sa classe parente.");
    }
  }
}

Il est possible d'imbriquer des classes sur plusieurs niveaux. Une classe normale peut contenir une à plusieurs classes internes et ces dernières peuvent contenir également une à plusieurs autres classes intérieures.

class ClasseParente {
  int x = 10;
  int y = 12;

  public static void main(String[] args){
  ClasseInterne obj_in = 
                      (new ClasseParente()).new ClasseInterne();
    obj_in.verification();
  }

  private int addition(){
    return (x + y);
  }

  class ClasseInterne {
    public void verification(){
      if((x + y)== addition())
        System.out.println("La classe interne a bien accédé "
                          + "aux membres de sa classe parente.");
        ClasseInterneInterieure obj_inin = 
                        new ClasseInterneInterieure();
        System.out.println(obj_inin.ajouter());
    }
    class ClasseInterneInterieure {
      int z = 10;
      int ajouter(){
        return (z + x);}
    }
  }
}

La classe doublement imbriquée ne peut être instanciée que dans sa classe parente directe.

Les méthodes et les variables d'instance d'une classe interne ne deviennent disponibles dans la classe parente qu'après l'instanciation de cette classe imbriquée.

Parfois, il peut être nécessaire de distinguer les variables situées dans les classes interne et externe.

class Externe {
  int x = 10;
  int y = 12;
  Externe(){
    new Interne();
  }
  public static void main(String[] args){
    new Externe();
  }
  class Interne {
    int x = 8;
    int y = 14;
    Interne(){
      if(this.x + this.y == Externe.this.x + Externe.this.y)
        System.out.println("La classe interne a bien "
                          + "accédé à l'ensemble des membres "
                          + "des classes imbriquées.");
    }
  }
}

Le mot-clé this permet d'accéder à un membre de la classe en cours, c'est-pourquoi this.variable accède au membre de la classe interne et Externe.this.variable à celui de la classe parente spécifiée.

19.2 / Les classes internes statiques

Les classes internes statiques peuvent accéder à l'ensemble des membres statiques de leur classe parente, à l'instar des méthodes de classe.

class ClasseParente {
  static int x = 10;
  static int y = 12;
  // La classe interne statique ne 
  // peut accèder à cette variable
  int z = x + y;
  static int addition(){
    return (x + y);
  }
  // La classe interne statique ne 
  // peut accèder à cette méthode
  int resultat(){
    return (z);
  }
  static class ClasseInterne {
    ClasseInterne(){
      if((x + y)== addition())
        System.out.println("La classe interne a bien accédé aux "
                          + "membres statiques de sa classe parente.");
    }
  }
  public static void main(String[] args){
    new ClasseInterne();
  }
}

Il n'est pas nécessaire de créer une instance de la classe parente pour pouvoir instancier la classe intérieure statique contrairement aux classes internes simples.

Il est possible de créer une instance d'une classe interne par l'instruction suivante :

new ClasseParente.ClasseInterne()

Le mot-clé this n'est pas utilisable dans le contexte des classes internes statiques, et partant, celles-ci n'ont pas accès aux variables et méthodes non-statiques de leur classe d'inclusion.

Les méthodes d'une classe interne statique peuvent être accédées dans la classe parente de la même façon que les classes internes simples, c'est-à-dire, suite à l'instanciation de leur propre classe.

class ClasseParente {
  static int x = 10;
  static int y = 12;
  static int addition(){
    return (x + y);
  }
  static class ClasseInterne {
    void verification(){
      if((x + y)== addition())
        System.out.println("La classe interne a bien accédé aux "
                          + "membres statiques de sa classe parente.");
    }
  }
  public static void main(String[] args){
    ClasseInterne obj_in = new ClasseInterne();
    obj_in.verification();
  }
}

19.3 / Les classes locales

Une classe locale est définie à l'intérieur d'une méthode, et partant, agît librement et essentiellement au sein de cette dernière.

modificateur class UneClasse {
  modificateur type_retour uneMethode([Liste de paramètres]){
    class UneClasseLocale {
      // instructions...
    }
  }
}

Il n'est possible de déclarer des classes locales, dont la portée est limitée au bloc, qu'avec les modificateurs final ou abstract. Les modificateurs suivants : public, protected, private et static, sont interdits.

Les données membres d'une classe externe peuvent être accédés par la classe locale.

class ClasseExterne {
  int x = 10;
  int y = 12;
  int z = x + y;
  void addition(){
    class ClasseLocale {
      boolean verification(){
        if(x + y == z)
          return true;
        else
          return false;
      }
    }

    ClasseLocale obj_in = new ClasseLocale();
    if(obj_in.verification()){
      x = x + y;
      System.out.println("La classe interne a bien accédé aux "
                          + "membres de la classe extérieure.n"
                          + "x = " + x + "ny = " + y + "nz = " + z);
     }
     else 
       System.out.println("Erreur !");

   }
   public static void main(String[] args){
     ClasseExterne obj_out = new ClasseExterne();
     obj_out.addition();
  }
}

Seules les variables locales et les paramètres de la méthode d'inclusion, déclarées avec le modificateur final, peuvent être exploitées par les classes internes locales, sinon une erreur se produit lors de la compilation. De plus, ces variables doivent être impérativement assignées avant leur emploi dans la classe locale.

class ClasseExterne {
  int x = 10;
  int y = 12;
  // Paramètre constant utilisable par la classe locale
  ClasseExterne(final int p){
    // Constante utilisable par la classe locale
    final int a = 20;
    // Variable inutilisable par la classe locale
    int b = 44;
    class ClasseLocale {
      boolean verification(){
        if(x + y == a + p)
          return true;
        else
          return false;
      }
    }

    ClasseLocale obj_in = new ClasseLocale();
      if(obj_in.verification()){
        x = x + y;
        System.out.println("La classe interne a bien accédé aux "
                          + "membres de la classe extérieure.n"
                          + "x = " + x + "ny = " + y + "na = " + a);
      }
      else 
        System.out.println("Erreur !");
  }
  public static void main(String[] args){
    ClasseExterne obj_out = new ClasseExterne(2);
  }
}

Lorsqu'une classe locale est déclarée dans une méthode statique, alors les variables d'instances de la classe externe ne sont plus accessibles pour la classe imbriquée.

class ClasseExterne {
  static int x = 10;
  static int y = 12;
  static int z = x + y;
  static void addition(){
    class ClasseLocale {
      boolean verification(){
        if(x + y == z)
          return true;
        else
          return false;
      }
    }

    ClasseLocale obj_in = new ClasseLocale();
    if(obj_in.verification()){
      x = x + y;
      System.out.println("La classe interne a bien accédé aux "
                          + "membres statiques de la classe extérieure.n"
                          + "x = " + x + "ny = " + y + "nz = " + z);
     }
     else 
       System.out.println("Erreur !");

    }
    public static void main(String[] args){
    addition();
  }
}

Seules, les variables statiques de la classe externe peuvent être exploitées par la classe localisée dans la méthode statique.

L'utilisation d'une classe locale ne dépend pas de l'instanciation d'une classe externe, contrairement aux classes internes simples. Autrement dit, il n'est donc pas utile d'instancier d'abord la classe externe pour instancier ensuite la classe locale.

19.4 / Les classes anonymes

Les classes anonymes (anonymous classes) sont déclarées immédiatement après l'expression d'instanciation d'une classe, permettant directement d'étendre ou d'implémenter respectivement la classe ou l'interface instanciée.

new Classe([Liste d'arguments]) {
  // Instructions de la classe anonyme...
};

new Interface() {
  // Instructions de la classe anonyme...
};

La déclaration d'une classe anonyme doit être toujours suivie d'un point virgule immédiatement après son accolade fermante, sans quoi une erreur de compilation serait générée.

Les classes anonymes obéissent aux mêmes restrictions que les classes locales et de plus, ne peuvent ni être abstraites (abstract) ni être statiques (static).
Par contre, elles portent toujours implicitement le modificateur final.

En fait, aucun modificateur n'est permis dans une déclaration de classe anonyme.

Dans le cas d'une extension, la classe anonyme doit outrepasser une à plusieurs des méthodes de la classe à instancier. La surcharge et la définition d'une nouvelle méthode ne sont pas permis sinon elles provoqueraient une erreur de compilation.

class ClasseExterne {
  static int x = 10;
  static int y = 12;
  public static void main(String[] args){
    Calcul obj = new Calcul() {
      float resultat;
      public float addition(float a, float b) {
        resultat =  a + b;
        System.out.println(resultat);
        return resultat;
      }
      public float soustraction(float a, float b) {
        resultat =  a - b;
        System.out.println(resultat);
        return resultat;
      }
      public float multiplication(float a, float b) {
        resultat =  a * b;
        System.out.println(resultat);
        return resultat;
      }
      public float division(float a, float b) {
        if(b != 0){
        resultat =  a / b;
        System.out.println(resultat);
        return resultat;
        }
        else
        return 0;
      }
    };
    obj.addition(x, y);
    obj.soustraction(x, y);
    obj.multiplication(x, y);
    obj.division(x, y);
  }
}

class Calcul {
  public float addition(float a, float b) {
    return a + b;
  }
  public float soustraction(float a, float b) {
    return a - b;
  }
  public float multiplication(float a, float b) {
    return a * b;
  }
  public float division(float a, float b) {
    return a / b;
  }
}

Dans le cas d'une implémentation, la classe anonyme doit définir chacune des méthodes abstraites de l'interface à instancier, sinon une erreur de compilation se produira.

class ClasseExterne {
  static int x = 10;
  static int y = 12;

  public static void main(String[] args){

    ICalcul obj = new ICalcul() {
      public float addition() {
        resultat = (float)(x + y);
        return (float)(x + y);
      }
      public float soustraction() {
        resultat (float)(x - y);
        System.out.println(resultat);
        return resultat;
      }
      public float multiplication() {
        resultat (float)x * (float)y;
        System.out.println(resultat);
        return resultat;
      }
      public float division() {
        if(y != 0){
          resultat = (float)x / (float)y;
          System.out.println(resultat);
          return resultat;
        }
        else
          return 0;
      }
    };

    obj.addition();
    obj.soustraction();
    obj.multiplication();
    obj.division();
  }
}

interface ICalcul {
  float addition();
  float soustraction();
  float multiplication();
  float division();
}

Une classe anonyme ne peut déclarer explicitement un constructeur, le compilateur Java fournissant automatiquement un constructeur anonyme pour ce genre de classe.

Une classe anonyme ne possède pas d'identificateur et est immédiatement utilisée lors de l'instanciation de la classe ou l'interface concernée.

20 / Les paquetages

Un paquetage (package) définit un espace de noms pour un groupe de classes le rendant unique par rapport à d'autres.

De même, il existe une hiérarchie de paquetages, java étant la principale, d'où descendent de nombreuses autres tels que awt, lang et rmi, contenant eux mêmes respectivement color, ref et server.

java
java.awt
java.awt.color
java.lang 
java.lang.ref
java.rmi
Java.rmi.server

Les différents composants d'une arborescence de paquetages sont séparés par un point.

A partir de chacun de ces espaces de noms, il est possible d'appeler les classes correspondantes.

java.awt.colorColorSpace
java.lang.ref.WeakReference
java.rmi.Naming

20.1 / Importation et création de paquetages

Les paquetages peuvent être importés et créés à l'aide d'instructions spécifiques, respectivement import et package.

L'instruction import permet d'importer une à plusieurs classes et interfaces d'un paquetage pour la classe courante.
Pour cela, il suffit de placer cette instruction au début du fichier source contenant la classe.

import NomClasse;
import java.nomPaquetage[.sousPaquetage].NomClasse;

import java.awt.image.ImageFilter;
// Importation de la classe imageFilter

Une étoile (*) placée dans la déclaration permet d'indiquer que toutes les classes et interfaces d'un paquetage sont mises à disposition de la classe en cours.

import java.awt.image.*;
// Fournit toutes les classes pour la création
// et la modifications des images.

Il faut importer explicitement les classes de chaque paquetage pour les besoins d'un fichier source courant, puisque l'étoile ne s'adresse qu'à des classes et non aux sous-paquetages.

import java.awt.*;
// Importe seulement les classes et interfaces du
// paquetage awt et non les autres sous-paquetages.
import java.awt.color.*; import java.awt.font.*; import java.awt.print.*; // Importation explicite des classes et interfaces
// de trois paquetages descendants d'awt.

Par ailleurs, il est également possible de définir son propre paquetage en utilisant l'instruction package. La déclaration d'un paquetage personnalisé se place au tout début d'un fichier source avant les éventuelles instructions d'importation.

package nomPaquetage;

Si cette déclaration est omise, pendant le temps d'exécution, Java crée implicitement un paquetage sans nom par défaut contenant toutes les classes se trouvant dans le répertoire en cours, y compris des classes n'appartenant pas forcément à ce paquetage courant.

Le fait de mentionner un nom de paquetage permettra de créer automatiquement un répertoire portant le nom du paquetage, dans lequel le fichier .class, résultant de la compilation du fichier source (fichier.java), sera placé.

// Compilation
c:\>javac -d c:\classes c:\sources\fichier.java

// Résultat
c:\classes\paquetage\fichier.class

20.2 / La classe Package

La classe Package représente un paquetage Java contenant un ensemble d'interfaces, de classes et d'exceptions.

Elle ne possède pas de constructeurs, mais peut être instanciée par l'intermédiaire de la méthode statique getPackage().

Package paquetage = Package.getPackage("javax.xml.parsers");

Une autre méthode dénommée getPackages() retourne tous les paquetages connus du chargeur de classe en cours, dans un tableau d'objets de type Package.

public class Paquetage {
  public static void main(String[] args) {
    Package[] paquetages = Package.getPackages();
    for(int i = 0; i < paquetages.length; i++){
      System.out.println("Le paquetage " + paquetages[i].getName());
    }
  }
}

Un objet Class dispose également d'une méthode permettant de renvoyer son propre paquetage d'appartenance, à partir de sa méthode d'instance getPackage()

Class obj = Class.forName("java.util.jar");
Package paquetage = obj.getPackage();

La classe Package est essentiellement composer de méthodes retournant des informations sur lui-même (get), et vérifiant des caractéristiques spécifiques (is).

Plusieurs informations relatives à l'implémentation et la spécification du paquetage, peuvent être obtenues sous la forme d'une chaîne de caractères, par les méthodes suivantes :

getImplementationTitle()retourne le titre du paquetage.
getImplementationVendor()retourne le nom de l'organisation, du vendeur ou de la compagnie qui a fournit l'implémentation.
getImplementationVersion()retourne la version de l'implémentation.
getSpecificationTitle()retourne le titre de la spécification que le paquetage implémente.
getSpecificationVendor()retourne le nom de l'organisation, du vendeur, ou de la compagnie qui possèdent et maintiennent la spécification des classes qui implément le paquetage.
getSpecificationVersion()retourne le numéro de version de la spécification que le paquetage implémente.
public class Paquetage {
    public static void main(String[] args) {
      if (args.length > 0){
        Package paquetage = Package.getPackage(args[0]);
        System.out.println(paquetage);
        if(paquetage != null){
          System.out.println("Distributeur implementation : " 
                                      + paquetage.getImplementationTitle());
          System.out.println("Version implementation : " 
                                      + paquetage.getImplementationVendor());
          System.out.println("Titre implementation : " 
                                      + paquetage.getImplementationVersion());
          System.out.println("Titre specification : " 
                                      + paquetage.getSpecificationTitle());
          System.out.println("Distributeur specification : " 
                                      + paquetage.getSpecificationVendor());
          System.out.println("Version specification : " 
                                      + paquetage.getSpecificationVersion());
        }
      }
    }
}

La méthode isCompatibleWith() permet de déterminer si la paquetage en cours est compatible avec le numéro de version de spécification spécifié en argument. Le numéro de version est composé de chiffres entiers séparés par des points ("."), comme par exemple 2.0 ou 1.3.6.

if (isCompatibleWith("2.5.1")){
    //Instructions...
}

Les méthodes isSealed() vérifient si le paquetage courant est scellé. En effet, les fichiers JAR et les paquetages peuvent être optionnellement scellés, de telle sorte qu'un paquetage puisse imposer une uniformité au sein d'une version. Un paquetage scellé dans un fichier JAR indique que toutes les classes définies dans ce paquetage doivent provenir du même fichier JAR. Dans le cas contraire, une exception SecurityException serait lancée.

if (paquetage.isSealed()){
    //Instructions...
}

20.3 / Liste des paquetages

Les paquetages (packages) Java contiennent un ensemble de classes possédant un rapport entre elles et chargées d'accomplir des opérations prédéfinies.

Par exemple, le paquetage java.awt propose de nombreuses classes destinées à élaborer des interfaces graphiques.

Paquetage
Description
java.applet
fournit les classes nécessaires pour créer un applet et ses classes utilisées pour communiquer avec son contexte.
java.awt
contient toutes les classes pour créer des interfaces utilisateurs et pour dessiner des images et des graphiques.
java.awt.color
fournit les classes pour les espaces de couleurs.
java.awt.datatransfer
fournit les interfaces et les classes pour le transfert de données entre et à l'intérieur des applications.
java.awt.dnd
Drag and Drop est une geste de manipulation directe trouvé dans plusieurs systèmes d'interfaces utilisateurs graphiques qui fournissent un mécanisme pour transférer des informations entre deux entités logiques associées avec des éléments de présentation dans le GUI.
java.awt.event
fournit les interfaces et les classes pour les relations entre les différents types d'événements lancés par les composants AWT.
java.awt.font
fournit les interfaces et les classes en relation avec les polices de caractères.
java.awt.geom
fournit les classes Java 2D pour définir et exécuter des opérations sur les objets liés à la géométrie à deux dimensions.
java.awt.im
fournit les interfaces et les classes pour la structure (framework) de méthode d'entrée.
java.awt.im.spi
fournit les interfaces qui active le développement de méthode d'entrée qui peuvent être utilisées avec n'importe quel environnement d'exécution Java.
java.awt.image
fournit les classes pour la création et la modification des images.
java.awt.image.renderable
fournit les interfaces et les classes pour produire des présentations indépendantes d'images.
java.awt.print
fournit les interfaces et les classes pour un API d'affichage général.
java.beans
contient les classes liées au développement de beans des composants basés sur l'architecture JavaBeans™.
java.beans.beancontext
fournit les interfaces et les classes liées au contexte bean.
java.io
fournit pour le système d'entrée/sortie à travers les flux de données, les sérialisations et les fichiers systèmes.
java.lang
fournit les classes qui sont fondamentales pour la conception de langage de programmation Java.
java.lang.ref
fournit les classes d'objet référence, lesquelles suppotent un degré limité d'interaction avec le collecteur garbage collector.
java.lang.reflect
fournit les interfaces et les classes pour l'obtention d'information réflective à propos des classes et des objets.
java.math
fournit les classes pour l'exécution de calculs arithmétiques avec des entiers et des décimaux de précision arbitraire.
java.net
fournit les classes pour l'implémentation d'applications réseaux.
java.nio
définit des tampons (buffers), lesquels sont contenus pour les données et fournissent une vue d'ensemble d'autres packages NIO.
java.nio.channels
définit les canaux, lesquels représentent des connexions à des entités qui sont capables d'exécuter des opérations d'entrée/sortie, comme des fichiers et des sockets.
java.nio.channels.spi
fournit les classes de fournisseur de service pour le packagejava.nio.channels.
java.nio.charset
définit les jeux de caractères, les décodeurs et les encodeurs pour la traduction entre les octets et les caractères Uniocde.
java.nio.charset.spi
définit les classes de fournisseur de service pour le package java.nio.charset.
java.rmi
fournit les interfaces et les classes du package RMI.
java.rmi.activation
fournit le support pour l'activation d'objet RMI.
java.rmi.dgc
Pfournit les interfaces et les classes pour la collection garbage distribuée RMI.
java.rmi.registry
fournit une classe et deux interfaces pour le registre RMI.
java.rmi.server
fournit les interfaces et les classes pour supporter le serveur côté du RMI.
java.security
fournit les interfaces et les classes pour la structure (framework) de sécurité.
java.security.acl
fournit les interfaces et les classes qui ont été remplacées par les classes dans le package java.security.
java.security.cert
fournit les interfaces et les classes pour l'analyse et la gestion des certificats.
java.security.interfaces
fournit les interfaces pour la production de clés RSA (Rivest, Shamir and Adleman AsymmetricCipher algorithm).
java.security.spec
fournit les interfaces et les classes pour les spécifications de clés et des paramètres d'algorithme.
java.sql
fournit l'API pour l'accès et le traîtement de données stockées dans une source de données.
java.text
fournit les interfaces et les classes pour la manipulation de textes, de dates, de nombres et de messages dans une manière indépendante des langages naturels.
java.util
contient des collections de structures (framework), l'héritage de collection de classes, de modèle d'événement, de facilités de date et d'heure, d'internationalisation, de classes utilitaires diverses.
java.util.jar
fournit les classes pour la lecture et l'écriture de format de fichier JAR (Java ARchive), lequel est basé sur le standard ZIP.
java.util.logging
fournit les interfaces et les classes de la plateforme principale Java de facilités d'ouverture de session.
java.util.prefs
permet de stocker et récupérer les utilisateurs et le système de préférences et les données de configuration.
java.util.regex
fournit les classes pour faire correspondre des séquences de caractères par rapport à des modèles spécifiés par des expressions régulières.
java.util.zip
fournit les classes pour la lecture et l'écriture les formats de fichier au standard ZIP et GZIP.
javax.accessibility
définit un contrat entre les composants d'interface utilisateur et une technologie d'aide qui fournit l'accès à ces composants.
javax.crypto
fournit les interfaces et les classes pour des opération de cryptographie.
javax.crypto.interfaces
fournit des interfaces pour les clés Diffie-Hellman comme définis dans les laboratoires RSA.
javax.crypto.spec
fournit les interfaces et les classes pour les spécifications de clé et de paramètres d'algorithme.
javax.imageio
constitue le package principal de l'API d'entrée/sortie d'images Java.
javax.imageio.event
est un package de l'API d'entrée/sortie des images Java gérant les notifications synchrones d'événements durant la lecture et l'écriture d'images.
javax.imageio.metadata
est un package de l'API d'entrée/sortie des images Java gérant la lecture et l'écriture de métadonnées.
javax.imageio.plugins.jpeg
fournit les classes supportant le module de construction JPEG.
javax.imageio.spi
est un package de l'API d'entrée/sortie des images Java contenant les interfaces de modules pour la lecture, l'écriture, le transcodage, les flux et un registre d'exécution.
javax.imageio.stream
est un package de l'API d'entrée/sortie des images Java gérant les niveaux bas d'entrée/sortie des fichiers et des flux.
javax.naming
fournit les classes et les interfaces pour l'accèder aux services nommés.
javax.naming.directory
permet d'étendre le package javax.naming fournissant les fonctionnalités pour l'accès aux services de répertoires.
javax.naming.event
fournit le support pour les notifications d'événement lors de l'accès aux services nommés et de répertoires.
javax.naming.ldap
fournit le support pour les opérations et les contrôles étendues LDAPv3.
javax.naming.spi
fournit les significations pour les modules d'extensions dynamiques dans le support pour l'accès aux services nommés et de répertoires aux travers de javax.naming et les packages liés.
javax.net
fournit les classes pour les applications réseaux.
javax.net.ssl
fournit les classes pour le package de socket sécurisé.
javax.print
fournit les classes et interfaces principales pour l'API du service d'affichage Java.
javax.print.attribute
fournit les classes et interfaces décrivant les types d'attributs de service d'affichage Java et comment ils peuvent être collectés à l'intérieur de jeux d'attributs.
javax.print.attribute.standard
est un package javax.print.attribute.standard contenant les classes pour les attributs d'affichage spécifiques.
javax.print.event
est un package javax.print.event contenant les classes d'événement et les interfaces auditrices.
javax.rmi
contient les API utilisateurs pour RMI-IIOP.
javax.rmi.CORBA
contient les API de portabilité pour RMI-IIOP.
javax.security.auth
fournit une structure (framework) pour l'authentification et l'autorisation.
javax.security.auth.callback
fournit les classes nécessaires pour les services d'interaction avec les applications de récupération d'informations d'authentification ou pour l'affichage d'informations.
javax.security.auth.kerberos
contient les classes utilitaires liées au protocole d'authentification de réseau Kerberos.
javax.security.auth.login
fournit une structure d'authentification modulable.
javax.security.auth.spi
fournit les interfaces utilisées pour l'implémentation de modules d'authentifications modulables.
javax.security.auth.x500
contient les classes devant être utilisées pour stocker les références principales et privées X500 dans un sujet.
javax.security.cert
fournit les classes pour les certificats de clé public.
javax.sound.midi
fournit les classes et interfaces pour les entrées/sorties, le séquençage et les synthèses de données MIDI (Musical Instrument Digital Interface).
javax.sound.midi.spi
fournit les interfaces pour les services de fournisseurs pour l'implémentation lors des propositions de nouveaux dispositifs MIDI, de lecture et d'écriture de fichier MIDI, ou pour la lecture de banque de son.
javax.sound.sampled
fournit les classes et interfaces pour la capture, le traîtement et pour l'interprétation de données audio échantillonnées.
javax.sound.sampled.spi
fournit les classes abstraites pour les fournisseurs de services pour sous-classer lors d'une proposition de nouveaux dispositifs audio, de lecture et d'écriture de fichier sonore ou pour la conversion de format audio.
javax.sql
fournit l'API pour l'accès aux sources de données côté serveur et le traîtement à partir de Java.
javax.swing
fournit un jeu de composants travaillant de la même façon avec toutes les plateformes.
javax.swing.border
fournit les classes et interfaces pour dessiner des bordures spécialisée autour d'un composant Swing.
javax.swing.colorchooser
contient les classes et les interfaces utilisées par le composant JColorChooser.
javax.swing.event
fournit les les événements lancés par les composants Swing.
javax.swing.filechooser
contient les classes et les interfaces utilisées par le composant JFileChooser.
javax.swing.plaf
fournit les interfaces et plusieurs classes abstraites qu'utilise Swing pour fournir ses capacités look-and-feel modulables.
javax.swing.plaf.basic
fournit les objets d'interface construit en accord avec les sensations et les visions basiques.
javax.swing.plaf.metal
fournit les objets d'interface utilisateur construit en accord aux sensations et visions par défaut.
javax.swing.plaf.multi
fournit les objets d'interface utilisateur qui combinent de deux à plusieurs visions et sensations.
javax.swing.table
fournit les classes et les interfaces afin de gérer le package javax.swing.JTable.
javax.swing.text
fournit les classes et les interfaces gérant les composants de texte éditable et non-éditable.
javax.swing.text.html
fournit les classes HTMLEditorKit et supporte les classes pour la création des éditeurs de texte HTML.
javax.swing.text.html.parser
fournit l'analyseur HTML par défaut, ainsi que les classes de support.
javax.swing.text.rtf
fournit la classe RTFEditorKit pour la création d'éditeurs de texte RTF (Rich Text Format).
javax.swing.tree
fournit les classes et les interfaces gérant le package javax.swing.JTree.
javax.swing.undo
fournit le support pour annuler/refaire (undo/redo) dans les applications comme des éditeurs de texte.
javax.transaction
contient les trois exceptions lancées par le mécanisme ORB durant un rassemblement.
javax.transaction.xa
fournit les API qui définissent les contrats entre les gestionnaires de transaction et de ressource.
javax.xml.parsers
fournit les classes permettant le traitement des documents XML.
javax.xml.transform
définit les API génériques pour l'exécution de transformations, d'instructions, et le fonctionnement d'une transformation à partir d'une source vers un résultat.
javax.xml.transform.dom
implémente les API de transformation du DOM spécifique.
javax.xml.transform.sax
implémente les API de transformation SAX2 spécifique.
javax.xml.transform.stream
implémente les API de transformation spécifique de flusx et d'adresse URI.
org.ietf.jgss
présente une structure permettant aux développeurs d'application de faire utiliser des services de sécurité comme l'authentification, l'intégrité et la confidentialité des données à partir d'une variété de mécanisme de sécurité sous-jacent comme Kerberos utilisant un API unifié.
org.omg.CORBA
fournit la carte de l'API CORBA OMG.
org.omg.CORBA_2_3
définit des extensions aux interfaces CORBA existantes.
org.omg.CORBA_2_3.portable
fournit les méthodes pour les entrées et sorties de types de valeur et contient d'autres mise à jour vers le package org/omg/CORBA/portable.
org.omg.CORBA.DynAnyPackage
fournit les exceptions utilisées avec l'interface DynAny.
org.omg.CORBA.ORBPackage
fournit les exceptions InvalidName lancées par la méthode ORB.resolve_initial_references et InconsistentTypeCodelancées par les méthodes de création Dynamic Any dans la classe ORB.
org.omg.CORBA.portable
Provides a portability layer, that is, a set of ORB APIs that makes it possible for code generated by one vendor to run on another vendor's ORB.
org.omg.CORBA.TypeCodePackage
fournit les exceptions définies par l'utilisateur BadKind et Bounds lancées par les méthodes dans la classe TypeCode.
org.omg.CosNaming
fournit un service de nommage pour Java IDL.
org.omg.CosNaming.NamingContextExtPackage
contient les classes suivantes utilisées dans le package org.omg.CosNaming.NamingContextExt:
org.omg.CosNaming.NamingContextPackage
contient les classes Exception pour le package org.omg.CosNaming.
org.omg.Dynamic
contient le module Dynamic spécifié dans les spécifications Portable Interceptor.
org.omg.DynamicAny
fournit les classes et les interfaces activant la traversée de valeur de données associée à un any à une exécution et extraction de composants primitifs de valeur de données.
org.omg.DynamicAny.DynAnyFactoryPackage
contient les classes et les exceptions des interfaces DynAnyFactory du module DynamicAny spécifié dans l'OMG.
org.omg.DynamicAny.DynAnyPackage
contient les classes et les interfaces à partir des interfaces DynAny du module DynamicAny spécifié dans l'OMG.
org.omg.IOP
contient le module IOP spécifié dans l'OMG.
org.omg.IOP.CodecFactoryPackage
contient les exceptions spécifiées dans les interfaces IOP::CodeFactory.
org.omg.IOP.CodecPackage
est généré à partir de la définition d'interface IDL IOP::Codec.
org.omg.Messaging
contient le module Messaging spécifié dans les spécifications OMG CORBA Messaging.
org.omg.PortableInterceptor
fournit un mécanisme au registre ORB pris à travers duquel les services ORB peuvent intercepter le flux norma d'exécution de l'ORB.
org.omg.PortableInterceptor.ORBInitInfoPackage
contient les exceptions et les définitions de type à partir de l'interface locale ORBInitInfo du module PortableInterceptor spécifié dans l'OMG .
org.omg.PortableServer
fournit les classes et les interfaces pour la fabrication côté serveur d'applications portables à travers des ORB multivendeurs.
org.omg.PortableServer.CurrentPackage
fournit les implémentations de méthode avec l'accès àl'identité de l'objet sur lequel la méthode était invoquée.
org.omg.PortableServer.POAManagerPackage
encapsule l'état de traitement des POA.
org.omg.PortableServer.POAPackage
permet aux programmeurs de contruire les implémentations d'objet qui sont portables entre les produits ORB différents.
org.omg.PortableServer.portable
fournit les classes et les interfaces pour la fabrication côté serveur d'aaplications portables à travers les ORB multivendeurs.
org.omg.PortableServer.ServantLocatorPackage
fournit les classes et les interfaces pour trouver le service (servant).
org.omg.SendingContext
fournit le support pour le rassemblement de types de valeur.
org.omg.stub.java.rmi
contient les morceaux RMI-IIOP pour les types distants se produisant dans le paquetage java.rmi.
org.w3c.dom
fournit les interfaces pour le modèkle d'objet de document qui est un composant de l'API pour le traitement XML.
org.xml.sax
fournit les classes et les interfaces pour SAX (Simple API for XML) qui est un composant de l'API pour le traitement XML.
org.xml.sax.ext
fournit les classes et les interfaces pour SAX (Simple API for XML) qui est un composant de l'API pour le traitement XML.
org.xml.sax.helpers
fournit les classes d'aide pour SAX (Simple API for XML) qui est un composant de l'API du traitement XML.

21 / Les erreurs

Il existe trois types de problèmes générateur d'erreurs dans le langage Java.

Les problèmes de compilation se produisent lorsque le code source d'un programme Java est compilé.

Sous Unix, la première erreur javac: Command not found peut intervenir si la variable d'environnement PATH ne spécifie pas le chemin correct vers le compilateur Java. Dans ce cas, il suffit de modifier ce chemin par la commande setenv.

Les erreurs de syntaxe sont souvent dues à des fautes d'inattention ou de vocabulaire comme l'oubli d'un point-virgule à la fin d'une instruction ou la mauvaise orthographe d'une commande.

Les erreurs de sémantique sont provoquées par des irrégularités dans l'utilisation d'éléments d'un programme Java, tel qu'une variable non-initialisée.

Les problèmes d'interprétation se produisent lorsqu'un programme est soumis à l'interpréteur java.

Si une tentative d'interprétation d'un fichier .class est effectuée, l'interpréteur renverra une erreur indiquant qu'il ne peut trouver la classe appropriée.

Si la méthode main n'est pas présente dans une classe et que cette dernière est exécutée, une erreur sera lancée spécifiant que la méthode main n'est pas définie.

D'autres problèmes peuvent survenir lors de l'utilisation des appliquettes Java dans des pages HTML.

Plusieurs erreurs peuvent intervenir à cause d'une écriture incorrecte du balisage applet dans une page HTML, de difficultés à recharger une appliquette par l'afficheur Java du navigateur, de dysfonctionnement de l'applet sur le serveur HTTP, etc..

22 / Les exceptions

Les exceptions se produisent lorsque des situations anormales surviennent durant l'exécution d'un programme Java.

Les exceptions représentent un moyen efficace de détecter des problèmes éventuels dans une application Java.

Plus un compilateur Java sera sévère dans l'analyse d'un programme, c'est-à-dire dans sa capacité à générer des avertissements et des alertes, plus la fiabilité de l'application sera meilleure.

En Java, il existe deux classes intéressantes dérivées de la classe Throwable :

Les exceptions sont donc de véritables objets créés suite à la détection d'une anomalie dans le déroulement du programme.

Contrairement à celles de la classe Error, les exceptions de la classe Exception peuvent et dans la plupart des cas, doivent être interceptées.

Il n'est pas nécessaire de gérer les exceptions de la classe RuntimeException. Ces dernières avec celles de la classe Error et de leurs sous-classes sont d'ailleurs communément appelées les exceptions non-contrôlées (unchecked).

En ce qui concerne toutes les autres, c'est-à-dire les exceptions contrôlées, il est impératif d'inclure un dispositif d'interception et de gestion, sans lequel Java ne pourra mener à son terme la compilation d'un programme.

Toutes les méthodes susceptibles de générer une exception doivent soit être comprises dans un bloc try, soit signaler au moyen de la commande throws cette particularité.

Si les exceptions contrôlées ne seraient pas interceptées, leur thread d'exécution s'interrromprait et la console Java afficherait un message d'erreur.

22.1 / Les exceptions de la classe Exception

Classe
Description (sous-classes)
AclNotFoundException
Exception d'ACL (Access Control List) inexistant.
ActivationException
Exceptions d'activation (UnknownGroupException, UnknownObjectException).
Already Bound Exception
Exception de nom déjà utilisé.
ApplicationException
Exception dans une application.
AWTException
Exception dans le système de gestion de l'interface utilisateur AWT.
BadLocationException
Exception de mauvaise localisations d'une ressource.
ClassNotFoundException
Exception de classe chargée avec un nom erroné.
CloneNotSupportedException
Exception de création de clone non supporté (ServerCloneException).
DataFormatException
Exception de mauvais format de données.
ExpandVetoException
Exception d'interdiction d'extension d'une classe.
FontFormatException
Exception de format de police invalide.
GeneralSecurityException
Exceptions de sécurité générale (CertificateException, CRLException, DigestException, InvalidAlgorithmParameterException, InvalidKeySpecException, InvalidParameterSpecException, KeyException, KeyStoreException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException, UnrecoverableKeyException).
IllegalAccessException
Exception d'accès illégal à une classe.
InstantiationException
Exception d'instanciationpar newInstance().
InterruptedException
Exception d'interruption de thread.
IntrospectionException
Exception d'introspection.
InvalidMidiDataException
Exception de données Midi invalide.
InvocationTargetException
Exception de cible d'invocation.
IOException
Exceptions d'entrée/sortie (ChangedCharSetException, CharConversionException, EOFException, FileNotFoundException, InterruptedIOException, MalformedURLException, ObjectStreamException, ProtocolException, RemoteException, SocketException, SyncFailedException, UnknownHostException, UnknownServiceException, UnsupportedEncodingException, UTFDataFormatException, ZipException).
LastOwnerException
Exception de tentative de suppression du dernier propriétaire ACL.
LineUnavailableException
Exception de ligne indisponible ou déjà ouverte.
MidiUnavailableException
Exception de composant Midi indisponible.
MimeTypeParseException
Exception d'analyse de type Mime
NamingException
Exceptions de nommage (AttributeInUseException, AttributeModificationException, CannotProceedException, CommunicationException, ConfigurationException, ContextNotEmptyException, InsufficientResourcesException, InterruptedNamingException, InvalidAttributeIdentifierException, InvalidAttributesException, InvalidAttributeValueException, InvalidNameException, InvalidSearchControlsException, InvalidSearchFilterException, LimitExceededException, LinkException, NameAlreadyBoundException, NameNotFoundException, NamingSecurityException, NoInitialContextException, NoSuchAttributeException, NotContextException, OperationNotSupportedException, PartialResultException, ReferralException, SchemaViolationException, ServiceUnavailableException).
NoninvertibleTransformException
Exception de transformation non inversible.
NoSuchFieldException
Exception de champs introuvables.
NoSuchMethodException
Exception de méthodes introuvables.
NotBoundException
Exception de tentative de défaire ou voir une liaison inexistante.
NotOwnerException
Exception de proprétaire non reconnu pour une modification.
ParseException
Exception d'analyse.
PrinterException
Exceptions d'impression (PrinterAbortException, PrinterIOException).
PrivilegedActionException
Exception d'action soumise à des priviléges.
PropertyVetoException
Exception de propriété interdite.
RemarshalException
Exception de réorganisation de requête.
RuntimeException
Exception d'exécution (ArithmeticException, ArrayStoreException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnsupportedOperationException).
ServerNotActiveException
Exception de serveur non actif pour une opération à distance.
SQLException
Exception SQL : Structured Query Language (BatchUpdateException, SQLWarning).
TooManyListenersException
Exception d'auditeurs trop nombreux pour une uni-distribution.
UnsupportedAudioFileException
Exception de fichier audio non supporté.
UnsupportedFlavorException
Exception de données demandées non supportées.
UnsupportedLookAndFeelException
Exception sur des opérations d'interfaces utlisateurs non supportées.
UserException
Exceptions utilisateur CORBA IDL (AlreadyBound, BadKind, Bounds, Bounds, CannotProceed, InconsistentTypeCode, Invalid, InvalidName, InvalidName, InvalidSeq, InvalidValue, NotEmpty, NotFound, PolicyError, TypeMismatch, UnknownUserException, WrongTransaction).

22.2 / La gestion des exceptions

Le langage de programmation Java fournit un mécanisme permettant de gérer les exceptions lancées par le programme.

Lorsqu'une exception se produit, le traitement normal du programme s'interrompt et l'environnement d'exécution tente de trouver le gestionnaire d'exception chargé de gérer le type d'erreur en cours.

Le gestionnaire d'exception peut tenter de récupérer l'erreur si cela est possible, sinon il essayera de provoquer une sortie correcte du programme.

try{
  // Instructions...
}
catch (type_exception1 nom){
  // Instructions de traitement d'exception
}
...
catch (type_exceptionN nom){
  // Instructions de traitement d'exception
}
finally{
  // Instructions de fin...
}

L'instruction try contient un bloc d'instructions à l'intérieur duquel une exception pourrait se produire.

L'instruction catch doit être associée à try et contient un bloc d'instructions susceptible de gérer un type d'exception particulier.

L'instruction finally facultative, doit être associée à try et placée après catch. Elle contient un bloc d'instructions qui est exécuté dans tous les cas de figure.

Il est possible d'utiliser plusieurs instructions catch afin de capturer des exceptions de types différents.

Cette succession de blocs catch doit correspondre à un ordre précis afin de correspondre à la hiérarchie inverse des classes d'exception.

Ainsi, les types d'exception risquant de se produire dans les sous-classes inférieures d'une hiérarchie devront être traités en premier, suivi de ceux des classes supérieures.

Si une exception se produit dans le bloc try, alors la machine virtuelle Java recherchera le bloc catch le plus approprié à l'exception en cours.

try {
  // Bloc d'instructions...
}
catch (FileNotFoundException e) {
  // Gestion des exceptions de fichier non trouvé
}
catch (IOException e) {
  // Gestion des exceptions d'entrée/sortie
}
catch (Exception e) {
  // Gestion des exceptions
}

Par exemple, si une exception du type FileNotFoundException se produit dans le bloc try, le bloc catch (FileNotFoundException e) intercepterait et gérerait l'exception en cours.
Si une exception du type EOFException se produit, alors ce serait au tour du bloc catch (IOException e) de traiter cette exception puisqu'elle est provient d'une sous-classe de IOException.
Enfin, si une exception du type BadLocationException se produit, alors le dernier bloc catch prendrait en compte cette exception car celle-ci descend de la classe Exception.

Les instructions try... catch peuvent être imbriquées les unes dans les autres.

try {
  // Bloc try 1
  ...
  try {
  // Bloc try 2
  ...
  }
  catch (TypeException e) {
  ...
  }
  ...
}
catch (TypeException e) {
  ...
}

Dans ce cas, si une exception est lancée dans le second bloc try terminant de fait son exécution, son bloc catch est vérifié pour une éventuelle interception. S'il n'est pas en mesure de gérer l'exception, alors cette dernière est propagée dans le premier bloc try qui ensuite transmet l'exception à son bloc catch.

22.3 / La gestion des exceptions

Le langage de programmation Java fournit un mécanisme permettant de gérer les exceptions lancées par le programme.

Lorsqu'une exception se produit, le traitement normal du programme s'interrompt et l'environnement d'exécution tente de trouver le gestionnaire d'exception chargé de gérer le type d'erreur en cours.

Le gestionnaire d'exception peut tenter de récupérer l'erreur si cela est possible, sinon il essayera de provoquer une sortie correcte du programme.

try{
  // Instructions...
}
catch (type_exception1 nom){
  // Instructions de traitement d'exception
}
...
catch (type_exceptionN nom){
  // Instructions de traitement d'exception
}
finally{
  // Instructions de fin...
}

public class RacineCarre {
  static public void main(String[] args) {
    int dividende = 9;
    int diviseur = 0;

    try {
      System.out.println("La division de " + dividende "/" + diviseur 
                          + " est égale à " + dividende/diviseur);
    }
    catch(ArithmeticException e) {
      System.out.println("Une exception s'est produite !rn" 
                                     + e.getMessage());
      System.out.println("rnAffichage de la pile :rn");
      e.printStackTrace();
    }
    finally {
      System.out.println("Je vous remercie d'avoir essayé !")); 
    }
  }
}

L'instruction try contient un bloc d'instructions à l'intérieur duquel une exception pourrait se produire.

L'instruction catch doit être associée à try et contient un bloc d'instructions susceptible de gérer un type d'exception particulier.

L'instruction finally facultative, doit être associée à try et placée après catch. Elle contient un bloc d'instructions qui est exécuté dans tous les cas de figure.

Il est possible d'utiliser plusieurs instructions catch afin de capturer des exceptions de types différents.

Cette succession de blocs catch doit correspondre à un ordre précis afin de correspondre à la hiérarchie inverse des classes d'exception.

Ainsi, les types d'exception risquant de se produire dans les sous-classes inférieures d'une hiérarchie devront être traités en premier, suivi de ceux des classes supérieures.

Si une exception se produit dans le bloc try, alors la machine virtuelle Java recherchera le bloc catch le plus approprié à l'exception en cours.

try {
  // Bloc d'instructions...
}
catch (FileNotFoundException e) {
  // Gestion des exceptions de fichier non trouvé
}
catch (IOException e) {
  // Gestion des exceptions d'entrée/sortie
}
catch (Exception e) {
  // Gestion des exceptions
}

Par exemple, si une exception du type FileNotFoundException se produit dans le bloc try, le bloc catch (FileNotFoundException e) intercepterait et gérerait l'exception en cours.
Si une exception du type EOFException se produit, alors ce serait au tour du bloc catch (IOException e) de traiter cette exception puisqu'elle est provient d'une sous-classe de IOException.
Enfin, si une exception du type BadLocationException se produit, alors le dernier bloc catch prendrait en compte cette exception car celle-ci descend de la classe Exception.

Les instructions try... catch peuvent être imbriquées les unes dans les autres.

try {
  // Bloc try 1
  ...
  try {
    // Bloc try 2
    ...
  }
  catch (TypeException e) {
    ...
  }
  ...
}
catch (TypeException e) {
  ...
}

Dans ce cas, si une exception est lancée dans le second bloc try terminant de fait son exécution, son bloc catch est vérifié pour une éventuelle interception. S'il n'est pas en mesure de gérer l'exception, alors cette dernière est propagée dans le premier bloc try qui ensuite transmet l'exception à son bloc catch.

L'omission du bloc catch est permise dans la mesure où le bloc try est suivi d'un bloc finally, mais les exceptions doivent être déclarées à partir de la méthode en cours.

Plusieurs méthodes des classes d'exceptions permettent de retourner des informations relatives à l'erreur en cours. Il s'agît de :

import java.io.*;

public class Ecrire {
  public static void main(String[] args) {
    try {
      FileWriter sortie = new FileWriter("titre");
      sortie.write("Un texte...");
      sortie.flush();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
}

22.4 / Génération d'une exception

La génération d'une exception s'effectue par l'instanciation de la classe Exception ou de l'une de ses nombreuses dérivées et par l'utilisation du mot clé throw.

throw new ConstructeurClasseException();

// déclenchement d'une exception
throw new Exception();

// déclenchement d'une exception DataFormatException
// descendant de la classe Exception;
throw new DataFormatException("Mauvais format de données !"); // propagation d'une exception en cours throw e;

L'expression new ConstructeurClasseException() permet d'allouer et d'initialiser un objet de la classe d'exception appropriée qui est ensuite lancé par throw.

Toutes les classes d'exception descendant de la classe Throwable, n'importe quel type d'exception (sous-classe Exception) et d'erreur (sous-classe Error) peut être lancé par la commande throw.
Néanmoins, il est préférable de se contenter des seules exceptions contrôlées.

En outre, une exception peut être déclenchée n'importe où dans une méthode.

Cependant, le déclenchement d'une exception dans une méthode nécessite de le signaler par l'intermédiaire du mot clé throws dans la déclaration de méthode, ou d'englober la méthode dans un bloc try.

22.5 / Signalisation d'une exception

Dans la déclaration d'une méthode methode, le mot clé throws permet de signaler le ou les exceptions qu'elle sera susceptible de lancer.

public int uneMethode() throws ClasseException {
  ...
}

La signalisation des exceptions est une obligation si :

Dans le cas des exceptions de types RuntimeException, Error et toutes leurs descendances, il n'est pas nécessaire de signaler le risque de génération d'exception.

La déclaration de signalisation d'une exception permet de construire des applications sûres où toutes les exceptions nécessitant un traitement particulier, seront soit gérées, soit intentionnellement ignorées lors du développement d'un programme java.

Les exceptions susceptibles de se produire par des méthodes appelées à partir d'une autre méthode doivent être impérativement signalées dans cette dernière, si aucune signalisation (throws) ou aucun mécanisme d'interception (try...catch) n'a été conçu dans les méthodes appelées.

22.6 / La création d'exception personnalisée

Si l'on désire créer une nouvelle sorte d'exception, il suffit de faire hériter une nouvelle classe de la classe Exception, puis de définir cette exception personnalisée.

class MonException extends Exception {
  // Définition de mon exception...
  public MonException(String message) {
    super(message);
    ...
  }
  public String toString() {
    return "Un message";
    ...
  }
}

class EgalZeroException extends Exception {
  public String toString() {
    return "Le côté d'un triangle rectangle "
             + "ne peut être égal à zéro !";
  }
}

public class Hypothenuse {
  double BC;
  static void calculHypothenuse(double AB, double AC)
             throws EgalZeroException {
    if ((AB == 0) && (AC == 0))
      throw new EgalZeroException();
    else {
      BC = sqrt(power(AB, 2) + power(AC, 2));
      System.out.println("AB = " + AB + "rnAC = " 
                         + AC + "rn BC" + " BC");
  }

  public static void main(String[] args) {
    try {
      System.out.println(calculHypothenuse(15, 20.9));
    }
    catch (EgalZeroException e) {
      System.out.println ("Erreur " + e);
    }
  }
}

23 / Le système de Garbage Collector

Le système de Garbage Collector (GC, littéralement ramasseur de déchets) permet de gérer automatiquement les ressources utilisées par les objets d'une application Java.

Le processus de GC détermine les objets inutilisés par un programme, pour ensuite les traiter de sorte à récupérer leur espace mémoire pour une éventuelle réutilisation.

Toutefois, il n'existe aucun moyen de contraindre le GC à accomplir un nettoyage de la mémoire à la demande.
Le processus de Garbage Collector n'est absolument pas déterminable.

En outre, le système GC n'assure en aucune façon que le programme ne devra pas à un moment donné faire face à une carence de ressources mémoires (out of memory).

23.1 / La gestion de la mémoire

Java s'occupe de la gestion automatique de l'allocation dynamique de la mémoire. Une zone mémoire est dynamiquement allouée à un objet lors de sa création.

Classe Variable_objet = new Classe();
//Variable_objet représente une référence 
//de l'instance de classe new Classe()

Lorsque cette zone mémoire n'est plus référencée par un objet du programme, elle est automatiquement libérée par le GC.

Variable_objet = null;
//Variable_objet ne référence 
//plus d'instance de classe

Plusieurs objets distincts d'un programme occupent un espace mémoire plus ou moins important sur un système informatique, en sachant que les ressources mémoires sont certainement limitées.
Un usage incontrôlé de la mémoire risque à terme de provoquer des conflits de ressources tels que :

Le système GC interdit l'utilisation d'une ressource déjà utilisée et évite dans la mesure du possible, les pertes de mémoires.

En outre, il existe deux types de perte de mémoire :

En ce qui concerne les fuites de mémoires légères (soft leaks), il suffit d'affecter la valeur null aux objets qui ne seront plus utilisés par le programme. Ensuite, le système GC détruira les références et libérera les ressources pour une utilisation ultérieure.

import java.io.*;
public class Execution {
  public static void main(String argv[]) {
    new Execution("fichier.bat");
  }

  public Execution(String commande) {
    try {
      String ligne;
      Process processus = Runtime.getRuntime().exec(commande);
      InputStreamReader flux_entree = 
                    new InputStreamReader(processus.getInputStream())
      BufferedReader entree = new BufferedReader();
      while ((ligne = entree.readLine()) != null) {
        System.out.println(ligne);
      }
      ligne = null;
      processus = null;
      flux_entree = null;
      entree = null;
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

fichier.bat
echo "Bonjour à tous et à toutes !"

Le système de Garbage Collector agît essentiellement sur les fuites mémoires graves (hard leaks) en s'occupant de :

  1. la surveillance de l'utilisation des objets,
  2. la détermination des objets devenus inutiles,
  3. l'information des objets sur leur inutilisation,
  4. la destruction des objets inutiles,
  5. la récupération des ressources libérées.

23.2 / Le fonctionnement du Garbage Collector

La Machine Virtuelle Java (JVM) comptabilise en permanence le nombre de références désignant chaque objet d'un programme. Ainsi, lorsque le nombre de références est égal à zéro, cela signifie que l'objet n'est plus utilisé et par conséquent, que sa zone mémoire doit être libérée.

Le système de Garbage Collector accomplit ses opérations en tâche de fond à partir d'un thread indépendant de faible priorité et en exécution asynchrone.

Le GC conserve la trace de chacun des objets créés et utilisés dans un programme. Que les objets soient accessibles ou inaccessibles, le GC les prend tous en compte.

Lorsqu'une instance de classe en mémoire ne possède plus de lien avec le programme, c'est-à-dire, que plus aucune variable ne référence cet objet, alors ce dernier est jugé inutile. Devenu inaccessible, l'objet peut alors être soumis au traitement du GC, en l'occurrence,il appele, si elle existe, la méthode finalize() de l'objet en question pour accomplir un traitement de finalisation, puis s'il y a lieu opére sa destruction et récupère sa zone mémoire.

Cependant, le processus de Garbage Collector est indéterminable.
Il n'est absolument pas garanti sur tous les objets déréférencés, car le programme peut se terminer avant que le traitement n'ait même commencé.
En effet, étant donné la nature du mode d'exécution du système GC (thread indépendant et exécution asynchrone), il est impossible de prévoir quand le GC s'exécutera, et encore moins, quels objets inaccessibles il traitera.

public class GarbageCollector {
  ProcessusGarbage pG;
  int max;

  public static void main(String[] args) {
    int nb = 275;
    if(args.length > 0)
      nb = (new Integer(args[0])).intValue();
    GarbageCollector oGC = new GarbageCollector(n);
    oGC.executer();
  }

  public GarbageCollector(int nb) {
    max = nb;
  }

  void executer() {
    for(int i = 1; i < max; i++)
      pG = new ProcessusGarbage(i);
  }
}

class ProcessusGarbage {
  double[] tableau;
  int num_objet;

  public ProcessusGarbage(int nb) {
    num_objet = nb;
    tableau = new double[n];
    tableau[0] = 0;
    for(int i = 1; i < n; i++)
      tableau[i] = Math.pow(tableau[i - 1], 1.7E+308);
  }

  protected void finalize() {
    System.out.println("L'objet num" + num_objet 
                      + " a ete traite par le Garbage Collector.");
  }
}

Dans cet exemple, on pourra remarquer que tous les objets créés devenus inaccessibles ne sont pas traités par le GC.

La méthode finalize() est automatiquement appelée lorsque le système GC a déterminé qu'un objet est devenu inaccessible. C'est pourquoi, dans l'exemple précédent, une information à propos du traitement de l'objet a pu être affichée.

23.3 / La méthode finalize()

La méthode finalize() définie dans la classe Java.lang.Object, permet d'effectuer des opérations de finalisation en général une opération de nettoyage d'un objet avant que le système de Garbage Collector ne s'en charge ou que ce dernier ne peut accomplir, comme dans le cas d'un objet de système de fichier, ou encore de connexion réseau.

protected void finalize() throws Throwable

La méthode finalize() est automatiquement appelée par un thread spécialisé (Finalizer), si elle existe dans la classe de l'objet, avant que le collecteur de déchets n'entreprenne le recyclage de ce dernier.

Un objet déréférencé peut par l'intermédiaire de la méthode de finalisation redevenir atteignable, c'est-à-dire retrouver une référence dans le programme.

Subséquemment, le GC vérifie à nouveau l'accessibilité de l'objet par le programme et si celui-ci possède effectivement, une nouvelle référence, alors il abandonne le processus de récupération des ressources pour l'objet en cours.

La méthode finalize() n'est jamais appelée plus d'une fois pour un objet donné.

La méthode System.runFinalization() lance la méthode finalize() de n'importe quel objet inatteignable avant que le processus de Garbage Collector ne commence.

public static void runFinalization()

System.runFinalization();

Runtime.getRuntime().runFinalization();
//Equivalent à System.runFinalization();

L'appel de cette méthode incite la Machine Virtuelle Java (JVM) à effectuer des tentatives d'exécution des méthodes finalize() des objets qui ont été trouvés pour leur inaccessibilité, mais dont les méthodes de finalisation n'ont pas encore été lancées.

public class CollecteurDechets extends Thread {
  public CollecteurDechets() {
    super();
  }
  public void run() {
    long i = 0;
    while (true) {
      if (verifierPremier(i)) {
        NombrePremier objet = new NombrePremier(
                                       String.valueOf(i));
        if(i > Short.MAX_VALUE)
          break;
      }
      i++;
    }
  }
  public boolean verifierPremier(long nombre) {
    if (nombre < 0) {
      return false;
    }
    else if (nombre < 4) {
      return true;
    }
    else {
      for (int i = 4; i <= nombre / 2; i++) {
        if (nombre != i && nombre % i == 0) {
          return false;
        }
      }
    }
    return true;
  }

  public static void main(String[] args) {
    CollecteurDechets thread = new CollecteurDechets();
    thread.start();
    while (thread.isAlive()) {
      try {
        Thread.sleep(500);
      }
      catch (InterruptedException e) {
      }
    }
  }
}

public class NombrePremier {
  private String valeur;
  public NombrePremier(String valeur) {
    this.valeur = valeur;
  }
  public String getValeur() {
    return this.valeur;
  }
  public void setValeur(String valeur) {
    this.valeur = valeur;
  }
  protected void finalize() throws Throwable {
    System.out.println("Invocation de la méthode finalize()");
    System.out.println("Contenu de l'objet : " + valeur);
    System.out.println("Nom du thread courant : "
                       + Thread.currentThread().getName());
    this.valeur = null;
  }
}
/* Affiche
...
Invocation de la méthode finalize()
Contenu de l'objet : 34807
Finalizer
Invocation de la méthode finalize()
Contenu de l'objet : 34781
Finalizer
Invocation de la méthode finalize()
Contenu de l'objet : 34763
Finalizer
...
*/

23.4 / Les méthodes gc()

Les méthodes Runtime.gc() et System.gc() définies dans la classe java.lang, permettent de suggérer l'exécution du nettoyage de la mémoire par le système de Garbage Collector.

public static void gc()
Runtime.gc();
System.gc();
Runtime.getRuntime().gc();
// Equivalent à System.gc();

L'appel de l'une de ces méthodes incite la Machine Virtuelle Java (JVM) à effectuer des tentatives de recyclage d'objets inutilisés afin de récupérer leurs zones mémoires de sorte à les rendre disponible pour une réutilisation ultérieure et rapide.

La JVM exécute le processus de recyclage automatiquement si nécessaire, dans un thread séparé, même si la méthode gc() n'a pas été invoquée explicitement.

Les méthodes Runtime.gc() et System.gc() ne garantissent pas l'exécution du recyclage de la mémoire, mais seulement qu'il sera probable.

23.5 / Les méthodes totalMemory et freeMemory

Deux méthodes totalMemory et freeMemory permettent de connaître la quantité de mémoire disponible sur le système informatique, où est installé la Machine Virtuelle Java (JVM).

La méthode Runtime.totalMemory() retourne la taille totale de la mémoire dont dispose la Machine Virtuelle Java.

public long totalMemory()

long taille = Runtime.getRuntime().totalMemory();

La valeur de cette méthode peut varier en fonction de l'environnement hôte.

La méthode Runtime.freeMemory() retourne la quantité de mémoire libre du système.

public long freeMemory()

long taille = Runtime.getRuntime().freeMemory();

L'appel de la méthode gc() pour le nettoyage de la mémoire, peut entrainer une augmentation de la valeur retournée par freeMemory().

Le nombre retourné par totalMemory() ou freeMemory(), mesurant la quantité de mémoire disponible, est exprimé en octets (bytes). Son type est un entier long.

Exemple [voir]
public class Memoire {
    public static void main(String[] args){
      System.out.print("Mémoire totale : ");
      System.out.print(Runtime.getRuntime().totalMemory() / 1000000d);
      System.out.println("Mo.");
      System.out.print("Mémoire disponible : ");
      System.out.print(Runtime.getRuntime().freeMemory() / 1000000d);
      System.out.println("Mo.");

      System.out.println("Manipulation d'un objet String");
      String chaine = new String("La chaîne n°0");
      for(int i = 1; i <= 1000; i++){
        chaine = chaine.replaceAll(String.valueOf(i -1), String.valueOf(i));
        if(i % 100 == 0) {
            System.out.print(chaine);
            System.out.print(" - Mémoire consommée : ");
            System.out.print((Runtime.getRuntime().totalMemory() 
                                - Runtime.getRuntime().freeMemory())/1000d);
            System.out.println("ko.");
        }
      }
      System.out.println("Manipulation d'un objet StringBuffer");
      StringBuffer chaine2 = new StringBuffer("La chaîne n°0.");
      for(int i = 1; i <= 1000; i++){
        String nb = String.valueOf(i - 1); 
        int ind = chaine2.indexOf(nb);
        chaine2.replace(ind, ind + nb.length(), String.valueOf(i));
        if(i % 100 == 0) {
            System.out.print(chaine2);
            System.out.print(" - Mémoire consommée : ");
            System.out.print((Runtime.getRuntime().totalMemory() 
                                - Runtime.getRuntime().freeMemory())/1000d);
            System.out.println("ko.");
        }
      }
      System.out.println();

      System.out.print("Mémoire totale : ");
      System.out.print(Runtime.getRuntime().totalMemory() / 1000000d);
      System.out.println("Mo.");
      System.out.print("Mémoire disponible : ");
      System.out.print(Runtime.getRuntime().freeMemory() / 1000000d);
      System.out.println("Mo.");
    }
  }

23.6 / Quantité de mémoire disponible

La méthode maxMemory retourne la quantité maximum de mémoire que la Machine Virtuelle Java (JVM) pourrait utiliser..

S'il n'y a aucune limite de mémoire, la valeur Long.MAX_VALUE sera retourné par cette méthode.

public long maxMemory()

long taille = Runtime.getRuntime().maxMemory();

Le nombre retourné par maxMemory(), mesurant la quantité maximum de mémoire utilisable, est exprimé en octets (bytes). Son type est un entier long.

Exemple [voir]
public class Memoire {
    public static void main(String[] args){
      System.out.print("Mémoire totale : ");
      System.out.print(Runtime.getRuntime().totalMemory() / 1000000d);
      System.out.println("Mo.");
      System.out.print("Mémoire disponible : ");
      System.out.print(Runtime.getRuntime().freeMemory() / 1000000d);
      System.out.println("Mo.");
      System.out.print("Mémoire maximum utilisable : ");
      System.out.print(Runtime.getRuntime().maxMemory() / 1000000d);
      System.out.println("Mo.");
    }
}

24 / Les expressions régulières

Les expressions régulières sont des modèles utilisés pour rechercher dans un texte des combinaisons de caractères correspondantes.

Modèle : l.+sse
Possiblités :
lasse
lisse
laisse
limasse
l'impasse

Les modèles sont des chaînes de caractères incluant des caractères spécifiques. Ces caractères spécifiques peuvent être :

Il est possible de combiner ces caractères spécifiques pour créer un modèle correspondant à des séquences de caractères cibles.

Modèle : A.*
Séquences de caractères correspondantes :
Alors que Newton s'était assoupi sous un pommier, il découvra la gravité...
A son tour, Einstein inventa la théorie de la relativité générale.
Sans succès, Albert Einstein tenta d'unifier les forces qui régissent l'univers !
Aujourd'hui, la théorie des cordes semble être la clé de l'unification des forces.

Modèle : \b\w*m\w*\b
Jusqu'alors, les deux mondes de l'infiniment grand
et de l'infiniment petit étaient incompatibles.
Le monde microscopique est totalement imprévisible.
Le monde macroscopique est quant à lui prévisible.
La théorie des cordes harmonise ces deux mondes.

24.1 / La classe Pattern

La classe java.util.Pattern concerne la configuration et la création de modèles d'expression régulière.

ChampOption
Description
CANON_EQ 
Deux caractères correspondent si et seulement si leurs décompositions canoniques correspondent (ex.: '\\u00E0' correspond à 'à').
CASE_INSENSITIVE(?i)regexp
Les caractères US-ASCII minuscules ou majuscules correspondent (ex.: 'A' correspond à 'a').
COMMENTS(?x)regexp
Les espaces blancs et les commentaires commençant par le signe dièse '#' sont ignorés (ex.: ' ' ou \"#Une ligne...\" sont ignorés).
DOTALL(?s)regexp
Le point '.' permet de remplacer tous les caractères, y compris les caractères de fin de ligne (ex.: \".*\" correspond à \"Une ligne\nUne autre ligne\n\").
LITERAL 
L'espression est interprétée comme une séquence de caractères littérale, c'est à dire que les méta-caractères et les séquences d'échappement ne seront pas interprétés (ex.: \"\b.*\b\" recherche les occurrences \"\b.*\b\").
MULTILINE(?m)regexp
Les caractères '^' et '$' indiquent respectivement un début et une fin de ligne (ex.: \"^A.*$\" correspond à \"Alors...\\n\").
UNICODE_CASE(?u)regexp
L'expression de recherche est insensible à la casse des caractères, y compris pour tous les caractères Unicode (ex.: \u00C0 correspond à \u00E0).
UNIX_LINES(?d)regexp
Le terminateur de lignes correspond à un caractère de fin de ligne Unix (Line Feed : \\n).
Méthode
Description
static Pattern compile(String regex)
crée un modèle à partir de l'expression régulière fournie.
static Pattern compile(String regex, int flags)
crée un modèle à partir de l'expression régulière et d'un indicateur passés en argument. L'indicateur est une combinaison des options précitées.
int flags()
retourne l'indicateur pour le modèle courant.
Matcher matcher(CharSequence input)
crée un objet Matcher qui appliquera le modèle courant sur la chaîne de caractères passée en argument.
static boolean matches(String regex, CharSequence input)
compile une expression régulière à appliquer sur la chaîne de caractères fournie.
String pattern()
retourne l'expression régulière du modèle courant.
String[] split(CharSequence input)
découpe la chaîne de caractères spécifiée en fonction du modèle courant.
String[] split(CharSequence input, int limit)
découpe la chaîne de caractères spécifiée en fonction du modèle courant. La limite indique le nombre de fois que le modèle courant devra s'appliquer à la chaîne de caractères.
  • n < 0 : n-1 applications du modèle.
  • n = 0 : autant d'applications que possible, mais les sous-chaînes de caractères vides sont supprimées.
  • n > 0 : autant d'applications que possible en conservant toutes les sous-chaînes y-compris les vides.

24.1.1 / Les méthodes compile()

La création d'un objet Pattern nécessite l'appel de l'une des méthodes statiques compile(). La classe Pattern ne possède pas de constructeurs.

Ces méthodes acceptent soit une expression régulière exprimée sous la forme d'une chaîne de caractères, soit cette dernière à laquelle on associe une combinaison d'options.

Pattern modele = Pattern.compile("l.*e");
//ou
Pattern modele = Pattern.compile("l.*e", Pattern.CASE_INSENSITIVE);

Lorsqu'un modèle doit être configuré de telle sorte à satisfaire à plusieurs options, il suffit d'ajouter les options entre elles.

Pattern modele = Pattern.compile("l.*e", 
                                    Pattern.CASE_INSENSITIVE + Pattern.DOTALL);

Les deux méthodes compile() sont susceptibles de lancer des exceptions du type PatternSyntaxException, si l'expression régulière comporte une erreur de syntaxe. Si les options son erronées, une exception IllegalArgumentException sera levée.

//PatternSyntaxException : \w doit s'écrire \\w
Pattern modele = Pattern.compile("l\w*e");

//IllegalArgumentException : 3 ne correspond pas à une option valide
Pattern modele = Pattern.compile("l.*e", 
                              3 + 32); 

La méthode Matcher permet de créer un objet de mise en correspondance pour le modèle courant. C'est à partir de cet objet que la recherche d'occurrences dans un texte spécifié pourra être réalisée.

Matcher recherche = modele.matcher("Texte...");
boolean trouve = recherche.find();

Une vérification préalable de la présence d'une occurrence correspondant au modèle courant, au sein de la chaîne de caractères cible peut être effectuée par l'intermédiaire de la méthode matches().

if(Matcher.matches("\\bq\\w+\\b", "Un texte quelconque...")){
    //...
}
Exemple [voir]
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MiseEnCorrespondance {
    public static void main(String[] args) {
        Pattern modele = Pattern.compile("a.c");
        Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
        recherche(recherche);

        recherche.usePattern(
                    Pattern.compile("^a.c.*$", Pattern.MULTILINE));
        recherche(recherche);
    }
    public static void recherche(Matcher recherche) {
        String regexp = recherche.pattern().pattern();
        if(recherche.matches()){
            System.out.println("Une occurrence a été trouvée entre " 
                             + recherche.regionStart() 
                             + " et " 
                             + recherche.regionEnd());
            
            String chaine = recherche.group();
            int debut = recherche.start();
            int fin = recherche.end();

            System.out.println("Modèle     : " + regexp);
            System.out.println("Occurrence : " + chaine);
            System.out.println("Début      : " + debut);
            System.out.println("Fin        : " + fin + "\n");
        }
        else {
            System.out.println("Aucune correspondance n'a pu être " 
                             + "trouvée pour l'expression " 
                             + regexp + "\n");
        }
    }
}

24.1.2 / Les méthodes split()

La classe Pattern possède deux autres méthodes split() particulièrement utiles pour la décomposition d'une chaîne de caractères selon un séparateur de valeurs.

Contrairement à la méthode split() de la classe String, un argument de limite peut favoriser la récupération de valeurs vides.

Exemple [voir]
import java.util.regex.Pattern;

public final class RegExp {
    public static void main(String[] args) {
        String chaine = 
              "#numero;service;nom;prenom;adresse;"
                            + "telephone;portable;fax;salaire\n"
            + "A0025DE;DRH;Dunord;Jean;1a rue des Péchés "
                            + "75000 Paris;0145827421;;;\n"
            + "B1241AB;Direction;Angel;Julie;145 avenue Dausmesnil "
                    + "75000 Paris;0121127842;0664157862;0121127844;\n";
        RegExp rPos = new RegExp(8);
        RegExp rZero = new RegExp(0);
        RegExp r = new RegExp();
        RegExp rNeg = new RegExp(-8);

        String[] lignes = r.decomposition(chaine, "\n");
        executer(rPos, lignes);
        executer(rZero, lignes);
        executer(r, lignes);
        executer(rNeg, lignes);
    }
    public static void executer(RegExp re, String[] lignes) {
        for (int i = 0; i < lignes.length; i++) {
            if(lignes[i].length() < 1 
            || Pattern.matches("#.*", lignes[i])) continue;
            System.out.println("Cible : " + lignes[i]);
            System.out.println("Limite : " + re.limite);
            String[] valeurs = re.decomposition(lignes[i], ";");
            re.afficher(valeurs);
        }
    }
    public int limite;
    public RegExp(int limite) {
        this.limite = limite;
    }
    public String[] decomposition(String chaine, String separateur) {
        Pattern modele = Pattern.compile(separateur);
        String[] valeurs = modele.split(chaine, this.limite);
        return valeurs;
    }
    public void afficher(String[] valeurs) {
        System.out.println("Nombre de valeurs : " + valeurs.length);
        for(int i = 0; i < valeurs.length; i++) {
            System.out.println("\"" + valeurs[i] + "\"");
        }
        System.out.println();
    }
}

24.2 / La classe Matcher

La classe Matcher dispose de méthodes de mise en correspondance d'un modèle par rapport à un texte cible et d'obtention des positions des occurrences trouvées.

La création d'un objet Matcher doit s'effectuer par l'entremise de la méthode matcher() d'un objet Pattern. La méthode prend un argument qui est une chaîne de caractères sur laquelle s'appliquera des mises en correspondance du modèle courant.

Matcher recherche = modele.matcher("Un texte quelconque...");

Les méthodes de la classe Matcher se décomposent en trois groupes :

Méthode
Description
Matcher appendReplacement(StringBuffer sb, String replacement)
remplace au sein de l'objet StringBuffer l'occurrence correspondant au modèle courant, par la chaîne de caractères de substitution.
StringBuffer appendTail(StringBuffer sb)
s'utilise après avoir invoqué la méthode appendReplacement(), elle ajoute les caractères restants après une opération de remplacement au sein d el'objet StringBuffer spécifié.
int end()
retourne la position du dernier caractère (+ 1) d'une occurrence correspondant au modèle courant.
int end(int group)
retourne la position du dernier caractère (+ 1) d'une occurrence capturée dans le groupe indiqué par son numéro.
boolean find()
exécute une recherche d'une occurrence qui correspond au modèle courant.
boolean find(int start)
réinitialise l'objet Matcher et exécute une recherche d'une occurrence qui correspond au modèle courant, à partir d'une position spécifiée.
String group()
retourne une occurrence correspondant au modèle courant suite à une opération de recherche.
String group(int group)
retourne une occurrence du groupe spécifié par son numéro, correspondant au modèle courant suite à une opération de recherche.
int groupCount()
retourne le nombre de groupe de capture suite à une opération de recherche du modèle.
boolean lookingAt()
exécute une recherche d'occurences correspondant au modèle courant en commençant toujours au début d'une zone de la chaîne de caractères cible.
boolean matches()
exécute une recherche d'occurences correspondant au modèle courant sur la totalité de la chaîne de caractères cible.
Pattern pattern()
retourne le modèle qui est appliqué par l'objet Matcher courant.
String replaceAll(String replacement)
remplace chaque occurrences correspondant au modèle courant, par la chaîne de caractères de substitution.
String replaceFirst(String replacement)
remplace la première occurrence correspondant au modèle courant, par la chaîne de caractères de substitution.
Matcher reset()
réinitialise l'objet courant.
Matcher reset(CharSequence input)
réinitialise 'objet Matcher avec une nouvelle chaîne de caractères.
int start()
retourne la position du premier caractère d'une occurrence correspondant au modèle courant.
int start(int group)
retourne la position du premier caractère d'une occurrence capturée dans le groupe indiqué par son numéro, correspondant au modèle courant.

24.2.1 / L'interface MatchResult

L'interface MatchResult regroupe des méthodes destinées à être implémentées pour la récupération des informations à propos des occurrences correspondant à un modèle d'expression régulière.

La classe Matcher implémente cette interface. D'ailleurs, un objet de type référence MatchResult peut être récupéré par l'intermédiaire de la méthode toMatchResult().

MatchResult resultat = recherche.toMatchResult();
Méthode
Description
int end()
retourne la position du dernier caractère (+ 1) d'une occurrence correspondant au modèle courant.
int end(int group)
retourne la position du dernier caractère (+ 1) d'une occurrence capturée dans le groupe indiqué par son numéro.
String group()
retourne une occurrence correspondant au modèle courant suite à une opération de recherche.
String group(int group)
retourne une occurrence du groupe spécifié par son numéro, correspondant au modèle courant suite à une opération de recherche.
int groupCount()
retourne le nombre de groupe de capture suite à une opération de recherche du modèle.
int start()
retourne la position du premier caractère d'une occurrence correspondant au modèle courant.
int start(int group)
retourne la position du premier caractère d'une occurrence capturée dans le groupe indiqué par son numéro, correspondant au modèle courant.
Exemple [voir]
public class Recherche {
    public static void main(String[] args) {
        String cible = 
            "Jusqu'alors, les deux mondes de l'infiniment grand\n" +
            "et de l'infiniment petit étaient incompatibles.\n" +
            "Le monde microscopique est totalement imprévisible.\n" +
            "Le monde macroscopique est quant à lui prévisible.\n" +
            "La théorie des cordes harmonise ces deux mondes.\n";
        String regexp = "\\b\\w*m\\w*\\b";

        Pattern modele = Pattern.compile(regexp);
        Matcher recherche = modele.matcher(cible);

        while(recherche.find()){
            MatchResult resultat = recherche.toMatchResult();
            int nombre = resultat.groupCount();
            if(nombre > 0) {
                for (int i = 0; i < nombre; i++) {
                    String chaine = recherche.group(i);
                    int debut = recherche.start(i);
                    int fin = recherche.end(i);
                    afficher(regexp, chaine, debut, fin, i + 1);
                }
            }
            else {
                String chaine = recherche.group();
                int debut = recherche.start();
                int fin = recherche.end();
                afficher(regexp, chaine, debut, fin, 1);
            }
        }
    }

    public static void afficher(String regexp, String chaine, int debut, int fin, int numero) {
        System.out.println("Une occurrence a été trouvée");
        System.out.println("Modèle     : " + regexp);
        System.out.println("Numéro     : " + numero);
        System.out.println("Occurrence : " + chaine);
        System.out.println("Début      : " + debut);
        System.out.println("Fin        : " + fin + "\n");
    }
}

24.2.2 / Les méthodes de recherche

Les méthodes de mise en correspondance permettent de trouver des occurrences au sein d'une chaîne de caractères, correspondant à un modèle d'expression régulière.

24.2.2.1 / Les méthodes find()

Le premier appel de la méthode find() démarre une recherche à partir du début de la chaîne de caractères cible, puis lors des appels suivants, la recherche débute au premier caractère suivant l'occurrence trouvée. Tant qu'une occurrence est trouvée la méthode retourne true.

Cible : >abcxxxabcxxxabcxxx
Expression régulière : "a.c"
Premier appel   : abc>xxxabcxxxabcxxx => true
Second appel    : abcxxxabc>xxxabcxxx => true
Troisième appel : abcxxxabcxxxabc>xxx = true
Quatrième appel : abcxxxabcxxxabcxxx> => false

Pattern modele = Pattern.compile("a.c");
Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
while(recherche.find()){
    System.out.println("Une occurrence a été trouvée");
    //...
}

Il existe une autre méthode find() qui possède un paramètre indiquant à quelle position démarrer la recherche.

if(recherche.find(10)){
    System.out.println("Une occurrence a été trouvée "
                            + "après la position 10.");
}
Exemple [voir]
private void rechercher() {
    try {
        if(this.fen.getTxtSource() != null 
        && !this.fen.getTxtSource().equals(Utilitaires.VIDE)
        && this.fen.getExpression() != null 
        && !this.fen.getExpression().equals(Utilitaires.VIDE)) {
            Pattern modele = Pattern.compile(this.fen.getExpression(), 
                     this.calculerOptions());
            Matcher recherche = modele.matcher(this.fen.getTxtSource());
            int compteur = 0;
            this.fen.initTable();
            this.fen.supprimerSelection();
            while(recherche.find()) {
                compteur++;
                int nombre = recherche.groupCount();
                if(nombre > 0) {
                    for (int i = 0; i < nombre; i++) {
                        this.afficher(
                                    compteur,
                                    i + 1,
                                    recherche.start(i), 
                                    recherche.end(i), 
                                    recherche.group(i));
                    }
                }
                else {
                    this.afficher(
                                compteur,
                                0,
                                recherche.start(), 
                                recherche.end(), 
                                recherche.group());
                }
            }
            this.fen.setLblTrouves(this.afficherTrouves(compteur));
            this.fen.ajouterSelection();
        }
    }
    catch(PatternSyntaxException e) {
        this.afficher(e);
    }
}

24.2.2.2 / La méthode lookingAt()

La méthode lookingAt() recherche des occurrences dans une zone délimitée par la méthode region(), de la chaîne de caractères cible. La mise en correspondance commence toujours au début de cette zone.

Les zones délimitées par la méthode region() apparaissent dans la version JDK 1.5.

Matcher zone = recherche.region(6, 12);

Par défaut, une zone concerne la totalité de la chaîne de caractères cible. La définition d'une zone nécessite d'invoquer la méthode region() et de lui passer des valeurs entières précisant ses limites.

Matcher zone = recherche.region(7, 16);
if(zone.lookingAt()){
    System.out.println("Une occurrence a été trouvée entre " 
                      + zone.regionStart() + " et " 
                      + zone.regionEnd());
    //...
}
Exemple [voir]
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Regard {
    public static void main(String[] args) {
        Pattern modele = Pattern.compile("a.c");
        Matcher regard = modele.matcher("abcxxxabcxxxabcxxx");
        regard.region(6, 16);
        regarder(regard);

        regard.reset();
        regard.usePattern(Pattern.compile("^a.c.*$", Pattern.MULTILINE));
        regarder(regard);
    }
    public static void regarder(Matcher regard) {
        String regexp = regard.pattern().pattern();
        if(regard.lookingAt()){
            System.out.println("Une occurrence a été trouvée entre " 
                             + regard.regionStart() 
                             + " et " 
                             + regard.regionEnd());
            
            String chaine = regard.group();
            int debut = regard.start();
            int fin = regard.end();

            System.out.println("Modèle     : " + regexp);
            System.out.println("Occurrence : " + chaine);
            System.out.println("Début      : " + debut);
            System.out.println("Fin        : " + fin + "\n");
        }
        else {
            System.out.println("Aucune correspondance n'a pu être " 
                             + "trouvée pour l'expression " 
                             + regexp + "\n");
        }
    }
}

24.2.2.3 / La méthode matches()

la méthode matches() pratique une mise en correspondance sur la chaîne de caractères cible complète. C'est à dire que l'expression régulière doit s'appliquer à la chaîne de caractères entière, au contraire des méthodes find() et lookingAt(). De même que la méthode lookingAt(), la recherche commence toujours au début de l'entrée.

Pattern modele = Pattern.compile("a.c");
Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
if(recherche.matches()){
    //Cette recherche échoue toujours...
    //Le modèle ne correspond pas à l'entrée entière
}

Pattern modele = Pattern.compile("a.c\\w*");
Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
if(recherche.matches()){
    System.out.println("Le modèle correspond effectivement à l'entrée.");
}

Au contraire de la méthode find(), il ne faut pas utiliser la méthode matches() comme condition d'une boucle, car une itération infinie s'exécuterait puisque le résultat de la recherche sur une même séquence d'entrée sera toujours le même. Evidemment, si le résultat est false, la boucle ne démarre pas.

Pattern modele = Pattern.compile("^a\\w*$", Pattern.MULTILINE);
Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
while(recherche.matches()){
    //Boucle infinie...
}
Exemple [voir]
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MiseEnCorrespondance {
    public static void main(String[] args) {
        Pattern modele = Pattern.compile("a.c");
        Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
        recherche(recherche);

        recherche.reset();
        recherche.usePattern(Pattern.compile("^a.c.*$", Pattern.MULTILINE));
        recherche(recherche);
    }
    public static void recherche(Matcher recherche) {
        String regexp = recherche.pattern().pattern();
        if(recherche.matches()){
            System.out.println("Une occurrence a été trouvée entre " 
                             + recherche.regionStart() 
                             + " et " 
                             + recherche.regionEnd());
            
            String chaine = recherche.group();
            int debut = recherche.start();
            int fin = recherche.end();

            System.out.println("Modèle     : " + regexp);
            System.out.println("Occurrence : " + chaine);
            System.out.println("Début      : " + debut);
            System.out.println("Fin        : " + fin + "\n");
        }
        else {
            System.out.println("Aucune correspondance n'a pu être " 
                             + "trouvée pour l'expression " 
                            + regexp + "\n");
        }
    }
}

24.2.2.4 / Les informations sur les occurrences

Suite à une mise en correspondance, il peut être utile de récupérer les occurrences et leurs limites.

Plusieurs méthodes sont conçues à cet effet. La méthode group() permet de récupérer une occurrence, tandis que les méthodes start() et end() retournent les positions de début et de fin de l'occurrence au sein de la chaîne de caractères cible.

Pattern modele = Pattern.compile("a.c");
Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
while(recherche.find()){
    System.out.println("Occurrence : " + recherche.group());
    System.out.println("Début      : " + recherche.start());
    System.out.println("Fin        : " + recherche.end() + "\n");
}
System.out.println("Utilisation de lookingAt()");
Matcher zone = recherche.region(6, 16);
if(zone.lookingAt()){
    int debut = recherche.start();
    int fin = recherche.end();
    String chaine = recherche.group();
    System.out.println("Occurrence : " + chaine);
    System.out.println("Début      : " + debut);
    System.out.println("Fin        : " + fin + "\n");
}
Resultats :
Occurrence : abc
Début      : 0
Fin        : 3

Occurrence : abc
Début      : 6
Fin        : 9

Occurrence : abc
Début      : 12
Fin        : 15

Utilisation de lookingAt()
Occurrence : abc
Début      : 6
Fin        : 9
Exemple [voir]
private void rechercher() {
    try {
        if(this.fen.getTxtSource() != null 
        && !this.fen.getTxtSource().equals(Utilitaires.VIDE)
        && this.fen.getExpression() != null 
        && !this.fen.getExpression().equals(Utilitaires.VIDE)) {
            Pattern modele = Pattern.compile(this.fen.getExpression(), 
                     this.calculerOptions());
            Matcher recherche = modele.matcher(this.fen.getTxtSource());
            int compteur = 0;
            this.fen.initTable();
            this.fen.supprimerSelection();
            while(recherche.find()) {
                compteur++;
                this.afficher(
                            compteur,
                            0,
                            recherche.start(), 
                            recherche.end(), 
                            recherche.group());
            }
            this.fen.setLblTrouves(this.afficherTrouves(compteur));
            this.fen.ajouterSelection();
        }
    }
    catch(PatternSyntaxException e) {
        this.afficher(e);
    }
}
private void afficher(int compteur, int groupe, int debut, int fin, String chaine) {
    final String[] valeurs = new String[] {
                            String.valueOf(compteur),
                            groupe > 0 ? String.valueOf(groupe) : Utilitaires.VIDE, 
                            String.valueOf(debut), 
                            String.valueOf(fin), 
                            chaine};
    fen.getModele().addRow(valeurs);
}

24.2.2.5 / Les informations sur les groupes

Lorsque l'expression régulière contient des groupes de capture, les occurrences trouvées se voient stockées dans des groupes, accessibles par la méthode group(int).

De la même façon, les positions de début et de fin d'une occurrence peuvent être récupérées en appelant respectivement les méthodes start(int) et end(int). Le nombre de groupes disponibles est fourni par la méthode groupCount()

Pattern modele = Pattern.compile("((a.)c)");
Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
int compteur = 0;
while(recherche.find()) {
    compteur++;
    System.out.println("Une occurrence a été trouvée : " + compteur);
    int nombre = recherche.groupCount();
    if(nombre > 0) {
        for (int i = 0; i < nombre; i++) {
            int debut = recherche.start(i);
            int fin = recherche.end(i);
            String chaine = recherche.group(i);
            System.out.println(i + " " + chaine + " " + debut + " " + fin);
        }
    }
    else {
        int debut = recherche.start();
        int fin = recherche.end();
        String chaine = recherche.group();
        System.out.println(chaine + " " + debut + " " + fin);
    }
}
Resultats :
Une occurrence a été trouvée : 1
0 abc 0 3
1 abc 0 3
Une occurrence a été trouvée : 2
0 abc 6 9
1 abc 6 9
Une occurrence a été trouvée : 3
0 abc 12 15
1 abc 12 15
Exemple [voir]
private void rechercher() {
    try {
        if(this.fen.getTxtSource() != null 
        && !this.fen.getTxtSource().equals(Utilitaires.VIDE)
        && this.fen.getExpression() != null 
        && !this.fen.getExpression().equals(Utilitaires.VIDE)) {
            Pattern modele = Pattern.compile(this.fen.getExpression(), 
                     this.calculerOptions());
            Matcher recherche = modele.matcher(this.fen.getTxtSource());
            int compteur = 0;
            this.fen.initTable();
            this.fen.supprimerSelection();
            while(recherche.find()) {
                compteur++;
                int nombre = recherche.groupCount();
                if(nombre > 0) {
                    for (int i = 0; i < nombre; i++) {
                        int debut = recherche.start(i);
                        int fin = recherche.end(i);
                        String chaine = recherche.group(i);
                        this.afficher(
                                    compteur,
                                    i + 1,
                                    debut, 
                                    fin, 
                                    chaine);
                    }
                }
                else {
                    int debut = recherche.start();
                    int fin = recherche.end();
                    String chaine = recherche.group();
                    this.afficher(
                                compteur,
                                0,
                                debut, 
                                fin, 
                                chaine);
                }
            }
            this.fen.setLblTrouves(this.afficherTrouves(compteur));
            this.fen.ajouterSelection();
        }
    }
    catch(PatternSyntaxException e) {
        this.afficher(e);
    }
}
private void afficher(int compteur, int groupe, int debut, int fin, String chaine) {
    final String[] valeurs = new String[] {
                            String.valueOf(compteur),
                            groupe > 0 ? String.valueOf(groupe) : Utilitaires.VIDE, 
                            String.valueOf(debut), 
                            String.valueOf(fin), 
                            chaine};
    fen.getModele().addRow(valeurs);
}

24.2.2.6 / Les informations pour lookingAt() et matches()

Dans le cas de la méthode lookingAt(), seule la première occurrence dans la zone est trouvée, et cela même s'il en existe d'autres.

Si le modèle d'expression régulière s'applique à la chaîne entière, l'occurrence résultante en cas de réussite, sera la chaîne de caractères complètes. Les limites seront donc en cas de correspondance le début (0) et la fin (chaine.length()) de la séquence d'entrée.

Ce dernier comportement de la méthode lookingAt() est identique pour la méthode matches(), l'occurrence ne peut être que la totalité de la chaîne de caractères si la mise en correspondance réussie.

Exemple [voir]
import java.util.regexp.Matcher;
import java.util.regexp.Pattern;
public class MiseEnCorrespondance {
    public static void main(String[] args){
        Pattern modele = Pattern.compile("a.c\\w*");
        Matcher recherche = modele.matcher("abcxxxabcxxxabcxxx");
        if(recherche.matches()){
            int debut = recherche.start();
            int fin = recherche.end();
            String chaine = recherche.group();
            System.out.println("Une occurrence a été trouvée");
            System.out.println(chaine + " " + debut + " " + fin);
        }
        Matcher zone = recherche.region(6, 16);
        if(zone.lookingAt()){
            int debut = recherche.start();
            int fin = recherche.end();
            String chaine = recherche.group();
            System.out.println("Une occurrence a été trouvée");
            System.out.println(chaine + " " + debut + " " + fin);
        }
    }
    Résultats : 
    Une occurrence a été trouvée
    abcxxxabcxxxabcxxx 0 18
    Une occurrence a été trouvée
    abcxxxabcx 6 16
}

24.2.3 / Les méthodes de remplacement

Les méthodes de remplacement organisent la substitution d'occurrences correspondantes à un modèle d'expression régulière, par une séquence de caractères de remplacement.

24.2.3.1 / Les méthodes replaceFirst() et replaceAll()

Les méthodes repaceFirst() et replaceAll() fonctionnent d'une façon identique à celle de la classe java.lang.String.

Ces méthodes prennent en argument une chaîne de caractères de substitution, qui doit remplacer seulement la première (replaceFirst()) ou toutes (replaceAll()) les occurrences correspondantes au modèle courant.

Pattern modele = Pattern.compile("x{3}");
Matcher correspondance = modele.matcher("abcxxxabcxxxabcxxx");
String resultat = modele.replaceFirst("def");
System.out.println(resultat);
Matcher correspondance = modele.matcher(resultat);
String resultat = modele.replaceAll("ghi");
System.out.println(resultat);
Exemple [voir]
import java.util.regexp.Matcher;
import java.util.regexp.Pattern;

public class Substitution {
    public static void main(String[] args) {
        String cible = 
            "Elle a été citée à la bourse de Tikyi à l'heure de la cliture vers 18h00.";
        String regexp = "i";
        String remplacement = Matcher.quoteReplacement("\\w");

        Pattern modele = Pattern.compile(regexp);
        Matcher recherche = modele.matcher(cible);
        remplacer(recherche, remplacement);
        recherche.reset();
        remplacer(recherche, "o");
    }

     public static void remplacer(Matcher recherche, String remplacement) {
        System.out.println("Substitution de '" 
                         + recherche.pattern().pattern() 
                         + "' par '" + remplacement + "'");

        System.out.println("Remplacement de la première occurrence");
        String resultat = recherche.replaceFirst(remplacement);
        System.out.println(resultat.toString());

        System.out.println("Remplacement de toutes les occurrences");
        resultat = recherche.replaceAll(remplacement);
        System.out.println(resultat.toString());

        System.out.println();
    }
}

24.2.3.2 / La méthode appendReplacement()

La méthode appendReplacement() travaille conjointement avec la méthode appendTail() pour le remplacement d'occurrences au sein d'un objet StringBuffer.

La méthode appendReplacement() exécute des remplacements. La méthode appendTail() doit être appelée après une ou plusieurs invocations de la méthode appendReplacement() afin de copier le reste de la chaîne de caractères cible.

Si cette méthode n'était pas invoquée après des opérations de remplacement, alors la chaîne de caractères résultantes ne serait pas complète.

Pattern modele = Pattern.compile("x{3}");
Matcher correspondance = modele.matcher("abcxxxabcxxxabcxxx");
StringBuffer chaine = new StringBuffer();
while (correspondance.find()) {
    correspondance.appendReplacement(chaine, "def");
}
System.out.println(chaine.toString());
correspondance.appendTail(chaine);
System.out.println(chaine.toString());

La méthode utilitaire quoteReplacement() retourne une chaîne de caractères de remplacement destinée à être utiliser dans la méthode appendReplacement(). Les éventuels signes '\' et '$' de la chaîne passée en argument, n'auront aucune signfication particullière dans la chaîne de caractères résultante.

String litteral = Matcher.quoteReplacement("\\w+$");
Exemple [voir]
import java.util.regexp.Matcher;
import java.util.regexp.Pattern;

public class Remplacement {
    public static void main(String[] args) {
        String cible = 
            "Elle a été citée à la bourse de Tikyi à l'heure de la cliture vers 18h00.";
        String regexp = "i";
        String remplacement = Matcher.quoteReplacement("\\w");

        Pattern modele = Pattern.compile(regexp);
        Matcher recherche = modele.matcher(cible);
        remplacer(recherche, remplacement);
        recherche.reset();
        remplacer(recherche, "o");
    }

     public static void remplacer(Matcher recherche, String remplacement) {
         StringBuffer resultat = new StringBuffer();
        System.out.println(recherche.pattern().pattern());
        while(recherche.find()){
            String chaine = recherche.group();
            int debut = recherche.start();
            int fin = recherche.end();
            afficher(recherche.pattern().pattern(), chaine, debut, fin);

            recherche.appendReplacement(resultat, remplacement);
        }
        System.out.println(resultat.toString());

        recherche.appendTail(resultat);

        System.out.println(resultat.toString());

    }
    public static void afficher(String regexp, String chaine, int debut, int fin) {
        System.out.println("Une occurrence a été trouvée");
        System.out.println("Modèle     : " + regexp);
        System.out.println("Occurrence : " + chaine);
        System.out.println("Début      : " + debut);
        System.out.println("Fin        : " + fin + "\n");
    }
}

24.2.4 / Les méthodes reset()

Une réinitialisation provoque le déchargement de l'état de l'objet courant, soit les positions de départ et de fin, ainsi que l'occurrence, et place également la position d'ajout à zéro.

La réinitialisation des objets Matcher s'obtient par une invocation des méthodes reset().

L'état d'un objet Matcher est récupérable par l'intermédiaire de la méthode toMatchResult(), retournant un objet de type référence MatchResult.

MatchResult resultat = correspondance.toMatchResult();

De plus, si une zone a été définie, elle est réadaptée à la chaîne de caractères cible entière. Enfin, l'ancrage et la transparence des limites d'une zone sont à leur tour désaffecté.

Matcher correspondance = correspondance.reset();

Il existe deux méthodes reset() pour réinitialiser un objet Matcher, mais l'une d'elle prend comme argument une chaîne de caractères destinée à remplacer la séquence d'entrée de l'objet courant.

Matcher correspondance = 
        correspondance.reset("Une nouvelle chaîne de caractères...");

Le modèle d'expression régulière peut lui aussi être modifié à partir de l'objet Matcher. Pour cela, il suffit de d'appeler la méthode usePattern(), à laquelle il faut passer comme argument un nouvel objet Pattern qui remplacera l'existant.

Matcher correspondance = 
            correspondance.usePattern(Pattern.compile("A.*Z"));
Exemple [voir]
import java.util.regexp.Matcher;
import java.util.regexp.Pattern;

public class Reinitialisation {
    public static void main(String[] args) {
        String cible = 
                "Alors que Newton s'était assoupi sous un pommier, " + 
                "il découvra la gravité...\n" +
                "A son tour, Einstein inventa la théorie de la relativité " + 
                "générale.\n" +
                "Sans succès, Albert Einstein tenta d'unifier les forces " + 
                "qui régissent l'univers !\n" +
                "Aujourd'hui, la théorie des cordes semble être la clé de " + 
                "l'unification des forces.";

        Pattern modele = Pattern.compile("A.*$", Pattern.MULTILINE);
        Matcher recherche = modele.matcher(cible);
        recherche(recherche);
        String sequence = 
                "Jusqu'alors, les deux mondes de l'infiniment grand\n" +
                "et de l'infiniment petit étaient incompatibles.\n" +
                "Le monde microscopique est totalement imprévisible.\n" +
                "Le monde macroscopique est quant à lui prévisible.\n" +
                "La théorie des cordes harmonise ces deux mondes.\n";

        recherche.reset(sequence);
        recherche.usePattern(Pattern.compile("\\bm\\w*\\b"));
        recherche(recherche);
    }

    public static void recherche(Matcher recherche) {
        String regexp = recherche.pattern().pattern();
        while(recherche.find()){
            System.out.println("Une occurrence a été trouvée entre " 
                             + recherche.regionStart() 
                             + " et " 
                             + recherche.regionEnd());
            
            String chaine = recherche.group();
            int debut = recherche.start();
            int fin = recherche.end();

            System.out.println("Modèle     : " + regexp);
            System.out.println("Occurrence : " + chaine);
            System.out.println("Début      : " + debut);
            System.out.println("Fin        : " + fin + "\n");
        }
    }
}

24.2.5 / Le comportement des limites

La manière dont les limites des zones interactives avec un certaines formes de modèle peut être modifiée en invoquant des méthodes spécifiques useAnchoringBounds() et useTransparentBounds().

La méthode useAnchoringBounds() fixe l'ancrage des limites d'une zone pour un objet Matcher. L'appel de cette méthode avec un argument booléen true indique à l'objet courant, d'utiliser l'ancrage des limites, c'est à dire, les ancres '^' (début de ligne) et '$' (fin de ligne). Par défaut, un objet Matcher utilise l'ancrage des limites.

if(!correspondance.hasAnchoringBounds())
    correspondance.useAnchoringBounds(true);

La méthode hasAnchoringBounds() indique si l'objet Matcher utilise un ancrage des limites.

La méthode useTransparentBounds() détermine si l'objet doit utiliser des limites de zones transparentes (true) ou opaques (false). Si l'argument est true, cela signifie que les limites de zones sont transparentes pour les modèles de formes de modèles du type lookahead et lookbehind. Dans ce cas, lors de la mise en correspondance, la validation d'une occurrence est soumise au préalable à un contrôle avant ou arrière d'une sous-expression régulière.

if(!correspondance.hasTransparentBounds())
    correspondance.useTransparentBounds(true);

La méthode hasTransparentBounds() indique si l'objet Matcher utilise des limites transparentes.

Exemple [voir]
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Limites {
    public static void main(String[] args) {
        String cible = 
            "Alors que Newton s'était assoupi sous un pommier, " + 
            "il découvra la gravité...\n" +
            "A son tour, Einstein inventa la théorie de la relativité " + 
            "générale.\n" +
            "Sans succès, Albert Einstein tenta d'unifier les forces " + 
            "qui régissent l'univers !\n" +
            "Aujourd'hui, la théorie des cordes semble être la clé de " + 
            "l'unification des forces.";

        Pattern modele = Pattern.compile("^A.*$", Pattern.MULTILINE);
        Matcher recherche = modele.matcher(cible);
        recherche.useAnchoringBounds(true);
        verification(recherche);
        recherche(recherche);
        String sequence = 
            "Jusqu'alors, les deux mondes de l'infiniment grand\n" +
            "et de l'infiniment petit étaient incompatibles.\n" +
            "Le monde microscopique est totalement imprévisible.\n" +
            "Le monde macroscopique est quant à lui prévisible.\n" +
            "La théorie des cordes harmonise ces deux mondes.\n";

        recherche.reset(sequence);
        recherche.usePattern(Pattern.compile("\\b\\w+(?<=s)\\b"));
        recherche.useTransparentBounds(true);
        verification(recherche);
        recherche(recherche);
    }
    public static void verification(Matcher recherche) {
        if(recherche.hasAnchoringBounds())
            System.out.println("Utilisation de l'ancrage des limites");
        else
            System.out.println("Utilisation du non-ancrage des limites");
        if(recherche.hasTransparentBounds())
            System.out.println("Utilisation de la transparence des limites");
        else
            System.out.println("Utilisation de l'opacité des limites");
        
    }
    public static void recherche(Matcher recherche) {
        String regexp = recherche.pattern().pattern();
        if(recherche.find()){
            System.out.println("Une occurrence a été trouvée entre " 
                             + recherche.regionStart() 
                             + " et " 
                             + recherche.regionEnd());
            
            String chaine = recherche.group();
            int debut = recherche.start();
            int fin = recherche.end();

            System.out.println("Modèle     : " + regexp);
            System.out.println("Occurrence : " + chaine);
            System.out.println("Début      : " + debut);
            System.out.println("Fin        : " + fin + "\n");
        }
    }
}

24.2.6 / Divers

La méthode hitEnd() retourne true si la fin de la séquence d'entrée était trouvée lors de la recherche dans la dernière mise en correspondance exécutée par l'objet Matcher. Si cette méthode retourne true et une mise en correspondance a été trouvée, alors requireEnd()

24.3 / L'exception PatternSyntaxException

La création de modèle d'expression régulière peut provoquer la levée d'une exception PatternSyntaxException.

Cette exception se produit si l'expression régulière passée en argument à la méthode compile() de la classe Pattern, comporte des erreurs de syntaxe.

try {
    //Produit une exception car une parenthèse ouvrante 
    //est présente sans la parenthèse fermante
    Pattern modele = Pattern.compile("\\b(A\\w+\\b");
}
catch(PatternSyntaxException e){
    System.out.println(e.getMessage());
}

Un message clair avec une description de l'erreur de syntaxe et un indicateur visuel stuant où elle se situe peut être obtenu en appelant la méthode getMessage().

Unclosed group near index 12
\\b(A\\w+\\b
            ^

Par ailleurs, la classe PatternSyntaxException propose également des méthodes pour récupérer une description (getDescription()), la position de l'erreur (getIndex()) et l'expression régulière erronée (getPattern()).

Description : Unclosed group near index 12
Modèle      : \\b(A\\w+\\b
Position    : 12
Constructeur
Description
PatternSyntaxException(String desc, String regex, int index)
crée une nouvelle instance de la classe PatternSyntaxException en l'initialisant avec une description de l'erreur, l'expression régulière erronée et la position où se situe le début de l'erreur.
Méthode
Description
String getDescription()
retourne la description de l'erreur.
int getIndex()
retourne la position de l'erreur au sein de la chaîne de caractères cible.
String getMessage()
retourne un message complet décrivant l'erreur contenant une description de l'erreur de syntaxe, un indicateur visuel de l'erreur et la position de cette dernière.
String getPattern()
retourne le modèle d'expression régulière erroné.
Exemple [voir]
private void rechercher() {
    try {
        if(this.fen.getTxtSource() != null 
        && !this.fen.getTxtSource().equals(Utilitaires.VIDE)
        && this.fen.getExpression() != null 
        && !this.fen.getExpression().equals(Utilitaires.VIDE)) {
            Pattern modele = Pattern.compile(this.fen.getExpression(), 
                     this.calculerOptions());
            Matcher recherche = modele.matcher(this.fen.getTxtSource());
            int compteur = 0;
            this.fen.initTable();
            this.fen.supprimerSelection();
            while(recherche.find()) {
                compteur++;
                int nombre = recherche.groupCount();
                if(nombre > 0) {
                    for (int i = 0; i < nombre; i++) {
                        int debut = recherche.start(i);
                        int fin = recherche.end(i);
                        String chaine = recherche.group(i);
                        this.afficher(
                                    compteur,
                                    i + 1,
                                    recherche.start(i), 
                                    recherche.end(i), 
                                    recherche.group(i));
                    }
                }
                else {
                    int debut = recherche.start();
                    int fin = recherche.end();
                    String chaine = recherche.group();
                    this.afficher(
                                compteur,
                                0,
                                recherche.start(), 
                                recherche.end(), 
                                recherche.group());
                }
            }
            this.fen.setLblTrouves(this.afficherTrouves(compteur));
            this.fen.ajouterSelection();
        }
    }
    catch(PatternSyntaxException e) {
        this.afficher(e);
    }
}
private void afficher(PatternSyntaxException e) {
    JOptionPane.showMessageDialog(
                this.fen, 
                e.getMessage(), 
                "Erreur : " + e.getPattern(), 
                JOptionPane.WARNING_MESSAGE);
}

24.4 / La syntaxe des expressions régulières

Les expressions régulières doivent se conformer aux règles de syntaxe énoncées au sein de la spécification ISO/IEC 9945.

Les erreurs de syntaxe peuvent être sanctionnées par un dysfonctionnement du modèle d'expression régulière, soit en fonctionnant d'une manière inattendue, soit en levant une exception du type PatternSyntaxException.

24.4.1 / Les caractères

Les expressions régulières peuvent être composées d'un ou plusieurs caractères. Ces caractères peuvent provenir des jeux de caractères US-ASCII ou/et Unicode.

//Recherche du caractère a
Expression régulière : a
Cible :
Grâce au clonage, les femmes pourraient procréer 
seules et ainsi se passer des hommes.

//Recherche des caractères accentués â ou é
Expression régulière : â|é
Cible :
Grâce au clonage, les femmes pourraient procréer 
seules et ainsi se passer des hommes.

Les caractères d'une séquence d'entrée, peuvent avoir une forme canonique (ex.: X) ou une forme numérique (ex.: \u005D) ou bien les deux combinées.

//Recherche des caractères â, é ou m
Expression régulière : \u00E2|\u00E9|\u006D
Cible :
Grâce au clonage, les femmes pourraient 
procréer seules et ainsi se passer des hommes.

Il est également possible d'utiliser des caractères spéciaux afin d'exprimer notamment les espaces blancs tels qu'un espace, une tabulation ou encore une fin de ligne.

//Recherche du caractère s avant une fin de ligne
Expression régulière : s\n
Cible :
Grâce au clonage, les femmes pourraient procréer seules 
et ainsi se passer des hommes.

Certains caractères spécifiques aux expressions régulières, appelés méta-caractères, ne peuvent être utilisés tels quels dans les expressions régulières. Il est nécessaire, dans ce cas, d'échapper les caractères. C'est le cas des caractères suivants : ( [ { \ ^ $ | ) ? * + ..

//Recherche d'une sous-chaîne entre des parenthèses
Expression régulière : \(.*\)
Cible :
Le premier animal cloné (la brebis dolly) 
a ouvert la porte au clonage humain.

//Recherche d'une sous-chaîne entre des accolades
Expression régulière : \{.*}
Cible :
Le premier animal cloné {la brebis dolly} 
a ouvert la porte au clonage humain.
Les caractères
SymbolesDescription
xUn caractère quelconque.
\\Le caractère anti-slash.
\0nUn caractère exprimé en valeur octale, ou n est compris entre 0 et 7.
\0nnUn caractère exprimé en valeur octale, ou n est compris entre 0 et 7.
\0mnnUn caractère exprimé en valeur octale, ou n est compris entre 0 et 7 et m entre 0 et 3.
\xhhUn caractère exprimé en valeur hexadécimale, ou h est compris entre 0 et F.
\uhhhhUn caractère exprimé en valeur Unicode, ou h est compris entre 0 et F.
\bLe caractère de retour arrière ('\u0008').
\tLe caractère de tabulation ('\u0009').
\nLe caractère de fin de ligne (LF : Line Feed :'\u000A')
\rLe caractère de retour charriot (CR : Carriage Return : '\u000D').
\fLe caractère de fin de formulaire (FF : Form Feed : '\u000C').
\aLe caractère d'alerte (bell : '\u0007').
\eLe caractère échappe (escape : '\u001B').
\cxLe caractère de contrôle avec un caractère quelconque (CTRL + x).
\u0085Le caractère de prochaîne ligne.
\u2028Le caractère de séparateur de lignes.
\u2029Le caractère de séparateur de paragraphes.

24.4.1.1 / Les règles

L'utilisation conjointe des expressions régulières avec le langage Java, nécessite de respecter des règles, sans lesquelles, un modèle d'expression régulière ne pourrait correctement fonctionner lors d'un processus de mise en correspondance.

Le langage Java oblige à doubler l'anti-slash dans les expressions régulières. Dans le cas contraire, il pourrait y avoir une confusion entre un caractère spécial et un méta-caractère, ou pire pourrait entraîner une erreur de compilation.

"\b" //Recherche d'un caractère backspace
"\\b" //Recherche d'une limite de mots
"\(" //Entraîne une erreur de compilation
"\\(" //Recherche une parenthèse ouvrante
"\\{" //Recherche une accolade ouvrante
"\\[" //Recherche un crochet ouvrant

"[a-z\-\.]" //Recherche d'une lettre de 'a' à 'z', d'un tiret ou d'un point

Les caractères de fin de ligne sont différents selon la plateforme sous-jacente. Par exemple, sous Windows XX, le terminateur de fin de ligne est composé de deux caractères (Carriage Return + Line Feed : CRLF : \r\n), sous Unix, un seul caractère fini une ligne (Line Feed : LF : \n).

Lorsque le mode UNIX_LINES est activé, alors seul les terminateurs de ligne Unix (\n) sont reconnus.

Le mode MULTILINE autorise l'emploi des méta-caractères de délimitation de lignes ^ (début de ligne) et $ (fin de ligne) sur l'ensemble du texte cible. Ainsi, toutes les lignes de ce texte pourront être précisément délimitées. Dans le cas contraire, sera trouvé par une expression régulière employant ces méta-caractères, le texte entier si le mode DOTALL est activé, sinon la recherche échoue.

Cible : 
Le monde quantique est totalement cahotique.
Il est ainsi quasiment impossible de prévoir un 
comportement.
Le monde régit par la gravité, est quant à lui,
stable et partant totalement prévisible.
Ainsi, comment trouver le lien entre ces deux mondes ?
La théorie du tout pourrait répondre à cette question...

//Mode MULTILINE activé
Expression régulière : ^.*$ 
Résultat :
debut=0, fin=44
groupe(0) = Le monde quantique est totalement cahotique.
debut=46, fin=94
groupe(0) = Il est ainsi quasiment impossible de prévoir un 
debut=96, fin=109
groupe(0) = comportement.
debut=111, fin=158
groupe(0) = Le monde régit par la gravité, est quant à lui,
debut=160, fin=200
groupe(0) = stable et partant totalement prévisible.
debut=202, fin=256
groupe(0) = Ainsi, comment trouver le lien entre ces deux mondes ?
debut=258, fin=314
groupe(0) = La théorie du tout pourrait répondre à cette question...

//Mode MULTILINE non activé
Expression régulière : ^.*$ 
Résultat :
aucun

//Mode MULTILINE non activé et mode DOTALL activé
Expression régulière : ^.*$ 
Résultat :
debut=0, fin=314
groupe(0) = Le monde quantique ... cette question...

Le mode DOTALL détermine si le point correspond à n'importe quel caractère, y compris les terminateurs de lignes. Dans le cas contraire, le point ne pourra remplacer un saut de ligne, un retour charriot, comme on le constate dans le second exemple (Mode MULTILINE non activé) et la mise en correspondance échouera.

24.4.2 / Les classes de caractères

Les expressions régulières peuvent nécessiter l'emploi d'intervalles de caractères, appelés classes de caractères, afin de limiter la recherche à un nombre de caractères prédéfinis.

//Recherche de tous les mots contenant les lettres de a à z
Expression régulière : \b[a-z]*\b
Cible :
Une femme nue ou dans une tenu légère dans 
une peinture de maître est toujours sensuelle.

Les occurrences recherchées par un modèle d'expression régulière sont en général composées d'une combinaison de plusieurs caractères distincts connus. Ainsi, il devient possible d'inclure ou d'exclure des intervalles de caractères pour une recherche d'occurrences correspondant à l'expression régulière.

//Recherche d'une combinaison de trois caractères
Expression régulière : [enu]{3} ou [a-z&&[enu]]{3}
Cible :
Une femme nue ou dans une tenu légère dans 
une peinture de maître est toujours sensuelle.

//Recherche de mots ne contenant pas le caractère e
Expression régulière : \b[^e]*\b ou \b[a-zA-Z&&[^e]]*\b
Cible :
Une femme nue ou dans une tenu légère dans 
une peinture de maître est toujours sensuelle.
SymbolesDescription
[abc]Intervalle de caractères incluant a, b, ou c.
[^abc]Intervalle de caractères excluant a, b, ou c.
[a-zA-Z]Intervalle de caractères incluant toutes les lettres de a à z majuscules ou minuscules.
[a-d[m-p]]Intervalle de caractères incluant les lettres de 'a' à 'd' ou de 'm' à 'p' (union).
[a-z&&[def]]Intervalle de caractères incluant les caractères 'd', 'e', ou 'f' (intersection)
[a-z&&[^bc]]Intervalle de caractères incluant les caractères de 'a' à 'z' en excluant les lettres 'b' ou 'c' (soustraction de caractères).
[a-z&&[^m-p]]Intervalle de caractères incluant les caractères de 'a' à 'z' en excluant l'intervalle de lettres de 'm' à 'p' (soustraction d'intervalles).

24.4.3 / Les classes de caractères prédéfinies

Les classes de caracères prédéfinies expriment des intervalles de caractères génériques.

Il existe des classes spécifiques pour :

//Recherche de mots contenant les caractères alphanumériques
Expression régulière : \b\w+\b
Cible :
Les conférences de Rio (1992) et Kyoto (1997) sur le réchauffement 
climatique de la planète ne semblent pas perturber l'Etat d'Amérique 
du Nord gouverné par le puissant lobby industriel américain.

//Recherche des nombres
Expression régulière : \b\d+\b
Cible :
Les conférences de Rio (1992) et Kyoto (1997) sur le réchauffement 
climatique de la planète ne semblent pas perturber l'Etat d'Amérique 
du Nord gouverné par le puissant lobby industriel américain.

//Recherche des lignes se terminant par deux espaces blancs (ex.: \r\n)
Expression régulière : .*\s{2}
Cible :
Les conférences de Rio (1992) et Kyoto (1997) sur le réchauffement 
climatique de la planète ne semblent pas perturber l'Etat d'Amérique 
du Nord gouverné par le puissant lobby industriel américain.

Chacune des classes précitées possède son inverse :

//Recherche des caractères non-alphanumériques
Expression régulière : \W+
Cible :
Les conférences de Rio (1992) et Kyoto (1997) sur le réchauffement 
climatique de la planète ne semblent pas perturber l'Etat d'Amérique 
du Nord gouverné par le puissant lobby industriel américain.
SymbolesDescription
.Remplacement de tous les caractères, y compris les teminateurs de lignes selon l'option du modèle courant.
\dUn chiffre de 0 à 9.
\DTout sauf un chiffre 0 à 9.
\sUn espace blanc (espace, tabulation, fin de lignes, retour charriot, etc.).
\STout sauf un espace blanc.
\wUne lettre de 'a' à 'z' ou 'A' à 'Z', ou un chiffre de 0 à 9, ou un caractère de soulignement (underscore : _).
\WTout sauf une lettre, un chiffre ou un caractère de soulignement.

24.4.4 / Les classes POSIX

Les classes de caractères pour le standard POSIX (Portable Operating System Interface) sont également des classes de caractères prédéfinies. Mais ces classes fournissent une plus grande variété de combinaisons.

//Recherche des mots commençant par une majuscule
Expression régulière : \b\p{Upper}\p{Lower}*\b
Cible :
La conférence de Kyoto (1997) a abouti à l’adoption d’un protocole 
le 10 décembre 1997 qui prévoit de commencer à réduire les émissions d
e gaz à effet de serre.
Le taux moyen de réduction consenti pour les principaux pays industrialisés 
est de -5,2% des émissions par rapport à leur niveau de 1990.
Les objectifs quantifiés de réduction d’émissions sont beaucoup plus élevés 
pour certain pays, tels que le Japon (-6%) et les Etats-Unis (-7%).

//Recherche des mots et nombres
Expression régulière : \b\p{Alnum}*\b
Cible :
La conférence de Kyoto a abouti à l'adoption dun protocole 
le 10 décembre 1997 qui prévoit de commencer à réduire les émissions 
de gaz à effet de serre. 
Le taux moyen de réduction consenti pour les principaux pays industrialisés 
est de -5,2% des émissions par rapport à leur niveau de 1990.
Les objectifs quantifiés de réduction d’émissions sont beaucoup plus élevés 
pour certain pays, tels que le Japon (-6%) et les Etats-Unis (-7%).

//Recherche de signes de ponctuation
Expression régulière : \p{Punct}
Cible :
La conférence de Kyoto a abouti à l'adoption d'un protocole 
le 10 décembre 1997 qui prévoit de commencer à réduire les émissions 
de gaz à effet de serre.
Le taux moyen de réduction consenti pour les principaux pays industrialisés 
est de -5,2% des émissions par rapport à leur niveau de 1990.
Les objectifs quantifiés de réduction d’émissions sont beaucoup plus élevés 
pour certain pays, tels que le Japon (-6%) et les Etats-Unis (-7%).
SymbolesDescription
\p{Lower}Les caractères alpabétiques minuscules ([a-z]).
\p{Upper}Les caractères alphabétiques majuscules ([A-Z]).
\p{ASCII}Tous les caractères US-ASCII ([\x00-\x7F])
\p{Alpha}Un caractère alphabétique ([\p{Lower}\p{Upper}]).
\p{Digit}Un chiffre décimal ([0-9]).
\p{Alnum}Un caractère alphanumérique ([\p{Alpha}\p{Digit}]).
\p{Punct}Un caractère de ponctuation (!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~).
\p{Graph}Un caractère visible ([\p{Alnum}\p{Punct}]).
\p{Print}Un caractère imprimable ([\p{Graph}]).
\p{Blank}Un espace ou une tabulation ([ \t]).
\p{Cntrl}Un caractère de contrôle ([\x00-\x1F\x7F]).
\p{XDigit}Un chiffre hexadécimal ([0-9a-fA-F]).
\p{Space}Un caractère d'espace blanc ([ \t\n\x0B\f\r]).

24.4.5 / Les classes Unicode

Les classes pour le jeux de caractères Unicode prennent en compte l'ensemble des caractères US-ASCII, mais aussi les caractères grecques, arabes, chinois, les caractères accentués majuscules et minuscules, les symboles monétaires, etc..

//Recherche de mots grecs
Expression régulière : \b\p{InGreek}+\b
Cible :
καλωσορίζω (bienvenue) τους (les) επισκέπτες (visiteurs)

//Recherche d'une majuscule
Expression régulière : \p{Lu}
Cible :
Être ou ne pas être, telle est la question !
William Shakespeare.

//Recherche d'un symbole monétaire
Expression régulière : \p{Sc}
Cible :
Les deniers cours monétaires :
1  = 1.31 $ = 137.87 ¥
SymbolesDescription
\p{propriété}Un caractère correspondant à une propriété.
\p{IsCatégorie} ou \p{Catégorie}Un caractère d'une catégorie Java définie dans la classe java.lang.Character.
\p{L}Une lettre Unicode.
\P{L}Tout sauf une lettre Unicode.
\p{Lu}Une lettre majuscule.
\P{Sc}Tout sauf une lettre majuscule.
\p{Ll}Une lettre minuscule.
\P{Sc}Tout sauf ue lettre minuscule.
\p{Sc}Un symbole monétaire.
\P{Sc}Tout sauf un symbole monétaire.
\p{InLangue}Un caractère d'une langue indiquée définie dans la classe java.lang.Character.UnicodeBlock.
\P{InLangue}Tout sauf un caractère d'une langue indiquée.
\p{InGreek}Un caractère grecque.
\P{InGreek}Tout sauf un caractère grecque.
\p{InCyrillic}Un caractère cyrillique.
\P{InCyrillic}Tout sauf un caractère cyrillique.
\p{InArabic}Un caractère arabe.
\P{InArabic}Tout sauf un caractère arabe.
[\p{L}&&[^\p{Lu}]]Toute lettre sauf une lettre majuscule.

24.4.6 / Les limites d'occurrences

Les délimiteurs précisent les limites des occurrences correspondant à une expression régulière ou à l'une de ses parties.

De cette manière, il est possible de délimiter une ligne (^Ligne...$)ou un mot (\bmot\b).

//Délimitation d'une entrée
Expression régulière : \A.*\Z
Cible :
Du sublime au ridicule il n'y a qu'un pas. (Napoléon 1er)

//Délimitation d'une entrée
Expression régulière : \b.*\b
Cible :
Du sublime au ridicule il n'y a qu'un pas. (Napoléon 1er)

//Délimitation d'une entrée
Expression régulière : \bN\P{L}+\b
Cible :
Du sublime au ridicule il n'y a qu'un pas. (Napoléon 1er)

//Recherche du premier mot d'une ligne
Expression régulière : ^\w*\b
Cible :
Du sublime au ridicule il n'y a qu'un pas. (Napoléon 1er)

//Recherche d'une sous-chaîne entre parenthèses et en fin de ligne
Expression régulière : \([\p{L}[0-9 ]]*\)$
Cible :
Du sublime au ridicule il n'y a qu'un pas. (Napoléon 1er)

//Recherche d'une sous-chaîne entre parenthèses et en fin de ligne
Expression régulière : ^<tr>.*</tr>$
Cible :
<html>
<body>
<table>
<tr><td>A</td></tr>
<tr><td>B</td></tr>
<tr><td>C</td></tr>
<tr><td>D</td></tr>
<tr><td>E</td></tr>
<tr><td>F</td></tr>
</table>
</body>
SymbolesDescription
^Le début d'une ligne.
$La fin d'une ligne.
\bLa limite d'un mot.
\BTout sauf la limite d'un mot.
\ALe début d'une entrée.
\GLa fin de la précédente recherche.
\ZLa fin de l'entrée mais pour le terminateur final éventuel.
\zLa fin de l'entrée.

24.4.7 / Les quantificateurs

Les quantificateurs déterminent le nombre de répétitions tolérées d'un caractère quelconque ou d'une expression régulière complète ou partielle.

Le nombre de répétitions est indiqué par un symbole (?, *, +) ou par un intervalle (ex.: {1, 3}).

//Recherche des mots se terminant par la lettre e
Expression régulière : \b\p{L}*e\b
Cible :
Elle est belle Isabelle lorsqu'elle se lève.

//Recherche deux caractères l consécutifs
Expression régulière : l{2}
Cible :
Elle est belle Isabelle lorsqu'elle se lève.

//Recherche d'un ou plusieurs caractères l consécutifs
Expression régulière : l+
Cible :
Elle est belle Isabelle lorsqu'elle se lève.

//Recherche d'un caractère e suivi éventuellement par un l
Expression régulière : el?
Cible :
Elle est belle Isabelle lorsqu'elle se lève.

//Recherche d'un caractère e suivi par 
//un (minimum) ou deux (maximum) l
Expression régulière : el{1, 2}
Cible :
Elle est belle Isabelle lorsqu'elle se lève.

//Recherche d'un caractère e suivi par un (minimum) ou plusieurs l
Expression régulière : el{1,}
Cible :
Elle est belle Isabelle lorsqu'elle se lève.

Des quantifiers gloutons consomment la chaîne de caractères cible entière lors d'une première tentative de recherche. Puis si cette première tentative échoue, alors à partir de la fin de la chaîne cible, ils reculent d'un caractère, essayent à nouveau une mise en correspondance, puis répêtent ce processus jusqu'à que la recherche réussise ou qu'il n'y ait plus de caractères.

Cible :
xxxabcxxxdefxxxabcxxxdefxxxabcxxxdef
//Recherche d'un caractère e suivi par un (minimum) ou plusieurs l
Expression régulière : .?def
Résultat :
debut=8, fin=12
groupe(0) = xdef
debut=20, fin=24
groupe(0) = xdef
debut=32, fin=36
groupe(0) = xdef

Expression régulière : .*def
Résultat :
debut=0, fin=36
groupe(0) = xxxabcxxxdefxxxabcxxxdefxxxabcxxxdef

Expression régulière : .+def
Résultat :
debut=0, fin=36
groupe(0) = xxxabcxxxdefxxxabcxxxdefxxxabcxxxdef
SymbolesDescription
X?Aucun ou un caractère X.
X*Zéro à plusieurs caractère X.
X+Un à plusieurs caractère X.
X{n}Exactement n caractères X.
X{n,}Au moins n caractères X.
X{n,m}Au moins n et au plus m caractères X.

24.4.8 / Les quantificateurs hésitants

Les quantificateurs hésitants (reluctant) fonctionnent différemment des quantificateurs gloutons (greedy). En effet, ils démarrent une recherche au début de la chaîne de caractères cible, consomment un caractère à la fois pour une mise en correspondance. La dernière chose qu'ils essayent est une mise en correspondance sur le chaîne de caractères cible entière.

Cible :
xxxabcxxxdefxxxabcxxxdefxxxabcxxxdef
//Recherche d'un caractère e suivi par un (minimum) ou plusieurs l
Expression régulière : .??def
Résultat :
debut=8, fin=12
groupe(0) = xdef
debut=20, fin=24
groupe(0) = xdef
debut=32, fin=36
groupe(0) = xdef

Expression régulière : .*?def
Résultat :
debut=0, fin=12
groupe(0) = xxxabcxxxdef
debut=12, fin=24
groupe(0) = xxxabcxxxdef
debut=24, fin=36
groupe(0) = xxxabcxxxdef

Expression régulière : .+?def
Résultat :
debut=0, fin=12
groupe(0) = xxxabcxxxdef
debut=12, fin=24
groupe(0) = xxxabcxxxdef
debut=24, fin=36
groupe(0) = xxxabcxxxdef

Expression régulière : def.??
Résultat :
debut=9, fin=12
groupe(0) = def
debut=21, fin=24
groupe(0) = def
debut=33, fin=36
groupe(0) = def
SymbolesDescription
X??Aucun ou un caractère X.
X*?Zéro à plusieurs caractère X.
X+?Un à plusieurs caractère X.
X{n}?Exactement n caractères X.
X{n,}?Au moins n caractères X.
X{n,m}?Au moins n et au plus m caractères X.

24.4.9 / Les quantificateurs possessif

Les quantificateurs possessifs consomment toujours la chaîne de caractères cible entière, en essayant une seule fois une mise en correspondance. A la différence des quantificateurs gloutons (greedy), ceux-ci ne reculent jamais, même si cela permettrait de réussir une recherche.

Cible :
xxxabcxxxdefxxxabcxxxdefxxxabcxxxdef

Expression régulière : .?+def
Résultat :
aucun

Expression régulière : .*+def
Résultat :
aucun

Expression régulière : .++def
Résultat :
aucun
SymbolesDescription
X?+Aucun ou un caractère X.
X*+Zéro à plusieurs caractère X.
X++Un à plusieurs caractère X.
X{n}+Exactement n caractères X.
X{n,}+Au moins n caractères X.
X{n,m}+Au moins n et au plus m caractères X.

24.4.10 / Lres opérateurs logiques

Les opérateurs logiques permettent de fournir des association (ex.: ab), alternatives (ex.: a|b) ainsi que des groupements ((a|b)) au sein d'un expression régulière.

#Association d'une lettre majuscule suivi de lettres minuscules
Expression régulière : \b\p{Lu}\p{L}*\b
Résultat :
La vitesse de la lumière ne serait pas une constante, 
selon le physicien João Magueijo.
Si cela s'avérait vrai, la théorie de la relativité 
d'Albert Einstein pourrait être remise en question.
Cette théorie surprenante semble étayer par les 
observations des quasars par John Webb, mais la
communauté scientifique réprouve vigoureusement
les allégations de ces deux chercheurs.

#Alternatives entre des noms de balises b ou i
Expression régulière : <(b|i)>.*</(b|i)>
Résultat :
<html>
<body>
<p>La vitesse de la lumière ne serait pas une constante, 
selon le physicien <b>João Magueijo</b>.
Si cela s'avérait vrai, la <i>théorie de la relativité</i> 
d'<b>Albert Einstein</b> pourrait être remise en question.
Cette théorie surprenante semble étayer par les 
observations des <i>quasars</i> par <b>John Webb</b>, mais la
communauté scientifique réprouve vigoureusement
les allégations de ces deux chercheurs.</p>
</body>
</html>

#Alternatives entre des balises <b>...</b> ou <i>...</i>
Expression régulière : (<b>.*</b>|<i>.*</i>)
Résultat :
<html>
<body>
<p>La vitesse de la lumière ne serait pas une constante, 
selon le physicien <b>João Magueijo</b>.
Si cela s'avérait vrai, la <i>théorie de la relativité</i> 
d'<b>Albert Einstein</b> pourrait être remise en question.
Cette théorie surprenante semble étayer par les 
observations des <i>quasars</i> par <b>John Webb</b>, mais la
communauté scientifique réprouve vigoureusement
les allégations de ces deux chercheurs.</p>
</body>
</html>

L'entourage d'une expression régulière ou d'une ou plusieurs parties de celle-ci, entraîne la création de groupes de captures durant la mise en correspondance d'un modèle.

#Groupes de capture
Expression régulière : (\{.*(\[.*(\()))
Cible : {Groupe 1[Groupe 2(Groupe 3)](Groupe 4)}
Résultat :
dénut=0, fin=30
Groupe(0) = {Groupe 1[Groupe 2(Groupe 3)](
Groupe(1) = {Groupe 1[Groupe 2(Groupe 3)](
Groupe(2) = [Groupe 2(Groupe 3)](
Groupe(3) = (
SymbolesDescription
XYX suivi par Y (ET).
X|YX ou Y (OU).
(X)Groupe d'un caractère X.

24.4.11 / Les références arrières

Les groupes de capture conservent des occurrences résultant d'une recherche, pour un rappel ultérieur durant le processus de mise en correspondance.

Les groupes de capture sont des séquences de caractères entourées de parenthèses (( )). Tous les caractères dans de tels groupes sont traités comme des unités uniques pendant la mise en correspondance du modèle.

#Groupes de capture
Expression régulière : (\{.*(\[.*(\()))
Cible : {Groupe 1[Groupe 2(Groupe 3)](Groupe 4)}
Résultat :
dénut=0, fin=30
Groupe(0) = {Groupe 1[Groupe 2(Groupe 3)](
Groupe(1) = {Groupe 1[Groupe 2(Groupe 3)](
Groupe(2) = [Groupe 2(Groupe 3)](
Groupe(3) = (

Il est possible de faire une référence arrière à un groupe de capture en indiquant le numéro du groupe devant être rappelé.

#Rappel du groupe
Cible : 200510
Expression régulière : (\d\d)\1
Résultat :
aucun

Cible : 202020
Expression régulière : (\d\d)\1
Résultat :
debut=0, fin=4
groupe(0) = 2020
groupe(1) = 20

Expression régulière : (\d\d)
Résultat :
debut=0, fin=2
groupe(0) = 20
groupe(1) = 20

debut=2, fin=4
groupe(0) = 20
groupe(1) = 20

debut=4, fin=6
groupe(0) = 20
groupe(1) = 20

#Rappel du groupe imbriqué
Cible : Le célèbre physicien Albert Einstein Einstein
Expression régulière : (Albert( Einstein)\2)
Résultat :
denut=21, fin=46
Groupe(0) = Albert Einstein Einstein
Groupe(1) = Albert Einstein Einstein
Groupe(2) =  Einstein

Expression régulière : (Albert( Einstein))
Résultat :
denut=21, fin=36
Groupe(0) = Albert Einstein
Groupe(1) = Albert Einstein
Groupe(2) =  Einstein
SymbolesDescription
\nLe nième groupe de capture.

24.4.12 / Les échappements

Un certain nombre de méta-caractères ne peuvent être utilisés tels quels dans des expressions régulières. C'est le cas des caractères suivants : ( [ { \ ^ $ | ) ? * + ..

L'utilisation de ces méta-caracères dans une expression régulières nécessite de les échapper, c'est-à-dire de faire précéder le caractère du signe anti-slash '\', ou d'encadrer une sous-expression des symboles \Q (début) et \E (fin).

#Echappement des accolades, crochets et parenthèses ouvrants
Expression régulière : \{\p{L}|\[\p{L}|\(\p{L}
Cible :
{Groupe 1[Groupe 2(Groupe 3)](Groupe 4)}

#Echappement des accolades, crochets et parenthèses fermants
Expression régulière : .\)|]|}
Cible :
{Groupe 1[Groupe 2(Groupe 3)](Groupe 4)}

#Echappement en entourant des symboles \Q...\E
Expression régulière : \Q\p{\E.*}
Cible :
<table align="center" border="0">
<tr><th class="entete">Symboles</th>
<tr><th>\p{L}</th>
<tr><th>\p{Lu}</th>
<tr><th>\p{Ll}</th>
<tr><th>\p{Sc}</th>
<tr><th>\p{InGreek}</th>
<tr><th>\P{InGreek}</th>
<tr><th>[\p{L}&&[^\p{Lu}]]</th>
</table>
SymbolesDescription
\Echappement d'un méta-caractère (ex.: \.).
\QEchappement de tous les caractères jusqu'à \E.
\EFin d'échappement des caractères ayant commencé à \Q.

24.4.13 / Les constructions spéciales

Les constructions spéciales fournissent des moyens de mise en correspondance conditionnelle (lookahead et lookbehind ou plus généralement zero-width assertions).

Littéralement, grâce aux constructions lookahead et lookbehind, il est possible de vérifier devant et derrière un critère qui permettra de trouver une occurrence qui correspond à une expression régulière.

#Recherche après le caractère :
Expression régulière : (?<=:)([\w\-\.]+@\w+\.[a-z]{2,4}|.+)
Cible :
From: expediteur@email.com
To: destinataire@email.com
Subject: Bonjour...

#Recherche incluant le caractère :
Expression régulière : (?=:)([\w\-\.]+@\w+\.[a-z]{2,4}|.+)
Cible :
From: expediteur@email.com
To: destinataire@email.com
Subject: Bonjour...

#Recherche d'une occurrence dont le début n'est pas un caractère :
Expression régulière : (?!:)([\w\-\.]+@\w+\.[a-z]{2,4}|.+)
Cible :
From: expediteur@email.com
To: destinataire@email.com
Subject: Bonjour...

#Recherche devant le caractère : en l'excluant
Expression régulière : ^.+(?=:)
Cible :
From: expediteur@email.com
To: destinataire@email.com
Subject: Bonjour...

#Recherche devant le caractère : en l'incluant
Expression régulière : ^.+(?<=:)
Cible :
From: expediteur@email.com
To: destinataire@email.com
Subject: Bonjour...

#Recherche devant le caractère : en l'incluant
Expression régulière : ^.+(?>:)
Cible :
From: expediteur@email.com
To: destinataire@email.com
Subject: Bonjour...

#Recherche d'une occurrence dont le début n'est pas un caractère :
Expression régulière : (?<!:)([\w\-\.]+@\w+\.[a-z]{2,4}|.+)
Cible :
From: expediteur@email.com
To: destinataire@email.com
Subject: Bonjour...

#Recherche d'une occurrence dont la fin n'est pas 'S' ou 'ES'
et peut être E mais en l'excluant :
Expression régulière : SAINT(?=E?)(?!E?S) Cible : SAINT SAINTE SAINTS SAINTES #Recherche d'une occurrence dont la fin peut être E mais en
l'excluant. En son sein, il ne peut y avoir 'A' ou 'RA' et il peut inclure
un 'D' s'il existe :
Expression régulière : \bGR?(?!R?A)N?(?>D?)(?=E?) Cible : GRD GD GND GDE GRNDE GRAND GRANDE AGDE
SymbolesDescription
(?options)Expression ne devant pas être prise pour un groupe de capture exprimant des options d'expression régulière. Les options peuvvent être accolées ensemble (ex.: (?is)) ou des groupes d'options peuvent se succéder (ex.: (?i)(?s)).
(?:regexp)Expression ne devant pas être prise pour un groupe de capture.
(?idmsux-idmsux)Activation ou désactivation des options de recherche.
(?idmsux-idmsux:regexp)Activation ou désactivation des options pour l'expression ne devant pas être prise pour un groupe de capture.
(?=regexp)XRecherche d'une occurrence correspondant à l'expression X, qui doit suivre une occurrence correspondant à la construction spéciale. Cette dernière occurrence est incluse dans la première (zero-width positive lookahead).
X(?=regexp)Recherche d'une occurrence correspondant à l'expression X, qui doit précéder une occurrence correspondant à la construction spéciale. Cette dernière occurrence n'est pas incluse dans la première (zero-width positive lookahead).
(?!regexp)XRecherche d'une occurrence correspondant à l'expression X, qui ne doit pas suivre une occurrence correspondant à la construction spéciale (zero-width negative lookahead).
X(?!regexp)Recherche d'une occurrence correspondant à l'expression X, qui ne doit pas précéder une occurrence correspondant à la construction spéciale (zero-width negative lookahead).
(?<=regexp)XRecherche d'une occurrence correspondant à l'expression X, qui doit suivre une occurrence correspondant à la construction spéciale. Cette dernière occurrence n'est pas incluse dans la première (zero-width positive lookbehind).
X(?<=regexp)Recherche d'une occurrence correspondant à l'expression X, qui doit précéder une occurrence correspondant à la construction spéciale. Cette dernière occurrence est incluse dans la première (zero-width positive lookbehind).
(?<!regexp)XRecherche d'une occurrence correspondant à l'expression X, qui ne doit pas suivre une occurrence correspondant à la construction spéciale (zero-width negative lookbehind).
X(?<!regexp)Recherche d'une occurrence correspondant à l'expression X, qui ne doit pas suivre une occurrence correspondant à la construction spéciale (zero-width negative lookbehind).
X(?>regexp)Recherche d'une occurrence correspondant à l'expression X, qui doit précéder une occurrence correspondant à la construction spéciale. Cette dernière occurrence est incluse dans la première.
(?>regexp)XRecherche d'une occurrence correspondant à l'expression X, qui doit suivre une occurrence correspondant à la construction spéciale. Cette dernière occurrence est incluse dans la première.

25 / Les collections

Les collections permettent de stocker un nombre variable d'éléments de types identiques ou disparates. Le langage Java dispose de plusieurs classes destinées à créer ce genre d'artifice.

Les collections se démarquent des tableaux dans la mesure ou elles ont la capacité de s'étendre et de diminuer au gré, respectivement, des ajouts et des suppressions d'éléments. Cela permet d'éviter de consommer des ressources mémoires inutilement en initialisant un tableau à une taille prédéfinie en sachant que celui-ci risque de ne pas être totalement rempli lors des différentes étapes d'exécution d'un programme. Dans ce cas, une collection possèdera la faculté d'adapter sa taille à tous changements.

Les classes de gestion de collections se situent dans le paquetage java.util. Il en existe trois sortes :

Type Classe Description
Les listes Vector représente un tableau dynamique dont la taille peut varier.
Stack représente un mécanisme de pile de type LIFO.
ArrayList représente un tableau dynamique dont la taille peut varier.
LinkedList représente une liste liée utilisable comme une pile LIFO ou une file FIFO.
Les Maps Hashtable représente un tableau associatif dont les clés ne peuvent être nulles.
HashMap représente un tableau associatif dont une clé et des valeurs peuvent être nulles.
WeakHashMap représente un tableau associatif où si une clé n'est plus référencée, la paire clé-valeur est ignorée.
TreeMap représente un tableau associatif dont les clés sont classées en ordre croissant.
Ensembles HashSet représente un ensemble renforcée par un map.
TreeSet représente un ensemble renforcée par un TreeMap et classant les objets en ordre croissant.

25.1 / L'interface Collection

L'interface Collection représente la racine de la hiérarchie des collections Java.

Une collection représente un groupe d'objets, dénommé éléments pour les listes (List) ou les ensembles (Set).

Les collections peuvent permettre des éléments en double (ou doublons) à l'image des listes, ou parfois les interdisent telles que les objets Set triés.

L'interface Collection possèdent trois sous-interfaces List, Set et SortedSet.

Les implémentations de l'interface Collection sont AbstractCollection, AbstractList, AbstractSet, ArrayList, HashSet, LinkedHashSet, LinkedList, TreeSet et Vector.

Les méthodes
boolean add(Object o)
ajoute l'objet spécifié au sein de la collection courante.
boolean addAll(Collection c)
ajoute tous les éléments de la collection spécifiée au sein de l'objet Collection courant.
void clear()
supprime tous les éléments de la collection.
boolean contains(Object o)
retourne true si la collection contient l'objet spécifié.
boolean containsAll(Collection c)
retourne true si la collection courante contient tous les éléments de la collection spécifiée.
boolean equals(Object o)
teste l'égalité entre la collection et l'objet spécifié.
int hashCode()
retourne le code de hachage de la collection.
boolean isEmpty()
retourne true si la collection ne contient aucun élément.
Iterator iterator()
retourne un itérateur sur les éléments de la collection.
boolean remove(Object o)
supprime une seule instance de l'élément spécifié, s'il est présent au sein de la collection.
boolean removeAll(Collection c)
supprime tous les éléments de la collection spécifiée, s'ils sont présents dans la collection courante.
boolean retainAll(Collection c)
retient seulement les éléments de la collection courante qui sont contenus dans la collection spécifiée.
int size()
retourne le nombre d'éléments de la collection courante.
Object[] toArray()
retourne un tableau contenant tous les éléments de la collection courante.
Object[] toArray(Object[] a)
retourne un tableau contenant tous les éléments de la collection courante. Le type d'exécution du tableau retourné est celui du tableau spécifié.

25.2 / Les ensembles

Les ensembles (Set) sont des structures contenant des éléments non dupliqués dont l'accès reste très performant.

25.2.1 / L'interface Set

L'interface Set représente une collection ne contenant aucun éléments en double. Autrement dit, les ensembles ne doivent contenir que des éléments uniques.

La méthode equals() appliquée entre chaque objet d'une implémentation de l'interface Set, doit retourner obligatoirement false.

Les collections Set peuvent accepter des objets de n'importe quel type, ainsi qu'au plus un et un seul élement null.

Un cas particulier des ensembles consiste à ne pas permettre à un objet Set de contenir un élément de type Set.

Les implémentations de l'inteface Set peuvent ajouter des restrictions supplémentaires, telles qu'interdire les éléments null ou de certains types. Dans le cas ou des tentatives d'ajouter des éléments inéligibles seraient pratiquées, des exceptions contrôlées pourraient être levées, à l'image d'un NullPointerException ou d'un ClassCastException. En outre, les opérations sur un élément inéligible, telles qu'une vérification de présence, peuvent provoquer un comportement différent selon les implémentations comme la levée d'une exception ou un échec normal de l'opération (retour d'un booléen false).

L'interface Set est implémentée par les classes HashSet et AbstractSet. De même, elle est étendue par l'interface SortedSet qui permet un tri sur un ensemble. L'autre classe TreeSet n'implémente pas directement l'interface Set puisqu'elle s'appuie sur l'interface SortedSet.

Le parcours d'un ensemble s'effectue via un itérateur, lequel est obtenu par la méthode iterator().

public class CollectionSet {
    public static void main(String[] args) {
    String[] joursSemaine = {"lundi", 
                             "mardi", 
                             "mercredi", 
                             "jeudi", 
                             "vendredi", 
                             "samedi", 
                             "dimanche"};
    Set ensemble = new HashSet();
    for(int i = 0; i < joursSemaine.length; i++){
      ensemble.add(joursSemaine[i]);
    }
    System.out.println("Taille de l'ensemble : " + ensemble.size());
    Iterator valeurs = ensemble.iterator();

    while(valeurs.hasNext()){
      System.out.println(valeurs.next());
      valeurs.remove();
    }
    System.out.println("Taille de l'ensemble : " + ensemble.size());
  }
}
Les méthodes
boolean add(Object o)
ajoute l'élément spécifié au sein de l'objet Set, s'il n'est pas déjà présent.
boolean addAll(Collection c)
ajoute tous les éléments de la collection spécifiée au sein de l'objet Set, s'ils ne sont pas déjà présents.
void clear()
supprime tous les éléments de la collection Set.
boolean contains(Object o)
retourne true si l'élément spécifié est contenu dans l'objet Set.
boolean containsAll(Collection c)
retourne true si l'objet Set contient tous les éléments de la collection spécifiée.
boolean equals(Object o)
teste l'égalité entre la collection Set et l'objet spécifié.
int hashCode()
retourne le code de hachage pour l'objet Set.
boolean isEmpty()
retourne true si l'ensemble ne contient aucun élément.
Iterator iterator()
retourne un itérateur sur les éléments de l'ensemble.
boolean remove(Object o)
supprime l'élément spécifié de la collection Set, s'il est présent.
boolean removeAll(Collection c)
supprime tous les éléments contenus dans la collection spécifiée, de l'objet Set, s'ils y sont présents.
boolean retainAll(Collection c)
retient seulement les éléments de l'objet Set, qui ne sont pas contenus dans la collection spécifiée.
int size()
retourne le nombre d'éléments de l'ensemble.
Object[] toArray()
retourne un tableau contenant tous les éléments de l'objet Set.
Object[] toArray(Object[] a)
retourne un tableau contenant tous les éléments de l'objet Set, et le type d'exécution du tableau retourné est celui du tableau spécifié.
Exemple [voir]
import java.util.Set;
import java.util.TreeSet;
import java.util.Iterator;

public class CollectionSet {
  public static void main(String[] args) {
    String[] joursSemaine = {"lundi", "mardi", "mercredi", "jeudi", 
                             "vendredi", "samedi", "dimanche"};
    String[] daysOfWeek = {"sunday", "monday", "tuesday", "wednesday", 
                           "thursday", "friday", "saturday"};

    Set ensemble = creerEnsemble(joursSemaine);
    System.out.println("Taille de l'ensemble 1 : " 
                                           + ensemble.size());
    Set ensemble2 = creerEnsemble(daysOfWeek);
    System.out.println("Taille de l'ensemble 2 : " 
                                           + ensemble2.size());

    Set ensemble3 = new TreeSet();
    System.out.println("Code de hachage ensemble 1 : " 
                                           + ensemble.hashCode());
    ensemble3.add(ensemble);
    System.out.println("Code de hachage ensemble 2 : " 
                                           + ensemble2.hashCode());
    //ensemble3.add(ensemble2); //EXCEPTION ClassCastException
    System.out.println("Taille de l'ensemble 3 : " 
                                           + ensemble3.size());
    System.out.println("Code de hachage ensemble 3 : " 
                                           + ensemble3.hashCode());
    ensemble3.clear();
    System.out.println("Taille de l'ensemble 3 après clear() : " 
                                           + ensemble3.size());
    System.out.println("Code de hachage ensemble 3 : " 
                                           + ensemble3.hashCode());
    ensemble3.addAll(ensemble2);
    System.out.println("Taille de l'ensemble 3 après "
                              "addAll(collection) : "  + ensemble3.size());
    System.out.println("Code de hachage ensemble 3 : " 
                                           + ensemble3.hashCode());

    if(ensemble2.containsAll(ensemble3)){
      System.out.println("L'ensemble 2 contient les " 
                                             + "éléments de l'ensemble 3 !");
    }
    
    if(ensemble.contains(joursSemaine[2])){
      System.out.println("La valeur \"mercredi\" a été " 
                                             + "trouvée dans l'ensemble 1 puis "
                                             + "a été remplacée par \"wednesday\"!");
      ensemble.remove(joursSemaine[2]);
      ensemble.add(daysOfWeek[3]);
    }
    
    System.out.println("Sauvegarde des éléments de "
                                           + "la collection Set dans un tableau.");
    Object[] tableauTemp = ensemble.toArray(joursSemaine);

    afficherValeurs(ensemble);
    System.out.println("Taille de l'ensemble 1 : " + ensemble.size());
    afficherValeurs(ensemble2);
    System.out.println("Taille de l'ensemble 2 : " + ensemble2.size());
    afficherValeurs(ensemble3);
    System.out.println("Taille de l'ensemble 3 : " + ensemble3.size());
  }
  
  public static Set creerEnsemble(String[] tab){
    Set ens = new TreeSet();
    for(int i = 0; i < tab.length; i++){
      ens.add(tab[i]);
    }
    return ens;
  }
  public static void afficherValeurs(Set ens){
    int i = 1;
    Iterator valeurs = ens.iterator();
    while(valeurs.hasNext()){
      System.out.println(i++ + " entrée : " + valeurs.next());
      valeurs.remove();
    }
  }
}

25.2.2 / La classe HashSet

La classe HashSet est une implémentation de l'interface Set et une extension de la classe AbstractSet. De plus elle est renforcée par une table de hachage.

// Extrait de la classe hashMap
public class HashSet extends AbstractSet
                     implements Set, Cloneable, java.io.Serializable {
  //...
  public HashSet() {
    map = new HashMap();
  }
  //...
}

Un seul élément null est autorisé dans une instance de classe HashSet.

Les objets HashSet ne garantissent pas l'ordre des éléments durant une itération de l'ensemble, contrairement aux collections TreeSet. En effet, la fonction de hachage disperse les éléments au sein d'une collection Set.

Néanmoins, les performances des objets implémentant cette classe restent constantes pour les opérations de base, telles que l'ajout (add()), la suppression (remove()), la vérification de présence (contains()) et l'obtention de la taille(size()).

Il existe quatre constructeurs concourant à la création de collection HashSet. Le constructeur par défaut (HashSet()) initialise l'instance avec des valeurs par défaut, soit une capacité initiale et un facteur de charge par défaut égaux respectivement à 16 et à 0.75. Toutefois, il est possible d'indiquer soit la capacité initiale seule (HashSet(int ini)), soit la capacité initiale et le facteur de charge (HashSet(int ini, float fac)).

// par défaut
HashSet ensemble = new HashSet();
// capacité initiale
HashSet ensemble = new HashSet(100);
// capacité initiale et facteur de charge
HashSet ensemble = new HashSet(100, 0.70f);

La capacité initiale spécifie le nombre de cases allouées initialement à l'objet. Le facteur de charge permet de déterminer à quel moment l'ensemble doit être recalculé la capacité de la collection HashSet afin d'accueillir éventuellement plus d'éléments. Dans le cas d'une capacité initiale de 100 et un facteur de charge de 0.70, lorsque le taux de remplissage atteint 70 pourcents, la capacité est recalculée et l'objet est réorganisé en conséquence. Le facteur de charge influe sur les performances de l'objet HashSet, si bien qu'il est important de ne pas le paramétrer trop bas.

le dernier constructeur accepte comme argument une collection destinée à initialiser la nouvelle instance. Chaque élément de la collection spécifiée sera copiée au sein de l'objet HashSet créé.

Collection collection = new Vector();
collection.add(valeur);
HashSet ensemble = new HashSet(collection);

La classe HashSet comprend principalement des méthodes d'ajout (add() et addAll()), de suppression (remove(), removeAll() retainsAll() et clear()) et de vérification de présence (isEmpty(), contains() et containsAll()).

En outre, les méthodes toArray() héritées de l'interface Set permettent de renvoyer l'ensemble des éléments contenus dans la collection Set, dans un tableau.

HashSet ensemble = new HashSet();
// remplissage de la collection...
Object[] tableau = ensemble.toArray();
// le type d'exécution du tableau retourné 
// est celui du tableau spécifié.
String[] tabString; Object[] tableauString = ensemble.toArray(tabString);

La méthode iterator() retourne un itérateur sur les éléments de l'ensemble. Cet objet Iterator fournira le seul moyen de parcourir l'ensemble sous-jacent.

Iterator valeurs = ensemble.iterator();
while(valeurs.hasNext()){
  System.out.println("Elements : " + valeurs.next());
}

La classe HashSet étant renforcée par une table de hachage (HashMap), les méthodes equals() et hashCode() revêtent une importance capitale dans le fonctionnement d'un objet HashSet. Effectivement, chaque élément ajouté, recherché ou supprimé font appel à ces méthodes pour calculer le code de hachage des objets et les comparer entre eux. Par exemple, l'ajout d'une entrée entraîne la vérification de l'existence de la clé spécifiée. Dans un premier temps, un code de hachage est calculé spécifiquement par la méthode statique hash() appelant hashCode(). Puis des tests d'égalité entre les codes de hachage des clés existantes et celui de la clé fournie sont réalisés en parallèle avec un autre test d'égalité sur les objets à l'aide de la méthode statique eq() appelant equals().

// Extrait de la classe HashMap
public Object put(Object key, Object value) {
  Object k = maskNull(key);
  int hash = hash(k);
  int i = indexFor(hash, table.length);

  for (Entry e = table[i]; e != null; e = e.next) {
    if (e.hash == hash && eq(k, e.key)) {
      Object oldValue = e.value;
      e.value = value;
      e.recordAccess(this);
      return oldValue;
    }
  }

  modCount++;
  addEntry(hash, k, value, i);
  return null;
}

static int hash(Object x) {
  int h = x.hashCode();
  h += ~(h << 9);
  h ^=  (h >>> 14);
  h +=  (h << 4);
  h ^=  (h >>> 10);
  return h;
}

static boolean eq(Object x, Object y) {
  return x == y || x.equals(y);
}
Exemple [voir]
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class CollMap {
  public static void main(String[] args) {
    HashSet ensemble = new HashSet();

    TreeSet ens = new TreeSet();
    ens.add(new Video("Le jour le plus long", "Ken Annakin", 1962));
    ens.add(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    ens.add(new Video("Platoon", "Oliver Stone", 1986));
    ens.add(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    ens.add(new Video("La ligne rouge", "Terrence Malick", 1998));
    ens.add(new Video("The patriot", "Roland Emmerich", 2000));

    ensemble.addAll(ens);
    System.out.println("\nTaille de la collection 'ensemble' : " 
                                              + ensemble.size());

    afficherEntrees(ensemble);
    Set copie = copierEntrees(ensemble);
    Video obj = new Video("Platoon", "Oliver Stone", 1986);
    if(ensemble.contains(obj)){
      if(ensemble.remove(new Video("Platoon", "Oliver Stone", 1986))){
        System.out.println("\nL'objet a été supprimé :\n");
        afficherEntrees(ensemble);
      }
    }
    if(copie.containsAll(ensemble)){
      System.out.println("\nLes éléments de l'ensemble ensemble sont "
                                  + "tous contenus dans l'ensemble copié");
  
      System.out.println("\nLes éléments restant dans l'ensemble copié " 
                                    + copie.retainAll(ensemble));
      afficherEntrees(copie);
    }
  }
  public static void afficherEntrees(Set ensemble){
    if(!ensemble.isEmpty()){
      Iterator iterateur = ensemble.iterator();
      while(iterateur.hasNext()){
        Object o = iterateur.next();
        System.out.println(o.toString());
      }
    }
  }
  public static Set copierEntrees(Set ensemble){
    Set res = new HashSet();
    if(!ensemble.isEmpty()){
      Iterator iterateur = ensemble.iterator();
      while(iterateur.hasNext()){
        res.add(iterateur.next());
      }
    }
    return res;
  }
}

25.2.3 / La classe TreeSet

La classe TreeSet est une implémentation de l'interface SortedSet et une extension de la classe AbstractSet. De plus, elle est renforcée par une instance TreeMap.

// extrait de la classe TreeSet
public class TreeSet extends AbstractSet
        implements SortedSet, Cloneable, java.io.Serializable {
  //...
  public TreeSet() {
    this(new TreeMap());
  }
  //...
}

Cette classe garantit que l'ensemble sera trié selon un ordre croissant, conformément à l'ordre naturel des éléments ou à l'aide d'un comparateur fourni au moment de la création de l'objet TreeSet.

Les objets TreeSet assurent de très bonnes performances (log(n)) pour des opérations de base, telles que lors d'ajouts, de suppressions et de vérifications de présence.

Il existe quatre constructeurs permettant d'instancier la classe TreeSet. Le constructeur par défaut (TreeSet()) initialise l'objet en fondant son mode de tri sur l'ordre naturel des éléments. Toutefois, il est possible de spécifier un comparateur pour effectuer le tri des éléments de l'objet TreeSet.

// par défaut
TreeSet ensemble = new TreeSet();
// comparateur
Comparator comparateur = new Comparateur();
TreeSet ensemble = new TreeSet(comparateur);

// classe Comparateur implémentant l'interface Comparator
public class Comparateur implements Comparator {
  public int compare(Object obj1, Object obj2){
    return ((Comparable)obj2).compareTo(obj1);
  }
  public boolean equals(Object obj){
    return this.equals(obj);
  }
}

L'objet Comparator doit être créé par les soins du programmeur. Pour cela, il est nécessaire d'écrire une classe devant implémenter l'interface Comparator, laquelle possède deux méthodes compare() et equals() qui doivent être définies dans cette classe. Un objet TreeSet défini sans comparateur, utilise les méthodes compareTo() et equals() des objets contenus dans cet ensemble.

public interface Comparator {
  public int compare(Object o1, Object o2);
  public boolean equals(Object o);
}

Les deux autres constructeurs acceptent comme argument un objet Collection ou un objet SortedSet, destinée à initialiser la nouvelle instance. Chaque élément des collections spécifiées sera copié au sein de l'objet TreeSet. Dans le premier cas, la collection sera trié selon l'ordre naturel de ses éléments, dans le second, conformément à l'ordonnancement de l'objet SortedSet fourni.

// initialisation avec un objet Collection
Collection collection = new Vector();
collection.add(valeur);
//...
TreeSet ensemble = new TreeSet(collection);

// initialisation avec un objet SortedSet
SortedSet collection = new TreeSet(comparateur);
collection.add(valeur);
//...
TreeSet ensemble = new TreeSet(collection);

La classe TreeSet comprend principalement des méthodes d'ajout (add() et addAll()), de suppression (remove(), removeAll() retainsAll() et clear()) et de vérification de présence (isEmpty(), contains() et containsAll()).

La méthode iterator() retourne un itérateur sur les éléments de l'ensemble. Cet objet Iterator fournira le seul moyen de parcourir l'ensemble sous-jacent.

Iterator valeurs = ensemble.iterator();
while(valeurs.hasNext()){
  System.out.println("Elements : " + valeurs.next());
}

La classe TreeSet fournit deux méthodes first() et last(), chargées respectivement de récupérer dans un ensemble le premier élément, soit le plus petit, et le dernier élément, soit le plus grand. La comparaison entre les éléments est assurée par l'ordre naturel ou par le comparateur spécifié.

Object premier = ensemble.fisrt();

Object dernier = ensemble.last();

Le comparateur de la collection TreeSet est accessible via la méthode comparator().

Comparator comparateur = ensemble.comparator();

En outre, les méthodes toArray() héritées de l'interface Set permettent de renvoyer l'ensemble des éléments contenus dans la collection Set, dans un tableau.

TreeSet ensemble = new TreeSet();
// remplissage de la collection...
Object[] tableau = ensemble.toArray();
// le type d'exécution du tableau retourné 
// est celui du tableau spécifié.
String[] tabString; Object[] tableauString = ensemble.toArray(tabString);

La méthode headSet() retourne seulement les éléments de l'objet TreeSet, qui sont strictement inférieurs à l'objet passé en argument. Ce dernier est exclus de l'objet SortedSet retourné.

SortedSet partie = ensemble.headSet(valeur);
Exemple [voir]
import java.util.TreeSet;
import java.util.Comparator;

public class CollectionTreeSet {
  static final Comparator ORDRE_REALISATEUR = new CompRealisateur();
  static final Comparator ORDRE_ANNEE = new CompAnnee();
  public static void main(String[] args) {
    TreeSet ensemble = new TreeSet();
    ensemble.add(new Video("Le jour le plus long", "Ken Annakin", 1962));
    ensemble.add(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    ensemble.add(new Video("Platoon", "Oliver Stone", 1986));
    ensemble.add(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    ensemble.add(new Video("La ligne rouge", "Terrence Malick", 1998));
    ensemble.add(new Video("The patriot", "Roland Emmerich", 2000));
    System.out.println("Tri par titre :");
    afficherElements(ensemble); 
    TreeSet ensembleR = new TreeSet(ORDRE_REALISATEUR);
    ensembleR.addAll(ensemble);
    System.out.println("\nTri par réalisateur :");
    afficherElements(ensembleR);
    TreeSet ensembleA = new TreeSet(ORDRE_ANNEE);
    ensembleA.addAll(ensemble);
    System.out.println("\nTri par année :");
    afficherElements(ensembleA);
    SortedSet selection = 
                  ensemble.headSet(new Video("Platoon", "Oliver Stone", 1986));
    System.out.println(selection);
  }
  public static void afficherElements(TreeSet ens){
    Iterator valeurs = ens.iterator();
    while(valeurs.hasNext()){
      System.out.println(valeurs.next());
    }
  }
}

// Classe comparatrice CompRealisateur
import java.util.Comparator;

public class CompRealisateur implements Comparator {
  public int compare(Object o1, Object o2){
    if(!(o1 instanceof Video))
      throw new ClassCastException();
    return (((Video)o1).obtenirRealisateur()).compareTo(
                                        ((Video)o2).obtenirRealisateur());
  }
}

// Classe comparatrice CompAnnee
import java.util.Comparator;

public class CompAnnee implements Comparator {
  public int compare(Object o1, Object o2){
    if(!(o1 instanceof Video))
      throw new ClassCastException();
    return (new Integer(((Video)o1).obtenirAnnee())).compareTo(
                                        new Integer(((Video)o2).obtenirAnnee()));
  }
}

//Classe Video implémentant l'interface java.lang.Comparable
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

25.2.4 / L'interface SortedSet

L'interface SortedSet permet de créer un objet Set qui concourt à garantir que l'ordre des éléments sera accompli selon un tri croissant, en accord avec l'ordre naturel de ses éléments (voir l'interface Comparable), ou par un comparateur fourni au moment de la création de l'instance.

L'interface SortedSet étend l'interface Set qui elle même étend Collection. Elle est implémentée par une seule classe permettant de créer un ensemble trié, en l'occurrence, il s'agît de la collection TreeSet.

Plusieurs opérations supplémentaires sont proposées par cette interface afin de fournir des fonctionnalités appuyant l'ordonnancement d'une implémentation de SortedSet.

Tous les éléments insérés dans une collection SortedSet doivent implémenter l'interface java.lang.Comparable ou être accepté par l'objet Comparator spécifié. En outre, tous les éléments d'une telle collection doivent êre mutuellement comparable, dans le cas contraire une exception ClassCastException sera levée.

boolean res = elt1.compareTo(elt2);
// ou
boolean res = comparateur.compare(e1, e2));
Les méthodes
Comparator comparator()
retourne le comparateur associé à l'objet SortedSet, ou null s'il utilise un ordre naturel de ses éléments.
Object first()
retourne le premier des éléments de l'objet SortedSet.
SortedSet headSet(Object toElement)
retourne une partie de l'objet SortedSet, où les éléments sont strictement inférieures à l'objet toElement.
Object last()
retourne le dernier élément de la collection SortedSet.
SortedSet subSet(Object fromElement, Object toElement)
retourne une partie de l'objet SortedSet, où les éléments sont situés entre l'objet fromElement inclus et toElement exclus.
SortedSet tailSet(Object fromElement)
retourne une partie de l'objet SortedSet, où les éléments sont supérieurs ou égaux à l'objet fromElement.
Les méthodes héritées de l'interface java.util.Set
add, addAll, clear, contains, containsAll, equals, hashCode, isEmpty, iterator, remove, removeAll, retainAll, size, toArray, toArray

25.3 / Les listes

Les listes sont des structures capables de contenir des objets de différents types accessibles séquentiellement.

25.3.1 / La classe Vector

La classe Vector permet de créer une collection d'objets qui fonctionne de la même manière qu'un tableau, à l'exception que sa capacité peut varier en fonction des besoins.

Une allocation de mémoire dynamique est utilisée par les objets Vector, si bien qu'il est possible d'ajouter, de supprimer aisément leurs éléments, soit de faire varier leur taille dynamiquement.

De cette manière, un vecteur peut stocker un nombre quelconque d'objets de type Object, soit n'importe quel genre d'objets (String, Integer, URL, Date, etc.). Par contre, un vecteur n'accepte pas les valeurs de types primitifs qui doivent être converties en objet par l'intermédiaire de leur classe Wrappers (double -> Double, char -> Character, etc.).

Bien qu'il soit possible d'ajouter des objets instances de diverses classes, il n'est pas recommandé d'utiliser cette particularité puisque la gestion de la collection deviendrait vite problématique lors notamment, d'opérations de consultation et surtout d'exploitation.

Un vecteur comporte quatre constructeurs permettant d'initialiser les instances de cette classe.

Le premier permet de créer un vecteur initialement vide auquel il sera possible d'ajouter des éléments via une méthode spécifique.

Vector vecteur = new Vector();

Le second permet d'initialiser le vecteur à une certaine taille fournie en argument. Dans ce cas, la valeur contenu par chacun des éléments est null. Cependant, cette initialisation peut poser des problèmes de gestion d'espace mémoire, car un vecteur initialisé à n éléments voit sa capacité doublée lorsqu'un dépassement de sa capacité initiale intervient.

Vector vecteur = new Vector(50);

import java.util.*;
class Vecteur {
    public static void main(String args[]) {
        Vector vecteur = new Vector(10);
        // Affiche 10
        System.out.println ("Taille du vecteur : " + vecteur.capacity());
        for(int i = 0; i < vecteur.capacity(); i++)
            vecteur.add(i, new Integer(1900 + i));
        vecteur.add(vecteur.size(), new Integer(1900 + 11));
        // Affiche 20
        System.out.println ("Nombre d'éléments : " + vecteur.size());
        System.out.println ("Taille du vecteur : " + vecteur.capacity());
    }
}

Le troisième permet d'initialiser le vecteur à une certaine capacité le vecteur tout en veillant également à définir un pas d'incrémentation de sa capacité suite à un dépassement, palliant ainsi à la contrainte du constructeur précédent.

Vector vecteur = new Vector(100, 10);

Enfin, le quatrième permet de construire un vecteur à partir d'une collection passée en argument. Cette collection doit implémenter l'interface Collection, à l'image de ArrayList, HashSet, LinkedHashSet, LinkedList, TreeSet et même Vector.

Vector vecteur = new Vector(collection);

import java.util.*;
class Vecteur {
    public static void main(String args[]) {
       ArrayList collection = new ArrayList();
       collection.add("lundi");
       collection.add("mardi");
       collection.add("mercredi");
       collection.add("jeudi");
       collection.add("vendredi");
       collection.add("samedi");
       collection.add("dimanche");
       Vector vecteur = new Vector(collection);
       for(int i = 0; i < vecteur.size(); i++)
           System.out.println (vecteur.elementAt(i));
       //Affiche 7
       System.out.println ("Taille du vecteur : " + vecteur.size());
    }
}

Deux méthodes permettent respectivement de récupérer la capacité et la taille d'un vecteur. Evidemment, ces deux dernières fournissent des informations différentes. La capacité correspond à la longueur du tableau de données interne conservé dans le champ elementData d'un vecteur, alors que la taille reflète le nombre d'éléments effectif contenu dans le champ elementCount du vecteur.

int capacite = vecteur.capacity();

int taille = vecteur.size();

Par ailleurs, la classe Vector dispose d'autres méthodes destinées à modifier les caractéristiques d'un objet vecteur. Il s'agît de setSize(int taille) déterminant une nouvelle taille pour le vecteur, ensureCapacity(int capacite) augmentant la capacité du vecteur si nécessaire, ainsi que trimToSize() adaptant la capacité à la taille courante du vecteur.

vecteur.setSize(100);

vecteur.ensureCapacity(vecteur.capacity() + 50);

vecteur.trimToSize();

L'ajout d'objets dans un vecteur s'accompli par l'intermédiaire de plusieurs méthodes dont la plupart sont préfixées par add.

La suppression est prise en charge par plusieurs méthodes de la classe Vector commençant en général par remove. La suppression d'un ou plusieurs éléments entraîne une réorganisation du vecteur, c'est-à-dire que l'emplacement d'un élement effacé et immédiatement remplacé par l'élément suivant et cela en cascade jusqu'au dernier élément du vecteur.

public class Vecteur {
    public static void main(String[] args) {
        Vector vecteur = new Vector();
        vecteur.add("lundi");
        vecteur.add("mardi");
        vecteur.add("mercredi");
        vecteur.add("jeudi");
        vecteur.add("Vendredi");
        Vector v1 = new Vector(vecteur);
        Vector v2 = new Vector(vecteur);
        v1.removeAllElements();
        v2.clear();
        System.out.println ("La taille du vecteur (1, 2) : " 
                                          + v1.size() + ", " + v1.size() );
        System.out.println ("La capacité du vecteur (1, 2) : " 
                                          + v1.capacity() + ", " + v1.capacity());
    }
}

La consultation des éléments présents dans une collection Vector s'effectue par l'intermédiaire de diverses méthodes permettant de récupérer un élément précis ou plusieurs.

La méthode Object elementAt(int index) retourne l'élément trouvé à l'index spécifié.

String obj = (String)vecteur.elementAt(5);

La méthode Enumeration elements() retourne la liste de tous les éléments du vecteur dans un objet Enumeration.

import java.util.*;
public class Vecteur {
    public static void main(String[] args) {
        Vector vecteur = new Vector();
        vecteur.add("lundi");
        vecteur.add("mardi");
        vecteur.add("mercredi");
        vecteur.add("jeudi");
        vecteur.add("vendredi");
        for (Enumeration enum = vecteur.elements(); 
                             enum.hasMoreElements();)
            System.out.println(enum.nextElement());
    }
}

Les méthodes Object firstElement() et Object lastElement() retournent respectivement le premier et le dernier élément du vecteur.

//Retourne l'élément à l'index 0
Object objPremier = vecteur.firstElement();
//Retourne l'élément à l'index vecteur.size() - 1
Object objDernier = vecteur.lastElement();

Les méthodes Object[] toArray() et Object[] toArray(Object[] obj) retournent un tableau d'objets contenant les éléments du vecteur. La seconde méthode remplit le tableau passé en argument et retourne également un tableau de même contenu que le premier. Ainsi dans ce cas, il est inutile d'utiliser la valeur de retour de cette méthode.

import java.util.*;
public class Vecteur {
    public static void main(String[] args) {
        Vector vecteur = new Vector();
        vecteur.add("lundi");
        vecteur.add("mardi");
        vecteur.add("mercredi");
        vecteur.add("jeudi");
        vecteur.add("vendredi");
        Object[] tabCh2 = new Object[10];
        Object[] tabCh = vecteur.toArray(tabCh2);
        for(int i = 0; i < tabCh.length; i++)
            System.out.println (tabCh[i]);
        for(int i = 0; i < tabCh2.length; i++)
            System.out.println (tabCh2[i]);
    }    
}

La méthode subList(int debut, int fin) extrait une liste d'éléments du vecteur depuis un index de début et jusqu'à un index de fin exclus.

//Extraction des éléments de l'indice 1 à 4.
List liste = vecteur.subList(1, 5);
//Retourne le troisième élément
Object o = liste.get(3);

Les méthodes Iterator iterator(), ListIterator listIterator() et Listiterator listIterator(int debut) de la classe abstraite AbstractList, retournent respectivement des objets Iterator et ListIterator contenant tous les éléments du vecteur ou une partie depuis le début de ce dernier.

import java.util.*;
class Vecteur {
    public static void main(String args[]) {
        Vecto collection = new Vector();
        collection.add("lundi");
        collection.add("mardi");
        collection.add("mercredi");
        collection.add("jeudi");
        collection.add("vendredi");
        collection.add("samedi");
        collection.add("dimanche");
        Iterator i = collection.iterator();
        System.out.println ("  Iterator");
        while(i.hasNext())
            System.out.println (i.next().toString());
        ListIterator li = collection.listIterator();
        System.out.println ("  ListIterator");
        while(li.hasNext())
            System.out.println (li.next().toString());
        ListIterator li2 = collection.listIterator(3);
        System.out.println ("  ListIterator 2");
        while(li2.hasNext())
            System.out.println (li2.next().toString());
    }
}

Les moyens de contrôler la présence d'un ou plusieurs éléments sont assurés par plusieurs méthodes prenant comme argument l'objet recherché et parfois un index de démarrage de la recherche.

La méthode boolean contains(Object obj) vérifie si l'objet spécifié est contenu dans le vecteur.

boolean reussi = vecteur.contains("mercredi");

La méthode boolean containsAll(Collection col) teste si tous les éléments de la collection spécifiée sont contenus dans le vecteur.

import java.util.*;
class Vecteur {
    public static void main(String args[]) {
        Vector collection = new Vector();
        collection.add("lundi");
        collection.add("mardi");
        collection.add("mercredi");
        collection.add("jeudi");
        collection.add("vendredi");
        collection.add("samedi");
        collection.add("dimanche");
        ArrayList tableau = new ArrayList();
        tableau.add("mercredi");
        tableau.add("samedi");
        tableau.add("dimanche");
        if(collection.containsAll(tableau))
            System.out.println ("La liste est bien "
                                + "contenue dans le vecteur !");
    }
}

Les méthodes int indexOf(Object obj) et int lastIndexOf(Object obj) recherchent respectivement la première et la dernière occurrence d'un objet donné en testant l'égalité entre les objets à l'aide de la méthode equals().

//retourne -1 puisque non-trouvé
int position = vecteur.indexOf("Samedi");
//retourne 5
int position = vecteur.lastIndexof("samedi");

Les méthodes int indexOf(Object obj, int index) et int lastIndexOf(Object obj, int index) recherchent respectivement la première et la dernière occurrence d'un objet donné en démarrant à une certaine position et en s'appuyant sur la méthode equals().

import java.util.*;
class Vecteur {
  public static void main(String args[]) {
    Vector collection = new Vector();
    collection.add("Belgique");
    collection.add("Allemagne");
    collection.add("Espagne");
    collection.add("France");
    collection.add("France");
    collection.add("Italie");
    collection.add("France");
    int position = 0;
    while(position < collection.size() 
                                                && position > -1){
      //Si "France".equals("France"); 
      //alors position > -1
      position = collection.indexOf("France", 
                                                                    position);
      System.out.println ("France : " + position++);
    }
  }
}

Le parcours des éléments d'un objet Vector peuvent se faire en utilisant une boucle, ou en appliqant un itérateur sur les éléments de la liste.

for(int i = 0; i < liste.size(); i++){
    Object element = liste.get(i);
}
// itérateur
Iterator iterateur = liste.iterator();
while(iterateur.hasNext()){
    Object element = iterateur.next();
}
// itérateur de liste
ListIterator iterateur = liste.listIterator();
while(iterateur.hasNext()){
    Object element = iterateur.next();
}

L'objet ListIterator possède plusieurs méthodes supplémentaires efficaces dans la gestion des listes, par rapport à une implémentation de l'interface Iterator surtout utilisée dans le cadre des ensembles (Set). Ainsi, il est possible de parcourir une liste dans les deux directions possibles.

// parcours du bas vers le haut
ListIterator iterateur = liste.listIterator();
while(iterateur.hasPrevious()){
    Object element = iterateur.previous();
}
// parcours du haut vers le bas
ListIterator iterateur = liste.listIterator();
while(iterateur.hasNext()){
    Object element = iterateur.next();
}

D'autre part, les méthodes permettent de retourner l'index suivant (nextIndex()) ou précédent (previousIndex()), de supprimer (remove()), d'ajouter (add()) et de remplacer (set()) des éléments.

Tous les exemples de la page [voir]

25.3.2 / La collection Stack

La collection Stack constitue une pile du type dernier entré/premier sorti (LIFO : Last-In-First-Out).

La classe Stack est une extension de Vector.

Un seul constructeur permet d'instancier la classe Stack. Lorsque l'objet est créé, il ne possède aucun élément.

Stack pile = new Stack();

La classe Stack possède cinq méthodes supplémentaires permettant d'assurer un comportement d'une pile à tout objet créé à partir de cette classe.

Les opérations d'entrée et de sortie de la pile sont exécutées respectivement par les méthodes push() et pop().

// récupère l'objet au sommet de la pile
Object element = pile.pop();
// ajoute l'objet spécifié au sommet de la pile et le retourne
Object element = pile.push(objet);

Une exception EmptyStackException est levée si l'objet Stack est vide lors de ces opérations.

La méthode peek() est chargée de retourner l'objet, sans le supprimer, situé au sommet de la pile.

Object element = pile.peek();

La position d'un objet, par rapport au sommet de la liste, peut être récupérée par le biais de la méthode search(). Si l'objet recherché n'est pas contenu dans la liste, alors la méthode retourne -1.

int position = pile.search();

Enfin, la méthode empty() teste si la pile ne contient aucun élément.

boolean resultat = pile.empty();

Toutes les opérations possibles sur les vecteurs sont également réalisables sur les objets Stack. Néanmoins, son fonctionnement doit répondre aux exigences d'une pile.

Exemple [voir]
import java.util.Stack;

public class programme {
  private static Stack pile = new Stack();
  private static int inc = 1;
  public static void main(String[] args) {
    ajout(new Video("Voyage au bout de l'enfer", "Michael Cimino", 1978));
    ajout(new Video("Le jour le plus long", "Ken Annakin", 1962));
    ajout(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    ajout(new Video("Platoon", "Oliver Stone", 1986));
    ajout(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    ajout(new Video("La ligne rouge", "Terrence Malick", 1998));
    ajout(new Video("The patriot", "Roland Emmerich", 2000));
    ajout(new Video("Outrages", "Brian De Palma", 1990));
    ajout(new Video("Paris brûle-t-il ?", "René Clément", 1966));
    ajout(new Video("Tora ! Tora ! Tora !", "Richard Fleischer", 1970));
    ajout(new Video("Guerre et Paix", "King Vidor", 1956));
    ajout(new Video("Apocalypse now", "Francis Ford Coppola", 1979));
    System.out.println("Taille après ajouts = " + pile.size());
    inc = 1;
    while(!pile.empty())
      System.out.println("Extraction n°" + inc++ + "\t: " + pile.pop());
    System.out.println("Taille après extraction = " + pile.size());
  }
  public static void ajout(Video v){
    pile.push(v);
    System.out.println("Ajout n°" + inc++ + "\t: " + pile.peek());
  }
}

// Classe Video
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

25.3.3 / La classe LinkedList

La classe LinkedList permet de créer des listes chaînées pouvant être utilisées comme des piles ou des files d'attente.

La classe LinkedList implémente l'interface List et étend la classe abstraite AbstractSequentialList.

Les listes chaînées acceptent tous types d'objets, y compris la valeur null.

Il existe deux constructeurs dans la classe LinkedList, destinées à instancier et initialiser des listes chaînées. Le constructeur par défaut, permet de créer un objet LinkedList vide, tandis que l'autre initialise l'objet créé, en le remplissant avec les éléments contenus dans une collection passée en argument.

// par défaut
LinkedList liste = new LinkedList();
// initialisation avec les éléments d'une collection fournie
Collection collection = new Vector();
collection.add(objet);
// ...
LinkedList liste = new LinkedList(collection);

Les liste pouvant se comporter à l'instar des piles LIFO (Last In First Out) ou des files d'attente FIFO (First In First Out), la classe LinkedList met à disposition de nombreuses méthodes d'extraction ou d'ajout, conçues spécifiquement pour soit l'une et l'autre des listes.

Une pile (stack) peut se servir des méthodes add() et plus spécifiquement addLast(), afin d'ajouter un objet à la fin de la liste. L'extraction et la suppression du dernier élément se réalisent en faisant appel à la méthode removeLast(). De cette manière, le fonctionnement de la liste chaînée peut s'apparenter à celui d'une pile.

import java.util.LinkedList;

public class Pile {
  private LinkedList liste;

  public Pile() {
    liste = new LinkedList();
    }

  public boolean empty(){
    return liste.isEmpty();
  }
  
  public Object peek(){
    return liste.getFirst();
  }
  
  public Object pop() { 
    return liste.removeFirst(); 
  }
  
  public void push(Object o) {
    liste.addFirst(o);
  }

  public int search(Object o) {
    int i = liste.lastIndexOf(o);
    if (i >= 0)
      return liste.size() - i;
    return -1;
  }
  
  public int size(){
    return liste.size();
  }
}

Une file d'attente (queue) peut se servir de la méthode addFirst() pour ajouter un objet au sommet de la liste. L'extraction et la suppression des éléments s'effectuent par le truchement de la méthode removeFirst(). De cette manière, le fonctionnement de la liste chaînée peut s'apparenter à celui d'une file d'attente.

import java.util.LinkedList;

public class FileAttente {
  private LinkedList liste;

  public FileAttente() {
    this.liste = new LinkedList();
  }

  public boolean isEmpty() {
    return liste.isEmpty();
  }

  public void put(Object o) {
    liste.addFirst(o);
  }

  public Object get() {
    return liste.removeLast();
  }
  
  public int size(){
    return liste.size();
  }
}

Une double file d'attente (deque) se construit à partir des méthodes addFirst() et addLast() pour ajouter des éléments au sommet et à la fin de la liste. L'extraction et la suppression des éléments aux extrémités s'accomplissent par les méthodes removeFirst() et removeLast().

import java.util.LinkedList;
import java.util.NoSuchElementException;

public class FileDouble {
    private LinkedList liste;

    public FileDouble() {
      liste = new LinkedList();
    }

  public Object peekFirst(){
    if(liste.isEmpty())
      throw null;
    return liste.getFirst();
  }

  public Object peekLast(){
    if(liste.isEmpty())
      throw null; 
    return liste.getLast();
  }

  public void pushFirst(Object o){
    liste.addFirst(o);
  }

  public void pushLast(Object o){
    liste.addLast(o);
  }

  public Object popFirst(){
    if(liste.isEmpty())
      throw new NoSuchElementException(); 
    return liste.removeFirst();
  }

  public Object popLast(){
    if(liste.isEmpty())
      throw new NoSuchElementException(); 
    return liste.removeLast();
  }

  public int searchFirst(Object o){
    return liste.indexOf(o);
  }

  public int searchLast(Object o){
    int i = liste.lastIndexOf(o);
    if (i >= 0)
      return liste.size() - i;
    return -1;
  }

  public boolean isEmpty(){
    return liste.isEmpty();
  }
  
  public int size(){
    return liste.size();
  }
}

Toutes les autres opérations sur les listes chaînées sont identiques à celles courament pratiquées sur les collections List. Par exemple, l'itération des éléments d'une objet LinkedList peut s'effectuer par l'intermédiaire d'un itérateur (Iterator ou ListIterator), ou l'ajout et la suppression de groupes d'éléments à la fin ou à une position spécifiée de la liste, sont possibles grâce aux méthodes addAll() et removeAll().

Exemple [voir]
public class Programme {
  public static void main(String[] args) {
    Pile pile = new Pile();
    FileAttente file = new FileAttente();
    FileDouble filed = new FileDouble();

    pile.push(new Video("Voyage au bout de l'enfer", "Michael Cimino", 1978));
    pile.push(new Video("Le jour le plus long", "Ken Annakin", 1962));
    pile.push(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    pile.push(new Video("Platoon", "Oliver Stone", 1986));
    pile.push(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    pile.push(new Video("La ligne rouge", "Terrence Malick", 1998));
    pile.push(new Video("The patriot", "Roland Emmerich", 2000));
    pile.push(new Video("Outrages", "Brian De Palma", 1990));
    pile.push(new Video("Paris brûle-t-il ?", "René Clément", 1966));
    pile.push(new Video("Tora ! Tora ! Tora !", "Richard Fleischer", 1970));
    pile.push(new Video("Guerre et Paix", "King Vidor", 1956));
    pile.push(new Video("Apocalypse now", "Francis Ford Coppola", 1979));
    
    System.out.println("Pile (taille = " + pile.size() + ")");
    while(!pile.empty())
      System.out.println(pile.pop());
    System.out.println("Taille = " + pile.size() + "\n");
    
    file.put(new Video("Voyage au bout de l'enfer", "Michael Cimino", 1978));
    file.put(new Video("Le jour le plus long", "Ken Annakin", 1962));
    file.put(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    file.put(new Video("Platoon", "Oliver Stone", 1986));
    file.put(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    file.put(new Video("La ligne rouge", "Terrence Malick", 1998));
    file.put(new Video("The patriot", "Roland Emmerich", 2000));
    file.put(new Video("Outrages", "Brian De Palma", 1990));
    file.put(new Video("Paris brûle-t-il ?", "René Clément", 1966));
    file.put(new Video("Tora ! Tora ! Tora !", "Richard Fleischer", 1970));
    file.put(new Video("Guerre et Paix", "King Vidor", 1956));
    file.put(new Video("Apocalypse now", "Francis Ford Coppola", 1979));

    System.out.println("File d'attente (taille = " + file.size() + ")");
    while(!file.isEmpty())
      System.out.println(file.get());
    System.out.println("Taille = " + file.size() + "\n");

    filed.pushFirst(new Video("Voyage au bout de l'enfer", "Michael Cimino", 1978));
    filed.pushFirst(new Video("Le jour le plus long", "Ken Annakin", 1962));
    filed.pushFirst(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    filed.pushFirst(new Video("Platoon", "Oliver Stone", 1986));
    filed.pushFirst(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    filed.pushFirst(new Video("La ligne rouge", "Terrence Malick", 1998));
    filed.pushLast(new Video("The patriot", "Roland Emmerich", 2000));
    filed.pushLast(new Video("Outrages", "Brian De Palma", 1990));
    filed.pushLast(new Video("Paris brûle-t-il ?", "René Clément", 1966));
    filed.pushLast(new Video("Tora ! Tora ! Tora !", "Richard Fleischer", 1970));
    filed.pushLast(new Video("Guerre et Paix", "King Vidor", 1956));
    filed.pushFirst(new Video("Apocalypse now", "Francis Ford Coppola", 1979));
    
    System.out.println("File double (taille = " + filed.size() + ")");
    while(!filed.isEmpty())
      System.out.println("Premier : " + filed.popFirst()
                          + "\nDernier : " + filed.popLast());
    System.out.println("Taille = " + filed.size() + "\n");
        
  }
}

// Classe Video
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

25.3.4 / La classe ArrayList

La classe ArrayList permet de mettre en oeuvre un tableau dont la taille peut varier dynamiquement.

La classe ArrayList implémente l'interface List qui elle même étend Collection. De plus, elle est une extension de la classe abstraite AbstractList.

Les éléments d'un objet ArrayList peuvent être de n'importe quel type référence. En outre, la valeur null est également tolérée dans cette liste.

La création et l'initialisation d'un objet ArrayList dépend de trois constructeurs. Le premier permet d'instancier un objet vide avec une capacité initiale égale à 10. Un autre accepte comme argument une valeur destinée à définir cette capacité initiale. Le dernier initialise la liste avec les éléments d'une collection qui lui aura été spécifiée.

// par défaut : capacité initiale = 10
ArrayList liste = new ArrayList();
// initialisé avec une capacité initiale
ArrayList liste = new ArrayList(100);
// initialisé avec un collection
Collection collection = new LinkedList();
collection.add(objet);
// ...
ArrayList liste = new ArrayList(collection);

L'ajout d'éléments dans une collection ArrayList se réalise de différentes manières. Il est possible d'ajouter un objet ou tous les éléments d'une collection existante. Egalement, des méthodes offrent l'opportunité d'insérer des objets à partir d'un index précis.

// ajout d'un objet
liste.add(objet);
// ajout des éléments d'une collection
liste.addAll(collection);
// insertion d'un objet à l'index spécifié
liste.add(10, objet);
// insertion d'éléments d'une collection à l'index spécifié
liste.addAll(10, collection);

L'accès aux éléments d'une collection ArrayList s'effectue de la même manière que dans un tableau, c'est-à-dire par l'intermédiaire de leur index. Néanmoins, l'objet retourné sera du type Object, si bien qu'il faudra penser à le convertir dans la plupart des cas d'utilisation.

Object obj = liste.get(index);

Les méthodes contains() et containsAll() fournissent un moyen de vérification de présence d'un ou plusieurs éléments au sein d'une collection ArrayList.

// vérifie si la liste contient l'élément spécifié
boolean resultat = liste.contains(objet);
// vérifie si la liste contient tous 
//les éléments de la collection spécifiée
boolean resultat = liste.containsAll(collection);

Les méthodes indexOf() et lastIndexOf() permettent de rechercher l'élément fourni, respectivement à partir du début et de la fin de la liste.

// recherche la première occurence de l'objet spécifié
Object element = liste.indexOf(obj);
// recherche la dernière occurence de l'objet spécifié
Object element = liste.lastIndexOf(obj);

Les méthodes subList() et toArray() sont capables d'extraire une partie ou la totalité des éléments d'une liste, dans respectivement un objet List et un tableau.

// retourne une liste contenant les éléments 
au sein de l'intervalle spécifié
List sousListe = liste.subList(5, 15); // retourne tous les éléments de la liste dans un tableau Object[] tableau = liste.toArray(); // retourne tous les éléments de la liste dans un tableau
//et affecte le type d'exécution du tableau spécifié au tableau retourné
String[] tabType; Object[] tableau = liste.toArray(tabType);

La suppression d'un ou plusieurs éléments d'une liste s'accomplit par le truchement de plusieurs méthodes, en l'occurrence remove(), removeRange(), retainAll() et clear().

// supprime l'objet à l'index spécifié
liste.remove(10);
// supprime les objets compris dans l'intervalle spécifié
liste.removeRange(5, 15);
// supprime tous les éléments ne faisant 
//pas partie de la collection spécifiée
liste.retainAll(colection); // supprime tous les éléments de la liste liste.clear();

La taille de la liste est accessible à partir de la méthode size().

int taille = liste.size();

La capacité peut être augmentée par la méthode ensureCapacity() et réadapter par rapport à la taille courante avec trimToSize().

// augmente la capacité de la liste
liste.ensureCapacity(50);
// réajuste la capacité à la taille de la liste
int taille = liste.size(); // taille = 33
liste.trimToSize();  capacité = 33

La méthode set() remplace un élément de la liste par un objet spécifié et retourne l'élément remplacé.

Object eltRemplace = liste.set(10, nouvelObjet);

Le parcours des éléments d'un objet ArrayList peuvent se faire en utilisant une boucle, ou en appliqant un itérateur sur les éléments de la liste.

for(int i = 0; i < liste.size(); i++){
    Object element = liste.get(i);
}
// itérateur
Iterator iterateur = liste.iterator();
while(iterateur.hasNext()){
    Object element = iterateur.next();
}
// itérateur de liste
ListIterator iterateur = liste.listIterator();
while(iterateur.hasNext()){
    Object element = iterateur.next();
}

L'objet ListIterator possède plusieurs méthodes supplémentaires efficaces dans la gestion des listes, par rapport à une implémentation de l'interface Iterator surtout utilisée dans le cadre des ensembles (Set). Ainsi, il est possible de parcourir une liste dans les deux directions possibles.

// parcours du bas vers le haut
ListIterator iterateur = liste.listIterator();
while(iterateur.hasPrevious()){
    Object element = iterateur.previous();
}
// parcours du haut vers le bas
ListIterator iterateur = liste.listIterator();
while(iterateur.hasNext()){
    Object element = iterateur.next();
}

D'autre part, les méthodes permettent de retourner l'index suivant (nextIndex()) ou précédent (previousIndex()), de supprimer (remove()), d'ajouter (add()) et de remplacer (set()) des éléments.

Exemple [voir]
import java.util.ArrayList;
import java.util.Iterator;

public class programme {
  public static void main(String[] args) {
    ArrayList tableau = new ArrayList(500);

    for(int i = 1; i <= 100; i++)
      tableau.add(new Integer(i));
    tableau.trimToSize();

    System.out.println("Taille du tableau : " + tableau.size());

    if(tableau.contains(new Integer(50)))
      System.out.println("L'objet Integer ayant une "
               + "valeur égale à 50 a été trouvé");
    
    for(int i = 0; i < tableau.size(); i++)
      System.out.println(i + " : " + tableau.get(i).getClass() 
              + " " + tableau.get(i));

    for(int i = 0; i < tableau.size(); i++)
      if(((Integer)tableau.get(i)).intValue() % 2 != 0)
        tableau.set(i, null);

    Iterator iterateur = tableau.iterator();
    while(iterateur.hasNext())
      System.out.println(iterateur.next());

    System.out.println("Le premier null se trouve à l'index " 
                  + tableau.indexOf(null));
    System.out.println("Le dernier null se trouve à l'index " 
                  + tableau.lastIndexOf(null));

    Integer[] type = new Integer[10];
    Object[] sauvegarde = tableau.toArray(type);
    System.out.println(sauvegarde.getClass());
    
    if(!tableau.isEmpty())
      tableau.clear();
      
    System.out.println("Taille du tableau : " + tableau.size());
  }
}

25.3.5 / L'interface List

L'interface List représente une collection ordonnée, également connue sous le terme de séquence.

L'utilisateur de cette interface a un contrôe précis sur la position sur laquelle chaque élément sera inséré.

L'interface List étend l'interface racine Collection. Elle est implémentée par les classes AbstractList, ArrayList, LinkedList, et Vector.

A l'image des tableaux, il est possible d'accéder aux éléments d'une liste par l'intermédiaire d'un index. La recherche s'effectue de la même façon.

Les listes peuvent contenir des éléments dupliqués, ainsi que des valeurs null. Bien qu'il soit possible d'implémenter une liste n'acceptant pas les doublons, cela est fortement déconseillé.

Les implémentations de l'inteface Set peuvent ajouter des restrictions supplémentaires surr les éléments qu'ils peuvent contenir, telles qu'interdire les éléments null ou de certains types. Dans le cas ou des tentatives d'ajouter des éléments inéligibles seraient pratiquées, des exceptions contrôlées pourraient être levées, à l'image d'un NullPointerException ou d'un ClassCastException. En outre, les opérations sur un élément inéligible, telles qu'une vérification de présence, peuvent provoquer un comportement différent selon les implémentations comme la levée d'une exception ou un échec normal de l'opération (retour d'un booléen false).

Les méthodes
void add(int index, Object element)
insère un objet à l'index spécifié, au sein de la liste courante.
boolean add(Object o)
ajoute l'élément spécifié à la fin de la liste en cours.
boolean addAll(Collection c)
ajoute tous les éléments de la collection spécifiée à la fin de la liste, selon l'ordre imposé par l'itérateur de la liste en cours.
boolean addAll(int index, Collection c)
insère tous les éléments de la collection spécifiée, à l'index donné au sein de la liste.
void clear()
supprime tous les éléments de la liste courante.
boolean contains(Object o)
retourne true si la liste contient l'élément spécifié.
boolean containsAll(Collection c)
retourne true si la liste contient tous les éléments de la collection spécifiée.
boolean equals(Object o)
teste l'égalité entre la liste et l'objet spécifié.
Object get(int index)
retourne l'élément à la position spécifiée dans la liste.
int hashCode()
retourne le code de hachage de la liste.
int indexOf(Object o)
retourne la position de la première occurrence de l'objet au sein de la liste courante, ou -1 s'il n'a pu être trouvé.
boolean isEmpty()
retourne true si la liste ne contient aucun élément.
Iterator iterator()
retourne un itérateur sur les éléments de la liste en cours.
int lastIndexOf(Object o)
retourne la position de la dernière occurrence de l'objet spécifié au sein de la liste, ou -1 s'il n'a pu être trouvé.
ListIterator listIterator()
retourne un itérateur de liste sur les éléments de l'objet List.
ListIterator listIterator(int index)
retourne un itérateur de liste sur les éléments de l'objet List à partir de la position spécifiée.
Object remove(int index)
supprime l'élément positionné à l'index spécifié au sein de la liste.
boolean remove(Object o)
supprime la première occurrence de l'élément spécifié au sein de la liste.
boolean removeAll(Collection c)
supprime tous les éléments de la collection spécifiée, au sein de la liste, s'ils sont présents.
boolean retainAll(Collection c)
retient seulement les éléments de la liste qui ne sont pas contenus dans la collection spécifiée.
Object set(int index, Object element)
remplace l'élément à la position spécifiée dans la liste, par l'objet passé en argument.
int size()
retourne le nombre d'éléments contenus dans la liste.
List subList(int fromIndex, int toIndex)
retourne une partie de la liste, délimitée par les index fromIndex inclus et toIndex exclus.
Object[] toArray()
retourne un tableau contenant tous les éléments de la liste courante.
Object[] toArray(Object[] a)
retourne un tableau contenant tous les éléments de la liste courante. Le type d'exécution du tableau retourné est celui du tableau spécifié.

25.4 / Les maps

Les maps sont en quelque sorte des tableaux associatifs qui permettent de lier un objet clé à un autre objet valeur.

25.4.1 / La classe Dictionary

La classe Dictionary est une classe abstraite permettant d'associer des clés à des valeurs, à l'image d'un dictionnaire faisant correspondre un mot à une définition.

Les clés et les valeurs peuvent être des objets de n'importe quel type Java. La valeur null n'est pas supportée par un objet Dictionary. Dans un objet Dictionary, chaque clé doit être associée à au moins une valeur.

L'implémentation de la classe Dictionary est la classe Hashtable.

public class Hashtable extends Dictionary
                    implements Map, Cloneable, Serializable {
    //Instructions...
}

La méthode equals() doit être utilisée par les implémentations de cette classe, afin de pouvoir effectuer un test d'égalité entre des clés. Lors de la recherche d'une valeur avec la méthode get(), de l'ajout d'une paire clé/valeur avec la méthode put() ou de la suppression d'une paire clé/valeur avec la méthode remove(), la méthode equals() est appelée automatiquement afin de vérifier la présence d'une clé par rapport à un objet spécifié.

Une énumération des clés ou des valeurs peut être obtenue par l'intermédiaire respectivement les méthodes keys() et elements().

La taille d'un objet Dictionary, c'est-à-dire, son nombre d'entrées, est accessible via la méthode size() et il est possible de vérifier si le dictionnaire contient des paires clé/valeur en utilisant la méthode isEmpty().

La classe Dictionary est rendue obsolète depuis le JDK 1.2, par l'interface Map implémentant les collections HashMap, TreeMap, Hashtable et SortedMap. Il est préférable d'implémenter l'interface Map plutôt que d'étendre une classe abstraite.

Les constructeurs
Dictionary()
crée un nouvel objet Dictionary.

Les méthodes
abstract Enumeration elements()
retourne une énumération des valeurs du dictionnaire.
abstract Object get(Object key)
retourne la valeur pointée par la clé spécifiée au sein de la collection.
abstract boolean isEmpty()
vérifie si le dictionnaire ne contient aucune entrée.
abstract Enumeration keys()
retourne une énumération des clés du dictionnaire.
abstract Object put(Object key, Object value)
associe une valeur spécifiée à une clé donnée au sein du dictionnaire.
abstract Object remove(Object key)
supprime l'entrée correspondant à la clé spécifiée.
abstract int size()
retourne le nombre d'entrées au sein de l'objet Dictionary.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Exemple [voir]
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;

public class CollectionDictionary {
  public static void main(String[] args) {
    String[] joursSemaine = {"lundi", "mardi", "mercredi", "jeudi", 
                             "vendredi", "samedi", "dimanche"};
    String[] daysOfWeek = {"sunday", "monday", "tuesday", "wednesday", 
                           "thursday", "friday", "saturday"};
    Dictionary dictionnaire = new Hashtable();
    for(int i = 0; i < joursSemaine.length; i++){
      dictionnaire.put(daysOfWeek[i < joursSemaine.length - 1 ? i+1 : 0], 
                       joursSemaine[i]);
    }
    System.out.println("Taille du dictionnaire : " + dictionnaire.size());
    int i = 1;
    Enumeration valeurs = dictionnaire.elements();
    Enumeration cles = dictionnaire.keys();
    while(valeurs.hasMoreElements() && cles.hasMoreElements()){
      System.out.println(i++ + " entrée : " + valeurs.nextElement() 
                     + " -> " + dictionnaire.remove(cles.nextElement()));
    }
    System.out.println("Taille du dictionnaire : " + dictionnaire.size());
  }
}

25.4.2 / L'interface Map

L'interface Map permet aux objets qui l'implémente de disposer d'un ensemble de méthodes destinées à manipuler des collections contenant des valeurs associées à des clés.

Les objets implémentant l'interface Map ne peuvent contenir des clés dupliquées. Chaque clé doit correspondre au maximum à une seule valeur. Autrement dit, les clés doivent être uniques.

Les objets Map tels que AbstractMap, HashMap, Hashtable, IdentityHashMap, TreeMap et WeakHashMap, dépendent de deux méthodes particulièrement importantes pour le fonctionnement de ces collections. En effet, les méthodes hashCode() et equals() permettent respectivement de calculer le code de hachage des clés, et de tester l'égalité entre deux objets clés. Lors de la récupération d'une valeur par la méthode get(), de l'ajout d'une entrée par put() ou encore de la suppression d'une paire clé/valeur par remove(), les méthodes equals() et hashCode() y jouent un rôle fondamentale, car elles sont chargées d'assurer la cohérence de la collection. Par exemple, si une nouvelle entrée doit être ajoutée à la collection, et que la clé y est déjà présente, il faut remplacer la valeur de cette clé et non rajouter une nouvelle paire clé/valeur.

L'interface Map a rendue obsolète la classe abstraite Dictionary.

L'interface Map fournit plusieurs ensembles de méthodes :

La classe imbriquée Map.Entry consitue une entrée au sein d'un objet implémentant l'interface Map. Les objets Map.Entry sont accessibles au sein de l'objet Set résultant de l'appel de la méthode entrySet().

Les classes imbriquées
static interface Map.Entry
représente une entrée (clé -> valeur) d'une collection Map.
Les méthodes
void clear()
supprime toutes les paires clé/valeur de la collection.
boolean containsKey(Object key)
retourne true si la collection contient une paire clé/valeur correspondant à la clé spécifiée.
boolean containsValue(Object value)
retourne true si la collection contient une ou plusieurs clés pointant la valeur spécifiée.
Set entrySet()
retourne un objet Set contenant toutes les entrées de la collection.
boolean equals(Object o)
teste l'égalité entre l'objet Map et un autre objet.
Object get(Object key)
reetourne la valeur correspondant à la clé spécifiée.
int hashCode()
retourne le code de hachage.
boolean isEmpty()
retourne true si la collection ne contient aucune entrée.
Set keySet()
retourne un objet Set contenant les clés de l'objet Map.
Object put(Object key, Object value)
associe la valeur spécifiée à la clé donnée au sein de la collection.
void putAll(Map t)
copie toutes les paires clé/valeur de la collection spécifiée au sein de l'objet Map.
Object remove(Object key)
supprime la paire clé/valeur correspondant à la clé spécifiée.
int size()
retourne le nombre d'entrées dans la collection.
Collection values()
retourne un objet Collection contenant les valeurs de l'objet Map.

25.4.3 / La classe Hashtable

La classe Hashtable permet de stocker des valeurs en les associant à des identificateurs uniques calculés à partir des clés.

Les clés et valeurs ne doivent pas possèder la valeur null, mais en revanche peuvent être des objets de n'importe quel type.

Les opérations d'ajout (put()), de récupération (get()) et de suppression (remove()) utilisent les méthodes equals() et hashCode().

Lors du stockage d'une paire clé/valeur, l'objet représentant la clé est automatiquement soumise à la méthode hashCode() afin d'en récupérer un code de hachage identifiant d'une manière unique l'objet valeur. Ensuite, les codes de hachage sont comparés de telle sorte à vérifier si la clé est déjà présente dans la table de hachage. Si tel est le cas, la valeur donnée remplace l'ancienne.

//Extrait de la méthode put()
public synchronized Object put(Object key, Object value) {
  //...
  Entry tab[] = table;
  int hash = key.hashCode();
  int index = (hash & 0x7FFFFFFF) % tab.length;
  for (Entry e = tab[index] ; e != null ; e = e.next) {
    if ((e.hash == hash) && e.key.equals(key)) {
      Object old = e.value;
      e.value = value;
      return old;
    }
  }
  //...
}

Lors d'une recherche d'une valeur dans une table de hachaqe, un appel implicite à la méthode hashCode() est effectué afin d'en extraire le code de hachage de l'objet soumis à la méthode get(). Puis une comparaison automatique (equals()) est pratiquée entre le code de hachage de l'objet et ceux des clés de la table de hachage. Si les codes de hachage correspondent, alors la valeur associée est retournée.

// Méthode get de la classe Hashtable
public synchronized Object get(Object key) {
  Entry tab[] = table;
  int hash = key.hashCode();
  int index = (hash & 0x7FFFFFFF) % tab.length;
  for (Entry e = tab[index] ; e != null ; e = e.next) {
    if ((e.hash == hash) && e.key.equals(key)) {
      return e.value;
    }
  }
  return null;
}

De la même façon, la méthode containsKey(), vérifiant l'existence d'une clé au sein de la collection, utilise les méthodes hashCode() et equals(). Quant aux méthodes contains() et containsValue(), vérifiant l'existence d'une valeur au sein de la collection, emploient la méthode equals().

// Méthode get de la classe Hashtable
public synchronized boolean containsKey(Object key) {
  Entry tab[] = table;
  int hash = key.hashCode();
  int index = (hash & 0x7FFFFFFF) % tab.length;
  for (Entry e = tab[index] ; e != null ; e = e.next) {
    if ((e.hash == hash) && e.key.equals(key)) {
      return true;
    }
  }
  return false;
}

Une instance de classe Hashtable possède deux paramètres qui affecte ses performances. Il s'agît de la capacité initiale et le facteur de charge d'une table de hachage.

Par exemple, si une table de hachage possède une capacité initiale égale à 100 et un facteur de charge de 0.75, lorsque la table de hachage atteindra un taux de remplissage de 75 pourcents, alors la capacité est augmentée par un appel automatique à la méthode rehash().

public class CollectionMap {
  public static void main(String[] args) {
    TableHachage table = new TableHachage(100, 0.70f);
    if(table.isEmpty()){
      for(int i = 0; i < 100; i++) {
        table.put(new Integer(i), new Double(Math.pow(i, 2)));
      }
    }
  }
}

// Extension de la classe Hashtable...
import java.util.Hashtable;
import java.util.Map;

public class TableHachage extends Hashtable {
  public TableHachage(int capaciteInitiale, float facteurCharge) {
    super(capaciteInitiale, facteurCharge);
  }
  protected void rehash(){
    System.out.println("La méthode rehash() a été appelée !\n" 
                     + "La taille était alors égale à " + super.size());
    super.rehash();
  }
}

Par défaut, la capacité initiale et le facteur de charge d'un objet Hashtable sont respectivement 11 et 0.75. Sinon, deux constructeurs permettent de fournir soit la capacité initiale soit cette dernière et le facteur de charge durant l'instanciation de la classe Hashtable.

// par défaut
Hashtable table = new Hashtable();
// capacité initiale
Hashtable table = new Hashtable(100);
// capacité initiale et facteur de charge
Hashtable table = new Hashtable(100, 0.70f);

Un autre constructeur permet d'initialiser l'objet Hashtable avec les entrées d'une implémentation de la classe Map, telle que les collections AbstractMap, HashMap, Hashtable, IdentityHashMap, TreeMap et WeakHashMap.

HashMap collection = new HashMap(50, 0.75f);
for(int i = 0; i < collection.size(); i++) 
    collection.put(new Integer(i), new Integer(Math.pow(i, 2)));

Hashtable table = new Hashtable(collection);

La méthode putAll() propose cette fonctionnalité d'ajout groupé après que l'objet ait été créé.

HashMap collection = new HashMap(50, 0.75f);
for(int i = 0; i < collection.size(); i++) 
    collection.put(new Integer(i), new Integer(Math.pow(i, 2)));

Hashtable table = new Hashtable(collection);
table.putAll(collection);

La classe Hashtable dispose de plusieurs méthodes retournant des énumérations, ensembles et collections. Les clés et les valeurs peuvent être récupérées distinctement dans des objets Enumeration par les méthodes respectives keys() et elements(). D'autres méthodes extrayent les valeurs dans un objet Collection (values()) et les clés dans un objet Set (keySet()). Enfin une dernière méthode (entrySet()) renvoie une collection Set contenant les entrées de la table de hachage, sous la forme d'objets Map.Entry.

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class CollectionMap {
  public static void main(String[] args) {
    Hashtable table = new Hashtable();
    for(int i = 0; i < 26; i++){
      char car = (char)('a' + i);
      table.put(new Integer(i), new Character(car));
    }
    System.out.println("Taille de la table de hachage : " + table.size());
    Set ensemble = table.entrySet();
    Iterator i = ensemble.iterator();
    while(i.hasNext()){
      Object o = i.next();
      System.out.println(o.getClass().getName() + "\t" + o.toString());
      Map.Entry entree = (Map.Entry)o;
      System.out.println("\t" + entree.getKey() + " -> " + entree.getValue());
    }
  }
}
Exemple [voir]
import java.util.Enumeration;
import java.util.Hashtable;

public class CollectionMap {
  public static void main(String[] args) {
    String[] joursSemaine = {
                              "lundi", 
                              "mardi", 
                              "mercredi", 
                              "jeudi", 
                              "vendredi", 
                              "samedi", 
                              "dimanche"
                            };
    String[] daysOfWeek = {
                            "sunday", 
                            "monday", 
                            "tuesday", 
                            "wednesday", 
                            "thursday", 
                            "friday", 
                            "saturday"
                          };
    Hashtable tableHachage = new Hashtable();
    for(int i = 0; i < joursSemaine.length; i++){
      tableHachage.put(daysOfWeek[i < joursSemaine.length - 1 ? i+1 : 0], 
                       joursSemaine[i]);
      System.out.println(tableHachage.toString());
    }
    System.out.println("Taille de la table de hachage : " 
                                                    + tableHachage.size());
    int i = 1;
    Enumeration valeurs = tableHachage.elements();
    Enumeration cles = tableHachage.keys();
    while(valeurs.hasMoreElements() && cles.hasMoreElements()){
      System.out.println(i++ + " entrée : " + valeurs.nextElement() 
                                   + " -> " + tableHachage.remove(cles.nextElement()));
    }
    System.out.println("Taille de la table de hachage : " 
                                                    + tableHachage.size());
  }
}

25.4.4 / La classe HashMap

La classe HashMap est une implémentation de l'interface Map et une extension de la classe AbstractMap.

// Extrait de la classe hashMap
public class HashMap extends AbstractMap
                     implements Map, Cloneable, java.io.Serializable {
  //...
}

Une seule clé null est autorisée dans une instance de classe HashMap. Par contre, les valeurs null peuvent être plusieurs, l'unicité des entrées étant assurées essentiellement par les clés.

Les objets HashMap ne garantissent pas l'ordre des éléments durant une itération de l'associations, contrairement aux collections TreeMap. En effet, la fonction de hachage disperse les éléments au sein d'une collection Map.

Néanmoins, les performances des objets implémentant cette classe restent constantes pour les opérations de base, telles que l'ajout (put()), l'extraction (get()).

Il existe quatre constructeurs concourant à la création d'une collection HashMap. Le constructeur par défaut (HashMap()) initialise l'instance avec des valeurs par défaut, soit une capacité initiale et un facteur de charge par défaut égaux respectivement à 16 et à 0.75. Toutefois, il est possible d'indiquer soit la capacité initiale seule (HashMap(int ini)), soit la capacité initiale et le facteur de charge (HashMap(int ini, float fac)).

// par défaut
HashMap associations = new HashMap();
// capacité initiale
HashMap associations = new HashMap(100);
// capacité initiale et facteur de charge
HashMap associations = new HashMap(100, 0.70f);

La capacité initiale spécifie le nombre de cases allouées initialement à l'objet. Le facteur de charge permet de déterminer à quel moment doit être recalculé la capacité de la collection HashMap afin d'accueillir éventuellement plus d'éléments. Dans le cas d'une capacité initiale de 100 et un facteur de charge de 0.70 et lorsque le taux de remplissage atteint 70 pourcents (100 * 0.70), la capacité est recalculée et l'objet est réorganisé en conséquence. Le facteur de charge influe sur les performances de l'objet HashMap, si bien qu'il est important de ne pas le paramétrer trop bas.

le dernier constructeur accepte comme argument une collection destinée à initialiser la nouvelle instance. Chaque entrée de la collection spécifiée sera copiée au sein de l'objet HashMap créé.

Map collection = new TreeMap();
collection.put(cle, valeur);
HashMap associations = new HashMap(collection);

La classe HashMap comprend deux méthodes d'ajout put() et putAll() permettant respectivement d'ajouter une seule paire clé/valeur et toutes les entrées d'une collection Map. Les méthodes d'ajout vérifient au préalable si les clés spécifiées ne sont pas déjà présentes dans la collection. Si tel est le cas, alors les valeurs correspondantes aux clés existantes sont remplacées par les nouvelles valeurs spécifiées.

Object entree = associations.put(cle, valeur);

Map collection = new TreeMap();
// Ajout d'entrées à la collection...
associations.putAll(collection);

La suppression d'une entrée spécifique par rapport à sa clé ou de la totalité des paires clé/valeur s'effectue respectivement par l'entremise de la méthode remove() ou clear().

// suppression de l'entrée correspondant à la clé passé en argument
Object entreeSupprimee = associations.remove(cle);
// suppression de toutes les entrées de la collection HashMap
associations.clear();

La méthode get() permet l'extraction d'une valeur en fonction d'une clé indiquée. L'objet retourné est du type référence Object, si bien qu'il sera nécessaire dans la plupart des cas d'utilisation, de convertir cet objet dans la type adéquat.

HashMap associations = new HashMap();
associations.put("Une clé", new StringBuffer("Une valeur");
// extraction d'une valeur
Object obj = associations.get("Une clé");
((StringBuffer)obj).setCharAt(3, '_');

La vérification de présence d'entrées, d'une clé ou d'une valeur est possible par l'intermédiaire des méthodes isEmpty(), containsKey() et containsValue().

if(associations.isEmpty())
    System.out.println("La collection est vide !");

if(associations.containsKey(cle))
    System.out.println("La clé 'cle' a été trouvée !");

if(associations.containsValue(valeur))
    System.out.println("La valeur 'valeur' a été trouvée !");

La taille de l'objet HashMap, soit le nombre d'entrées contenues, est retourné par la méthode size().

int taille = associations.size();

En outre, la collection HashMap comporte plusieurs méthodes capables d'extraire la totalité des entrées, ou uniquement les clés ou les valeurs stockées dans l'objet TreeMap.

HashMap associations = new HashMap();
// remplissage de la collection...
// Toutes les clés sont stockées dans la collection Set
Set cles = associations.keySet();
// Toutes les valeurs sont stockées dans l'objet Collection.
Collection valeurs = associations.values();

La méthode entrySet() retourne toutes les entrées de l'objet HashMap au sein d'un ensemble Set. Le contenu de cette collection Set est un ensemble d'objets Map.Entry contenant la clé et la valeur de chaque paire clé/valeur de l'objet HashMap.

Set entrees = associations.entrySet();
Iterator iterateur = entrees.iterator();
while(iterateur.hasNext()){
  Map.Entry entree = (Map.Entry)iterateur.next();
  System.out.println(entree.getKey() + " " + entree.getValue());
}

Les méthodes equals() et hashCode() revêtent une importance capitale dans le fonctionnement d'un objet HashMap. Effectivement, chaque entrée ajoutée, recherchée ou supprimée fait appel à ces méthodes pour calculer le code de hachage des objets clés et les comparer entre eux.

Exemple [voir]
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Map;
import java.util.TreeMap;

public class CollMap {
  private static TreeMap assocTreeMap = new TreeMap();

  public static void main(String[] args) {
    HashMap associations = new HashMap();
    associations.putAll(assocTreeMap);

    System.out.println("Taille de la collection 'associations' : " + associations.size());
    afficherEntrees(associations);

    Video obj = new Video("Platoon", "Oliver Stone", 1986);
    if(associations.containsKey(obj))
      System.out.println(System.out.println("\nL'objet ci-dessous a été supprimé :\n" 
        + associations.remove(new Video("Platoon", "Oliver Stone", 1986)));
    System.out.println("\nTaille de la collection 'associations' : " + associations.size());
    afficherEntrees(associations);

    Set entrees = associations.entrySet();
    Iterator iterateur = entrees.iterator();
    System.out.println("\nListe des entrées (clé - valeur)");
    while(iterateur.hasNext()){
      Map.Entry entree = (Map.Entry)iterateur.next();
      System.out.println(entree.getKey() + " - " + entree.getValue());
    }
  }
  public static void afficherEntrees(Map assoc){
    Set ensemble = assoc.keySet();
    int taille = assoc.size();
    if(!assoc.isEmpty()){
      Iterator iterateur = ensemble.iterator();
      while(iterateur.hasNext()){
        Object o = iterateur.next();
        System.out.println(o.toString() + " : " + assoc.get(o));
      }
    }
  }
  public static void ajoutTreemap(){
    assocTreeMap.put(new Video("Le jour le plus long", "Ken Annakin", 1962), 
                   "Le débarquement en Normandie par les troupes alliées " 
                 + "le 6 juin 1944. Un casting prestigieux pour un film " 
                 + "de guerre d'anthologie.");
  assocTreeMap.put(new Video("Un pont trop loin", "Richard Attenborough", 1977), 
                   "La plus grande opération aéroportée sur les ponts entre " 
                 + "la France et l'Allemagne, doit précipiter la chute de "
                 + "l'Allemagne nazie.");
  assocTreeMap.put(new Video("Platoon", "Oliver Stone", 1986), 
                   "Ce film choc sur la guerre du Vietnam, met en "
                 + "scène un peloton du 25eme régiment d'infanterie "
                 + "gangréné par des luttes intestinales.");
  assocTreeMap.put(new Video("Full metal jacket", "Stanley Kubrik", 1987), 
                 + ""Cette épopée de la guerre du Vietnam raconte "
                 + "l'évolution de jeunes Marines durant un entraînement "
                 + "impitoyable et jusqu'à une réalité sanglante des "
                 + "combats lors des offensives du tet à Hue.");
  assocTreeMap.put(new Video("La ligne rouge", "Terrence Malick", 1998), 
                   "Ce film décrit la bataille de Guadalcanal et ses "
                 + "terribles affrontements entre soldats américains "
                 + "et japonais dans une île aux paysages paradisiaques.");
  assocTreeMap.put(new Video("The patriot", "Roland Emmerich", 2000), 
                 + ""Lors de la guerre d'indépendance américaine en 1776, "
                 + "un père tente de sauvegarder ses enfants de la barbarie "
                 + "d'une guerre fratricide, mais ne peut empêcher d'y être "
                 + "plongé malgrè lui.");
  }
}

//Classe Video
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

25.4.5 / La classe TreeMap

La classe TreeMap est une implémentation de l'interface SortedMap et une extension de la classe AbstractMap.

// extrait de la classe TreeMap
public class TreeMap extends AbstractMap
         implements SortedMap, Cloneable, java.io.Serializable {
  //...
}

Cette classe garantit que la collection Map sera triée selon un ordre croissant, conformément à l'ordre naturel des clés ou à l'aide d'un comparateur fourni au moment de la création de l'objet TreeMap.

Les objets TreeMap fournissent de très bonnes performances (log(n)) pour des opérations de base, telles que lors d'extractions, d'ajouts et de suppressions et de vérifications de présence de clés.

Il existe quatre constructeurs permettant d'instancier la classe TreeMap. Le constructeur par défaut (TreeMap()) initialise l'objet en fondant son mode de tri sur l'ordre naturel des éléments. Toutefois, un autre constructeur permet de spécifier un comparateur afin d'effectuer le tri des paires clé/valeur de l'objet TreeMap.

// par défaut
TreeMap associations = new TreeMap();
// comparateur
Comparator comparateur = new Comparateur();
TreeMap associations = new TreeMap(comparateur);

// classe Comparateur implémentant l'interface Comparator
public class Comparateur implements Comparator {
  public int compare(Object obj1, Object obj2){
    return ((Comparable)obj2).compareTo(obj1);
  }
  public boolean equals(Object obj){
    return this.equals(obj);
  }
}

L'objet Comparator doit être créé par les soins du programmeur. Pour cela, il est nécessaire d'écrire une classe devant implémenter l'interface Comparator, laquelle possède deux méthodes compare() et equals() qui doivent être définies dans cette classe. Un objet TreeMap défini sans comparateur, utilise les méthodes compareTo() et equals() des objets contenus dans cet objet Map.

public interface Comparator {
  public int compare(Object o1, Object o2);
  public boolean equals(Object o);
}

Les deux autres constructeurs acceptent comme argument un objet de type Map ou SortedMap, destinée à initialiser la nouvelle instance. Chaque paire clé/valeur des collections spécifiées sera copiée au sein de l'objet TreeMap. Dans le premier cas, la collection sera triée selon l'ordre naturel de ses clés, dans le second, conformément à l'ordonnancement de l'objet SortedMap indiqué.

// initialisation avec un objet Map
Map collection = new HashMap();
collection.put(cle, valeur);
//...
TreeMap associations = new TreeMap(collection);

// initialisation avec un objet SortedMap
SortedMap collection = new TreeMap(comparateur);
collection.put(cle, valeur);
//...
TreeMap associations = new TreeMap(collection);

La classe TreeMap contient des méthodes d'ajout (put() et putAll()), de suppression (remove() et clear()), de vérification de présence (isEmpty(), containsKey() et containsValue()), d'information (size()) et d'extraction (get()).

La classe TreeMap fournit deux méthodes firstKey() et lastKey(), chargées respectivement de récupérer dans un objet Map la première clé, soit la plus petite, et la dernière clé, soit la plus grande. La comparaison entre les clés est assurée par l'ordre naturel ou par le comparateur fourni lors de l'instanciation de l'objet.

Object premier = associations.fisrtKey();

Object dernier = associations.lastKey();

Le comparateur associé à la collection TreeMap est accessible via la méthode comparator().

Comparator comparateur = associations.comparator();

En outre, la collection SortedMap comporte plusieurs méthodes capables d'extraire la totalité ou une partie des entrées, ou seulement des clés ou des valeurs stockées dans l'objet TreeMap. Les méthodes headMap(), trailMap(), subMap(), keySet() et values() permettent toutes d'obtenir une vue spécifique de la collection TreeMap.

TreeMap associations = new TreeMap();
// remplissage de la collection...
// Toutes les clés sont stockées dans la collection Set
Set cles = associations.keySet();
// Toutes les valeurs sont stockées dans l'objet Collection.
Collection valeurs = associations.values();

Les méthodes headMap() et tailMap() retournent seulement les entrées de l'objet TreeMap, dont les clés sont respectivement, strictement inférieures et supérieures ou égales à l'objet passé en argument. La méthode subMap() extrait un intervalle d'entrées, dont les clés sont comprises entre la valeur du premier argument incluse et la valeur du second argument exclue.

SortedMap partieInferieure = associations.headMap(valeur);

SortedMap partieSuperieure = associations.tailMap(valeur);

SortedMap partie = associations.subMap(valInf, valSup);
Exemple [voir]
import java.util.Iterator;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Comparator;

public class CollectionSortedMap {
  static final Comparator ORDRE_REALISATEUR = new CompRealisateur();
  static final Comparator ORDRE_ANNEE = new CompAnnee();

  public static void main(String[] args) {
    TreeMap associations = new TreeMap();
    associations.put(new Video("Le jour le plus long", "Ken Annakin", 1962), 
                     "Le débarquement en Normandie par les troupes alliées " 
                   + "le 6 juin 1944. Un casting prestigieux pour un film " 
                   + "de guerre d'anthologie.");
    associations.put(new Video("Un pont trop loin", "Richard Attenborough", 1977), 
                     "La plus grande opération aéroportée sur les ponts entre " 
                   + "la France et l'Allemagne, doit précipiter la chute de "
                   + "l'Allemagne nazie.");
    associations.put(new Video("Platoon", "Oliver Stone", 1986), 
                     "Ce film choc sur la guerre du Vietnam, met en "
                   + "scène un peloton du 25eme régiment d'infanterie "
                   + "gangréné par des luttes intestinales.");
    associations.put(new Video("Full metal jacket", "Stanley Kubrik", 1987), 
                   + ""Cette épopée de la guerre du Vietnam raconte "
                   + "l'évolution de jeunes Marines durant un entraînement "
                   + "impitoyable et jusqu'à une réalité sanglante des "
                   + "combats lors des offensives du tet à Hue.");
    associations.put(new Video("La ligne rouge", "Terrence Malick", 1998), 
                     "Ce film décrit la bataille de Guadalcanal et ses "
                   + "terribles affrontements entre soldats américains "
                   + "et japonais dans une île aux paysages paradisiaques.");
    associations.put(new Video("The patriot", "Roland Emmerich", 2000), 
                   + ""Lors de la guerre d'indépendance américaine en 1776, "
                   + "un père tente de sauvegarder ses enfants de la barbarie "
                   + "d'une guerre fratricide, mais ne peut empêcher d'y être "
                   + "plongé malgrè lui.");
    System.out.println("Tri par titre :");
    afficherEntrees(associations); 

    TreeMap associationsR = new TreeMap(ORDRE_REALISATEUR);
    associationsR.putAll(associations);
    System.out.println("\nTri par réalisateur :");
    afficherEntrees(associationsR);

    TreeMap associationsA = new TreeMap(ORDRE_ANNEE);
    associationsA.putAll(associations);
    System.out.println("\nTri par année :");
    afficherEntrees(associationsA);

    Video article = new Video("Platoon", "Oliver Stone", 1986);
    if(associations.containsKey(article))
        System.out.println("La vidéo Platoon a été trouvée !");

    System.out.println("\nRécupération des vidéos strictement inférieures :");
    SortedMap selectInf = 
            associations.headMap(article);
    afficherEntrees(selectInf);
    System.out.println("\nRécupération des vidéos supérieures ou égales :");
    SortedMap selectSup = 
            associations.tailMap(article);
    afficherEntrees(selectSup);
  }

  public static void afficherEntrees(SortedMap assoc){
    Set ensemble = assoc.keySet();
    int taille = assoc.size();
    Iterator iterateur = ensemble.iterator();
    while(iterateur.hasNext()){
      Object o = iterateur.next();
      System.out.println(o.toString() + " : " + assoc.get(o));
    }
  }
}

// Classe comparatrice CompRealisateur
import java.util.Comparator;

public class CompRealisateur implements Comparator {
  public int compare(Object o1, Object o2){
    if(!(o1 instanceof Video))
      throw new ClassCastException();
    return (((Video)o1).obtenirRealisateur()).compareTo(
                                        ((Video)o2).obtenirRealisateur());
  }
}

// Classe comparatrice CompAnnee
import java.util.Comparator;

public class CompAnnee implements Comparator {
  public int compare(Object o1, Object o2){
    if(!(o1 instanceof Video))
      throw new ClassCastException();
    return (new Integer(((Video)o1).obtenirAnnee())).compareTo(
                                        new Integer(((Video)o2).obtenirAnnee()));
  }
}

//Classe Video implémentant l'interface java.lang.Comparable
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

25.4.6 / L'interface SortedMap

L'interface SortedMap permet de créer un objet Map qui concourt à garantir que l'ordre des entrées sera accompli selon un tri croissant sur les clés, en accord avec l'ordre naturel de ses éléments (voir l'interface Comparable), ou par un comparateur fourni au moment de la création de l'instance.

Cet ordre est reproduit lors de l'itération sur les vues de la collection SortedMap retourné par les méthodes entrySet(), keySet() et values().

L'interface SortedMap étend l'interface Map. Elle est implémentée par une seule classe permettant de créer une collection associative triée sur ses clés, en l'occurrence, il s'agît de la collection TreeMap.

Plusieurs opérations supplémentaires sont proposées par l'interface SortedMap afin de fournir des fonctionnalités appuyant l'ordonnancement d'une implémentation de SortedMap.

Toutes les clés insérées dans une collection SortedMap doivent implémenter l'interface java.lang.Comparable ou être accepté par l'objet Comparator spécifié. En outre, toutes les clés d'une telle collection doivent êre mutuellement comparable, dans le cas contraire une exception ClassCastException sera levée.

boolean res = cle1.compareTo(cle2);
// ou
boolean res = comparateur.compare(cle1, cle2));

La classe imbriquée Map.Entry représente une entrée, soit une paire clé/valeur, dans une collection SortedMap.

Les classes imbriquées
Les classes imbriquées héritées de la classe java.util.Map
Map.Entry

Les méthodes
Comparator comparator()
retourne le comparateur associé à l'objet SortedMap ou null s'il utilise un ordre nature de ses clés.
Object firstKey()
retourne la première clé de l'objet SortedMap.
SortedMap headMap(Object toKey)
retourne une partie des entrées, dont les clés sont strictement inférieures à la clé spécifiée, de l'objet SortedMap.
Object lastKey()
retourne la dernière clé de l'objet SortedMap.
SortedMap subMap(Object fromKey, Object toKey)
retourne une partie des entrées de l'objet SortedMap, dont les clés sont situées entre les objets fromKey inclus et toKey exclus.
SortedMap tailMap(Object fromKey)
retourne une partie des entrées de l'objet SortedMap, dont les clés sont plus grandes ou égales à fromKey.
Les méthodes héritées de l'interface java.util.Map
clear, containsKey, containsValue, entrySet, equals, get, hashCode, isEmpty, keySet, put, putAll, remove, size, values

25.5 / Les classes utilitaires

Les collections Java nécessitent le support de plusieurs classes et interfaces utilitaires pour fonctionner ou exécuter certaines opérations à l'image de comparaisons d'énumérations ou encore d'itérations. Les classes et interfaces utiles peuvent être Collections pour l'ensemble des collections, Enumeration pour les ensembles et les listes, Map.Entry pour les maps, etc..

25.5.1 / La classe Collections

La classe Collections est une classe utilitaire pour les collections Java. Cette classe contient des méthodes statiques qui manipulent ou retournent des collections.

Toutes les méthodes de la classe Collections sont susceptibles de lever un exception NullPointerException si les collections passées en argument possèdent la valeur null.

Trois champs statiques et constants, sont contenus dans la classe Collections, pour représenter une collection vide immutable.

List liste = Collections.EMPTY_LIST;

Set ensemble = Collections.EMPTY_SET;

Set associations = Collections.EMPTY_MAP;

Les méthodes binarySearch() permettent de rechercher, selon un algorithme binaire, un objet spécifié au sein d'une collection de type List également donnée. Un comparateur peut également être fourni afin d'ordonner la liste conformément à ses propres règles. Par défaut, l'ordre naturel est employé pour ce tri. Par ailleurs, si la liste contient plusieurs éléments égaux, alors il n'y a aucune garantie sur lequel des éléments sera trouvé. La valeur de retour de ces méthodes est du type int. Si l'objet spécifié est trouvé, la méthode retournera la position de l'élément, dans le cas contraire, la valeur -1 sera renvoyée. Si les éléments de la liste ne sont pas mutuellement comparables, alors l'exception ClassCastException sera levée par les méthodes.

List liste = new LinkedList();
liste.add("Un élément");
// ...
liste.add("Dix éléments");
int res = Collections.binarySearch(liste, "Quatre éléments");

List liste = new ArrayList();
liste.add(new Video("Le jour le plus long", "Ken Annakin", 1962));
// ...
liste.add(new Video("Platoon", "Oliver Stone", 1986));
int res = Collections.binarySearch(liste, 
              new Video("Platoon", "Oliver Stone", 1986), 
              compAnnee);

La méthode reverseOrder() retourne un objet Comparator qui impose un tri inverse à celui de l'ordre naturel d'une collection.

List liste = new LinkedList();
liste.add("Un élément");
// ...
liste.add("Dix éléments");
int res = Collections.sort(liste, 
                              Collections.reverseOrder());

Le tri des collections List peut être mis en oeuvre par les méthodes sort(), selon l'ordre naturel de éléments de la collection ou par rapport à un comparateur spécifié.

ArrayList tableau = new ArrayList();
tableau.add(new Video("Platoon", "Oliver Stone", 1986));
// ...
tableau.add(new Video("Le jour le plus long", "Ken Annakin", 1962));
Collections.sort(tableau, compRealisateur);

Les méthodes min() et max() retournent respectivement l'élément minimum ou maximum d'une collection spécifiée, selon l'ordre naturel de ses éléments ou d'un comparateur fourni. Un objet de type Object est retourné par ces méthodes.

Object oMin = Collections.min(tableau);

Object oMin = Collections.min(tableau, compAnnee);

Object oMax = Collections.max(tableau);

Object oMax = Collections.max(tableau, compAnnee);

Plusieurs méthodes permettent de modifier l'ordre initiale d'une collection List. La méthode swap() est capable d'échanger la position d'éléments en indiquant leurs index.

Collections.swap(liste, 5, 8);

La méthode rotate() fait glisser dans un sens ou dans l'autre, l'élément pointé dans une sorte de cercle joignant les deux extrêmités de la liste.

List liste = new LinkedList();
for (int i = 0; i <= 10; i++)
  liste.add(new Integer(i));
Collections.rotate(liste, 1); // sens avant
// liste[10, 0, 1, ..., 9]
Collections.rotate(liste, -1); // sens arrière
// liste[1, 2, ..., 10, 0]

Les méthodes shuffle() permutent aléatoirement la liste spécifiée en utilisant un algorithme aléatiore par défaut ou précisé par un objet Random.

Collections.shuffle(liste);

Collections.shuffle(liste, objRandom);

L'inversion complète de l'ordre des éléments d'une liste peut être obtenu par la méthode reverse().

List liste = new LinkedList();
for (int i = 0; i <= 10; i++)
  liste.add(new Integer(i));
Collections.reverse(liste);
// liste[10, 9, ..., 0]

La méthode fill() remplace tous les éléments de la liste indiquée par l'objet passé en argument.

Collections.fill(liste, null);

Il est possible de rechercher une liste cible au sein d'une liste source par l'intermédiaire des méthodes indexOfSubList() et lastIndexOfSubList(). La position de la première occurrence ou de la dernière de la liste cible, à l'intérieur de la liste source, est retournée, sinon, -1 est renvoyée.

List listeSource = new LinkedList();
for (int i = 0; i <= 10; i++)
  listeSource.add(new Integer(i));
List listeCible = new LinkedList();
for (int i = 3; i <= 7; i++)
  listeCible.add(new Integer(i));
Collections.indexOfSubList(listeSource, listeCible);
// retourne 3
Collections.lastIndexOfSubList(listeSource, listeCible);
// retourne 7

La méthode de copie de liste copy() est également à disposition dans la classe Collections. Elle recopie tous les éléments d'une liste source vers une liste cible.

Collections.copy(listeSource, listeCible);

La méthode nCopies() a pour fonction de créer un liste qui sera composée d'un certain nombre d'occurrences de l'objet spécifié.

List liste = Collections.nCopies(100, "bonjour");

La méthode replaceAll() donne la possibilité de substituer un élément existant par un nouvel objet, au sein d'une liste.

boolean res = 
        Collections.replaceAll(liste, ancValeur, nouvValeur);

Une énumération sur une collection donnée, peut être récupérée par le truchement de la méthode enumeration().

Enumeration e = Collections.enumeration(collection);

La méthode list() retourne un objet Arraylist à partir d'une énumération passée en argument.

ArrayList tab = Collections.list(enumeration);

Les singletons, ou ensembles constitués d'un seul élément, sont réalisables pour chaque genre de collections Java, par le biais des méthodes singleton() (Set), singletonList() et singletonMap(). Chacune de ces méthodes prend en argument un élément pour les collections Set et List ou une entrée pour les Map.

Set ensemble = Collections.singleton(objet);

List liste =  Collections.singletonList(objet);

Map associations = Collections.singletonMap(cle, valeur);

La possibilité de fournir des collections non-modifiables, soit accessibles en lecture seule, est donnée par les méthodes particulières préfixées par unmodifiable.

Collection collection = 
        Collections.unmodifiableCollection(colSource);

List liste = Collections.unmodifiableList(listeSource);

Map associations = Collections.unmodifiableMap(mapSource).

Set ensemble = Collections.unmodifiableSet(ensSource);

SortedMap mapTrie = 
        Collections.unmodifiableSortedMap(sortedMapSource);

SortedSet setTrie = 
        Collections.unmodifiableSortedSet(sortedSetSource);

Afin de pallier à un défaut de synchronisation d'une collection lors d'un fonctionnement en multithreads, des méthodes spécialisées permettent de retourner une collection synchronisée. Les trois types de collections (Set, List et Map) sont prises en compte, ainsi que celles triées (SortedSet et SortedMap).

Collection colSync = 
        Collections.synchronizedCollection(colSource);

List listeSync = Collections.synchronizedList(listeSource);

Map assocSync = Collections.synchronizedMap(mapSource);

Set ensSync = Collections.synchronizedSet(setSource);

SortedMap sortedMapSync = 
        Collections.synchronizedSortedMap(sortedMapSource);

SortedSet sortedSetSync = 
        Collections.synchronizedSortedSet(sortedSetSource);

Les objets Arraylist, HashMap, HashSet, IdentityHashMap, LinkedHashMap, TreeMap, TreeSet et WeakHashMap ne sont pas synchronisés et nécessitent donc l'apport des méthodes précitées.

Seules les collections Hashtable et Vector supportent la synchronisation. Toutes les méthodes sensibles lors d'une utilisation en multithreads sont synchonisées dans ces classes.

// Extrait de la classe Vector
public synchronized void addElement(Object obj) {
  modCount++;
  ensureCapacityHelper(elementCount + 1);
  elementData[elementCount++] = obj;
}
// Extrait de la classe Hashtable
public synchronized Enumeration elements() {
  return getEnumeration(VALUES);
}

25.5.2 / L'interface Enumeration

L'interface Enumeration fournit seulement deux méthodes permettant de parcourir les éléments d'un vecteur, les clés et les valeurs d''une table de hachage.

Vector vecteur = new Vector();
Enumeration enumeration = vecteur.elements();

Hashtable tableHachage = new Hashtable();
Enumeration enumValeur = tableHachage.elements();
Enumeration enumCle = tableHachage.keys();

Les objets implémentant l'interface Enumeration génère une série d'éléments à partir d'une liste ou d'un map, par l'intermédiaire de la méthode nextElement() qui retourne un élément des collections précitées et la seconde méthode hasMoreElements() teste s'il n'y a plus d'éléments dans l'objet Enumeration.

Les méthodes
boolean hasMoreElements()
retourne true si l'énumération n'a plus d'éléments.
Object nextElement()
retourne le prochaîn élément de l'itérateur.

Le fonctionnement de l'interface Enumeration consiste à obtenir un énumérateur à partir de la collection courante, puis au sein d'une boucle permettant d'accéder à chaque élément (nextElement()), vérifier dans la condition d'arrêt si l'énumérateur ne comporte plus d'éléments (hasMoreElement()).

Enumeration e = vecteur.elements();
while (!e.hasMoreElements()) {
    System.out.println(e.nextElement());
}

L'interface Enumeration a été abandonnée au bénéfice de l'interface Iterator possédant des noms de méthode plus courts, et surtout ajoutant une fonctionnalité supplémentaire, une opération de suppression.

Exemple [voir]
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

public class CollectionEnumeration {
    public static void main(String[] args) {
      Vector vecteur = creerVecteur();
      for (Enumeration enumerateur = 
            vecteur.elements() ; enumerateur.hasMoreElements() ;) {
        System.out.println(enumerateur.nextElement());
      }
      int j = 1;
      Hashtable tableHachage = creerTableHachage();
      for (Enumeration enumValeur = 
            tableHachage.elements(); enumValeur.hasMoreElements() ;) {
        System.out.println(j++ + " : " + enumValeur.nextElement());
      }
      j = 0;
      for (Enumeration enumCle = 
            tableHachage.keys(); enumCle.hasMoreElements() ;) {
        System.out.println(j++ + " : " + enumCle.nextElement());
      }
    }
    public static Vector creerVecteur(){
      Vector vecteur = new Vector();
      for(int i = 1; i <= 7; i++){
        vecteur.add(new Integer(i));
      }
      return vecteur;
    }
    public static Hashtable creerTableHachage(){
      String[] joursSemaine = {"lundi", "mardi", "mercredi", "jeudi", 
                               "vendredi", "samedi", "dimanche"};
      String[] daysOfWeek = {"sunday", "monday", "tuesday", "wednesday", 
                             "thursday", "friday", "saturday"};
      Hashtable tableHachage = new Hashtable();
      for(int i = 0; i < joursSemaine.length; i++){
        tableHachage.put(daysOfWeek[i < joursSemaine.length - 1 ? i+1 : 0], 
                                                              joursSemaine[i]);
        System.out.println(tableHachage.toString());
      }
      return tableHachage;
    }
}

25.5.3 / L'interface Iterator

L'interface Iterator se substitue à l'interface Enumeration dans le cadre des collections Java.

L'interface Iterator se distingue d'Enumeration par une nouvelle fonctionnalité, consistant à supprimer un élément de la collection sous-jacente.

Une autre différence réside dans le raccourcissement des noms de méthode.

Les méthodes
boolean hasNext()
retourne true si l'itérateur a encore des éléments.
Object next()
retourne le prochain élément de l'itérateur.
void remove()
supprime de la collection sous-jacente le dernier élément retourné par l'itérateur.

Le fonctionnement de l'itérateur consiste dans un premier temps, à récupérer un objet Iterator par l'intermédiaire de la méthode iterator() disponible dans toutes les classes implémentant les interfaces List et Set, telles que AbstractList, ArrayList, LinkedList, Vector, AbstractSet, HashSet, LinkedHashSet et TreeSet. Puis à l'aide d'une boucle, dont la condition d'arrêt est une expression faisant appel à la méthode hasNext() afin de vérifier si l'itérateur possède encore des éléments, récupérer dans un objet, les éléments de l'itérateur en utilisant la méthode next().

Iterator iterateur = collection.iterator();
for(Object element = null; iterateur.hasNext();){
    element = iterateur.next();
    System.out.println(element.toString());
}

Quant à la méthode remove(), il faut l'utiliser après que l'itérateur ait accédé à un élément. Dans le cas contraire, une exception java.lang.IllegalStateException serait levée. Si l'opération de suppression n'est pas supportée par l'implémentation d'Iterator, l'exception UnsupportedOperationException pourrait être lancée.

//iterateur.remove(); EXCEPTION !
element = iterateur.next();
iterateur.remove();
Exemple [voir]
import java.util.Iterator;
import java.util.LinkedList;

public class CollectionIterateur {
    public static void main(String[] args) {
      LinkedList liste = creerListeChainee();
      System.out.println("Taille de la liste avant itération : " + liste.size());
      Iterator iterateur = liste.iterator();
      System.out.println("Type reference\tValeur");
      while (iterateur.hasNext()) {
        Object element = iterateur.next();
        System.out.println(element.getClass().getName() + "\t" + element.toString());
        iterateur.remove();
      }
      System.out.println("Taille de la liste après itération : " + liste.size());
    }
    public static LinkedList creerListeChainee(){
      String[] joursSemaine = {"lundi", "mardi", "mercredi", "jeudi", 
                               "vendredi", "samedi", "dimanche"};
        LinkedList listeChainee = new LinkedList();
      for(int i = 0; i < joursSemaine.length; i++){
        listeChainee.add(joursSemaine[i]);
      }
      return listeChainee; 
    }
}

25.5.4 / L'interface ListIterator

L'interface ListIterator est un itérateur de liste qui permet de traverser une liste dans plusieurs directions, de modifierla liste durant l'itération et d'obtenir la position courante de l'itérateur dans la liste.

while(iterateurListe.hasNext()) {
    listeItertateur.next();
}
// ou
while(iterateurListe.hasPrevious()) {
    listeItertateur.previous();
}

Les classes implémentant l'interface ListIterator sont des collections implémentant l'interface List telles que AbstractList, ArrayList, LinkedList et Vector.

Les méthodes
void add(Object o)
insère un élément donné au sein de la liste.
boolean hasNext()
retourne true si l'itérateur de liste ne rencontre plus d'élément durant une itération descendante.
boolean hasPrevious()
retourne true si l'itérateur de liste ne rencontre plus d'élément durant une itération ascendante.
Object next()
retourne le prochain élément de la liste.
int nextIndex()
retourne l'index du prochain élément à retourner.
Object previous()
retourne l'élément précédent de la liste.
int previousIndex()
retourne l'index du précédent élément à retourner.
void remove()
supprime de la collection sous-jacente le dernier élément retourné par l'itérateur de liste.
void set(Object o)
remplace le dernier élément retourné par l'itérateur de liste, par l'élément spécifié.

Un objet ListIterator ne possède aucun élément courant. Sa position de curseur se trouve toujours entre l'élément qui serait retourné lors de l'appel de la méthode previous() et l'élément qui serait retourné par la méthode next().

Une position de curseur égale à zéro, signifie que le curseur de l'itérateur de liste pointe la position située juste avant le premier élément de la liste sous-jacente. Ainsi, Une position égale à 1, indique que le curseur est positionné entre le premier élément et le second.

Exemple [voir]
import java.util.ListIterator;
import java.util.ArrayList;

public class CollectionIterateurDeListe {
    public static void main(String[] args) {
      String[] joursSemaine = {"lundi", "mardi", "mercredi", "jeudi", 
                               "vendredi", "samedi", "dimanche"};
      String[] daysOfWeek = {"sunday", "monday", "tuesday", "wednesday", 
                             "thursday", "friday", "saturday"};

      ArrayList liste = creerTableau(joursSemaine);
      ArrayList liste2 = creerTableau(daysOfWeek);
      ListIterator iterateur = liste.listIterator();
      ListIterator iterateur2 = liste2.listIterator(liste2.size());
      Object element;
      while(iterateur.hasNext()){
        element = iterateur.next();
        iterateur.set(iterateur2.previous());
        System.out.println(iterateur.previousIndex() 
                                              + "\t" + element.toString());
      }
      while(iterateur.hasPrevious()){
        element = iterateur.previous();
        System.out.println(iterateur.nextIndex() 
                                              + "\t" + element.toString());
      }
    }
    public static ArrayList creerTableau(String[] obj){
      ArrayList tableau = new ArrayList();
      for(int i = 0; i < obj.length; i++){
        tableau.add(obj[i]);
      }
      return tableau;
    }
}

25.5.5 / L'interface java.lang.Comparable

L'interface java.lang.Comparable impose un ordre global sur les instances des classes implémentant cette interface.

Une seule méthode est contenue dans l'interface Comparable. Il s'agît de la méthode compareTo() ayant pour fonction de comparer un objet passé en argument à l'instance de classe courante.

public interface Comparable {
    public int compareTo(Object o);
}

L'ordre imposé par cette interface se réfère à l'ordre naturel de la classe et la méthode compareTo() de la classe se réfère également à sa méthode de comparaison naturelle.

Les listes et les tableaux d'objets qui implémentent l'interface Comparable peuvent être respectivement triés automatiquement par les méthodes Collections.sort() et Arrays.sort(). De plus, de tels objets peuvent être utilisés comme clés ou comme éléments dans, respectivement, une collection Map ou Set triée, sans avoir besoin de spécifier un objet Comparator.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class CollectionListe {
  public static void main(String[] args) {
    // Video est un classe définie plus bas.
    Video tableau[] = {
      new Video("Le jour le plus long", "Ken Annakin", 1962),
      new Video("Un pont trop loin", "Richard Attenborough", 1977),
      new Video("Platoon", "Oliver Stone", 1986),
      new Video("Full metal jacket", "Stanley Kubrik", 1987),
      new Video("La ligne rouge", "Terrence Malick", 1998),
      new Video("The patriot", "Roland Emmerich", 2000)
    };
    // ORDRE_DATE est un comparateur défini plus bas.
    Arrays.sort(tableau, ORDRE_DATE);
    for(int i = 0; i < tableau.length; i++)
      System.out.print(tableau[i].toString() + " ");
    List liste = Arrays.asList(tableau);
    Collections.sort(liste);
    System.out.println(liste);
  }
}

L'ordre naturel pour une classe est dit consistant avec equals(), si et seulement si (e1.compareTo((Object)e2) == 0) possède la même valeur booléenne que e1.equals((Object)e2) pour chacun des éléments de cette classe.

Etant donné que des collections triées (SortedSet ou SortedMap) risquent de se comporter anormalement, il est fortement recommandé que l'ordre naturel soit consistant avec equals().

La relation qui définit l'ordre naturel sur une classe donnée est :

{(x, y) tel que x.compareTo((Object)y) <= 0}

Le quotient pour l'ordre total est :

{(x, y) tel que x.compareTo((Object)y) == 0}

Cela suit directement du contrat pour la méthode compareTo(), que le quotient soit une relation d'équivalence sur la classe et que l'ordre naturel soit un ordre global sur cette classe. Lorsque l'ordre naturel d'une classe est dit consistant avec equals(), cela signifie que le quotient de l'ordre naturel est la relation d'équivalence définie par la méthode equals() de cette classe.

{(x, y) tel que x.equals((Object)y)}

Si l'objet spécifié ne peut être comparé à l'objet spécifié, la méthode compareTo() lancera une exception ClassCastException.

La valeur null n'étant pas une instance de classe, une exception NullPointerException sera levée si une tentative de comparaison est tentée.

// provoque une exception
boolean res = objet.compareTo(null);

La méthode compareTo() suite à la comparaison de l'objet passé en argument par rapport à l'objet courant, retourne une valeur entière qui indique l'ordre de ces objets.

L'implémenteur doit s'assurer des règles suivantes :

Bien que la dernière règle ne soit pas strictement requise, il est fortement recommandée de l'appliquer.

La notation sgn(expression) désigne la fonction mathématique signum(), laquelle est définie pour retourner les valeurs -1, 0 et 1 pour respectivement toutes les valeurs négatives, nulles et positives renvoyées par l'expression.

Exemple [voir]
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = 
                      realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }

  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }

  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    return true;
  }

  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

// Classe mettant en oeuvre la classe Video
import java.util.Comparator;
import java.util.TreeSet;

public class CollectionComparable {
  public static void main(String[] args) {
    TreeSet t = new TreeSet();
    t.add(new Video("Le jour le plus long", "Ken Annakin", 1962));
    t.add(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    t.add(new Video("Platoon", "Oliver Stone", 1986));
    t.add(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    t.add(new Video("La ligne rouge", "Terrence Malick", 1998));
    t.add(new Video("The patriot", "Roland Emmerich", 2000));
    System.out.println("Tri par titre :\n" + t);
  }
}

25.5.6 / L'interface Comparator

L'interface Comparator permet de réaliser une comparaison qui impose un ordre global sur les éléments d'une collection. Les comparateurs peuvent être passés à une méthode de tri, telle que Collections.sort() ou Arrays.sort(), dans le but d'appliquer un contrôle précis sur l'ordre de tri. Les comparateurs peuvent aussi être utilisés pour contrôler l'ordre de certaines structures de données, telles que les objets TreeSet et TreeMap.

L'ordre imposé par un objet Comparator sur un ensemble d'éléments est dit être consistant avec equals() si et seulement si (compare((Object)e1, (Object)e2)==0) retourne la même valeur booléenne que l'expression e1.equals((Object)e2) pour chaque e1 et e2 dans l'ensemble précité.

Cependant des précautions devraient être prises, lors de l'utilisation d'un comparateur capable d'imposer un ordre inconsistant avec equals() ordonnant une collection TreeSet ou TreeMap. En supposant qu'un ensemble SortedSet ou SortedMap avec un comparateur explicite sont utilisés avec les éléments ou les clés extraits d'un ensemble, l'ordre imposé par le comparateur sur l'ensemble précité est inconsistant avec equals() et la collection triée se comportera d'une manière étrange. En particulier, elle violerait le contrat général des collections Set ou Map, lesquelles sont définies en terme d'égalité.

Par exemple, si l'ajout de deux clés a et b, tel que (a.equals((Object)b) && c.compare((Object)a, (Object)b) != 0) dans un ensemble SortedSet avec un comparateur, la seconde opération d'ajout retournerait la valeur booléenne false, car les deux clés sont équivalentes à partir de la perspective de l'objet SortedSet.

Il est approprié que les comparateurs implémentent l'interface java.io.Serializable, étant donné qu'ils peuvent être utilisés comme méthode d'ordonnancement dans des structures de données sérialisables, à l'image des objets Treeset et TreeMap. Les structures de données correctement ordonnées pourront être sérialiser avec succès, c'est pourquoi, les comparateurs doivent implémenter l'interface Serializable.

La relation qui définit l'ordre global qu'un comparateur donné impose à un ensemble d'objets S est :

{(x, y) tel que c.compare((Object)x, (Object)y) <= 0}

Le quotient pour l'ordre total est :

{(x, y) tel que c.compare((Object)x, (Object)y) == 0}

Cela découle directement du contrat pour la méthode compare(), que le quotient soit une relation d'équivalence sur S et que l'ordre naturel soit un ordre global sur S. Lorsque l'ordre imposé par la comparateur sur l'ensemble est dit consistant avec equals(), cela signifie que le quotient de l'ordre naturel est la relation d'équivalence définie par les méthodes equals() des objets.

{(x, y) tel que x.equals((Object)y)}

Le seul constructeur Comparator() s'utilise avec une classe anonyme chargée de définir la méthode comparaison.

  Comparator comparateur = new Comparator() {
    public int compare(Object o1, Object o2){
      // instructions...
    }
  };
Les méthodes
int compare(Object o1, Object o2)
compare les deux objets pour indiquer leur ordre.
boolean equals(Object obj)
indique si l'objet spécifié est égal à l'implémentation de l'interface Comparator.

La méthode compare() retourne une valeur entière indiquant l'ordre des objets soumis.

int res = comparateur.compare(arg1, arg2);

L'implémenteur doit s'assurer des règles suivantes :

Bien que la dernière règle ne soit pas strictement requise, il est fortement recommandée de l'appliquer.

La méthode equals() doit retourner la valeur true, si et seulement si l'objet spécifié est aussi un comparateur et qu'il impose le même ordre que l'objet Comparator courant. Ainsi, comp1.equals(comp2) implique que sgn(comp1.compare(obj1, obj2)) == sgn(comp2.compare(obj1, obj2)) pour chaque référence d'objet obj1 et obj2.

Comparator comparateur1 = new Comparateur();
Comparator comparateur2 = new AutreComparateur();
boolean res = comparateur1.equals(comparateur2);

La notation sgn(expression) désigne la fonction mathématique signum(), laquelle est définie pour retourner les valeurs -1, 0 et 1 pour respectivement toutes les valeurs négatives, nulles et positives renvoyées par l'expression.

Exemple [voir]
import java.util.Comparator;
import java.util.TreeSet;

public class CollectionComparator {
  static final Comparator ORDRE_DATE = new Comparator() {
    public int compare(Object o1, Object o2){
      if(!(o1 instanceof Video))
        throw new ClassCastException();
      return (new Integer(((Video)o1).obtenirAnnee())).compareTo(
                        new Integer(((Video)o2).obtenirAnnee()));
    }
  };
  static final Comparator ORDRE_REALISATEUR = new Comparator() {
    public int compare(Object o1, Object o2){
      if(!(o1 instanceof Video))
        throw new ClassCastException();
      return (((Video)o1).obtenirRealisateur()).compareTo(
                        ((Video)o2).obtenirRealisateur());
    }
  };
  public static void main(String[] args) {
    TreeSet t = new TreeSet();
    t.add(new Video("Le jour le plus long", "Ken Annakin", 1962));
    t.add(new Video("Un pont trop loin", "Richard Attenborough", 1977));
    t.add(new Video("Platoon", "Oliver Stone", 1986));
    t.add(new Video("Full metal jacket", "Stanley Kubrik", 1987));
    t.add(new Video("La ligne rouge", "Terrence Malick", 1998));
    t.add(new Video("The patriot", "Roland Emmerich", 2000));
    System.out.println("Tri par titre :\n" + t);    
    TreeSet tr = new TreeSet(ORDRE_REALISATEUR);
    tr.addAll(t);
    System.out.println("\nTri par réalisateur :\n" + tr);
    TreeSet ta = new TreeSet(ORDRE_DATE);
    ta.addAll(t);
    System.out.println("\nTri par année :\n" + ta);
  }
}

//Classe Video implémentant l'interface java.lang.Comparable
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

25.5.7 / L'interface Map.Entry

L'interface statique Map.Entry est imbriquée dans l'interface Map. Elle représente une entrée, c'est-à-dire une paire clé/valeur, d'un objet Map.

La méthode Map.entrySet() retourne un objet Set, lequel contient les paires clé/valeur de la collection Map sous-jacente, sous la forme d'objets Map.Entry.

Set ensemble = table.entrySet();

Les objets Map.Entry ne sont valides que durant l'itération. Plus formellement, le comportement d'une entrée de collection Map, n'est pas défini si l'objet Map support a été modifié après que l'entrée ait été retournée par l'itérateur, excepté par l'opération remove() propre à l'itérateur, ou par l'opération setValue() sur une entrée retournée par l'itérateur.

Les méthodes
boolean equals(Object o)
teste l'égalité entre l'objet spécifié et l'objet Map.Entry.
Object getKey()
retourne la clé correspondant à l'entrée en cours.
Object getValue()
retourne la valeur correspondant à l'entrée en cours.
int hashCode()
retourne le code de hachage pour l'entrée en cours.
Object setValue(Object value)
fixe la valeur de l'entrée en cours avec l'objet spécifié.
Exemple [voir]
import java.util.Map;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

public class CollectionMapEntry {
  public static void main(String[] args) {
    Hashtable table = new Hashtable();
    for(int i = 0; i < 26; i++){
      char car = (char)('A' + i);
      table.put(new Integer(i), new Character(car));
    }
    System.out.println("Taille de la table de hachage : " + table.size());
    Set ensemble = table.entrySet();
    Iterator i = ensemble.iterator();
    while(i.hasNext()){
      Object o = i.next();
      System.out.println(o.getClass().getName() + "\t" + o.toString());
      Map.Entry entree = (Map.Entry)o;
      Character val = entree.getValue();
      System.out.print("\t" + entree.getKey() + " -> (ancienne) " + val + " (nouvelle) ");
      entree.setValue(new Character((char)(valeur.charValue() + 32)));
      System.out.println(entree.getValue());
    }
  }
}

25.5.8 / La classe Arrays

La classe Arrays contient diverses méthodes destinées à manipuler les tableaux Java.

La classe Arrays est statique et donc ne peut être instanciée. Elle contient essentiellement des méthodes statiques.

[Type valeur = ]Arrays.methodeStatique(tableau[, autreArguments]);

Toutes les méthodes de cette classe sont susceptibles de lever une exception NullPointerException, si le tableau sur lequel doit s'appliquer une opération, est la valeur null.

int[] tableau = null;
Arrays.methodeStatique(tableau, args);
// L'exception NullPointerException est levée par la méthode

Les méthodes permettent notamment d'effectuer des recherches et du tri dans un tableau.

Les méthodes sort() sont capables de trier les éléments du tableau spécifié, selon un ordre ascendant. Tous les éléments ayant un type primitif numérique (byte, short, int, long, float et double) sont triés numériquement, y compris les caractères (char). Pour chaque type, il existe deux méthodes, la première triant tout le tableau, la seconde appliquant le tri à un intervalle donné du tableau.

int[] tableau = {8, 1, 6, 10, 9, 3, 7};
Arrays.sort(tableau);
// tri de l'intervalle [2, 5] soit {6, 1, 10, 9, 3}
Arrays.sort(tableau, 2, 5);

En ce qui concerne les objets, le tri peut être réalisé au moyen de quatre méthodes classée dans deux genres. La première catégorie applique un tri en accord avec l'ordre naturel des éléments, la seconde par rapport à un objet Comparator spécifié.

Dans le premier cas, tous les éléments du tableau doivent impérativement implémenter l'interface Comparable et doivent être mutuellement comparable, c'est-à-dire, qu'une exception ClassCastException ne doit pas être levée lors de l'appel de la méthode compareTo().

boolean res = elt1.compareTo(elt2);

Dans le second cas, un comparateur est passé en argument avec le tableau, afin d'indiquer à la méthode sort() le mode de tri à mettre en oeuvre sur ce tableau. Le comparateur spécifié inclus un algorithme de comparaison spécifique au type référence des objets du tableau. En outre, il est nécessaire que tous les éléments du tableau soient mutuellement comparables, sans quoi une exception ClassCastException risquerait d'être levée lors d'une tentative de comparaison.

import java.util.Arrays;
import java.util.Comparator;

public class programme {
  public static void main(String[] args) {
    Video[] tabObjets = {
      new Video("Voyage au bout de l'enfer", "Michael Cimino", 1978),
      new Video("Le jour le plus long", "Ken Annakin", 1962),
      new Video("Un pont trop loin", "Richard Attenborough", 1977),
      new Video("Platoon", "Oliver Stone", 1986),
      new Video("Full metal jacket", "Stanley Kubrik", 1987),
      new Video("La ligne rouge", "Terrence Malick", 1998),
      new Video("The patriot", "Roland Emmerich", 2000),
      new Video("Outrages", "Brian De Palma", 1990),
      new Video("Paris brûle-t-il ?", "René Clément", 1966),
      new Video("Tora ! Tora ! Tora !", "Richard Fleischer", 1970),
      new Video("Guerre et Paix", "King Vidor", 1956),
      new Video("Apocalypse now", "Francis Ford Coppola", 1979)
    };
    System.out.println("Tableau des objets Video :");
    for(int i = 0; i < tabObjets.length; i++)
      System.out.println(i + "\t: " + tabObjets[i]);

    System.out.println("Tri des objets par année :");
    Comparator comparateur = new Comparator(){
      public int compare(Object o1, Object o2){
        if(!(o1 instanceof Video))
        throw new ClassCastException();
        return (new Integer(((Video)o1).obtenirAnnee())).compareTo(
                  new Integer(((Video)o2).obtenirAnnee()));
      }
    };
    Arrays.sort(tabObjets, comparateur);
    for(int i = 0; i < tabObjets.length; i++)
      System.out.println(i + "\t: " + tabObjets[i]);
    
  }
}

A l'instar des méthodes de tri pour les types primitifs, il est possible également de spécifier un intervalle d'éléments à trier, au sein du tableau.

Arrays.sort(tabObjets, 3, 6, comparateur);

Les méthodes binarySearch() sont utilisées pour accomplir une recherche d'un élément spécifié au sein d'un tableau cible après que ce dernier eut été trié par la méthode sort() appropriée. En cas de réussite de la recherche, l'index de l'élément dans le tableau est retourné, dans le cas contraire, la valeur -1 est retournée. De même que pour les méthodes sort(), il existe autant de déclinaisons de binarySearch(), qu'il existe de types primitifs et du type référence Object.

char[] tableau = {'a', 'r', 'k', 'q', 'o', 's'};
Arrays.sort(tableau);
// tableau = {'a', 'k', 'o', 'q', 'r', 's'}
int res = Arrays.binarySearch(tableau, 'k');

Les objets peuvent être recherchés en fonction de leur ordre naturel ou par rapport à un comparateur fourni. Dans les deux cas, il est impératif que les éléments soient mutuellement comparables puisqu'ils ne pourraient être préalablement triés par la méthode sort().

Les méthodes fill() affectent un valeur donnée à tous ou un intervalle des éléments d'un tableau. Chaque type d'élément possède un jeu de méthodes à l'instar des méthodes précitées.

double tableau = new double[10];
Arrays.fill(tableau, 0.0);

String[] tableau = new String[100];
Arrays.fill(tableau, "");

Les méthodes equals() ont la fonction de tester l'égalité entre deux tableaux de même type. Si l'égalité des tableaux est effectives, la méthode equals() retourne true, sinon elle renvoie false. Une égalité effective est tributaire d'un nombre d'éléments équivalent et d'une correspondance stricte entre les paires d'éléments (ta[1] = tb[1], ta[2] = tb[2], etc..). Ainsi, pour assurer un même ordre aux deux tableaux à comparer, il peut être opportun de les trier préalablement.

float[] tab1 = {0.2f, 0.5f, 0.9f, 1.54f, 7.2f, 4.5f};
float[] tab2 = {0.2f, 0.5f, 0.9f, 1.54f, 7.2f, 4.5f};
float[] tab3 = {1.54f, 7.2f, 0.2f, 0.9f, 0.5f, 4.5f};
boolean res = Arrays.equals(tab1, tab2); // retourne true
boolean res = Arrays.equals(tab1, tab3); // retourne false
Arrays.sort(tab3);
boolean res = Arrays.equals(tab1, tab3); // retourne true

La méthode asList() constitue un pont entre les tableaux et les collections Java. En effet, cette méthode retourne une liste dont les éléments seront ceux du tableau spécifié en argument.

List liste = Arrays.asList(tableau);
Exemple [voir]
import java.util.Arrays;
import java.util.Comparator;

public class programme {
  public static void main(String[] args) {
    int[] tabEntiers = {10, 5, 2, 8, 6, 1, 78, 45, 12, 9};
    Video[] tabObjets = {
      new Video("Voyage au bout de l'enfer", "Michael Cimino", 1978),
      new Video("Le jour le plus long", "Ken Annakin", 1962),
      new Video("Un pont trop loin", "Richard Attenborough", 1977),
      new Video("Platoon", "Oliver Stone", 1986),
      new Video("Full metal jacket", "Stanley Kubrik", 1987),
      new Video("La ligne rouge", "Terrence Malick", 1998),
      new Video("The patriot", "Roland Emmerich", 2000),
      new Video("Outrages", "Brian De Palma", 1990),
      new Video("Paris brûle-t-il ?", "René Clément", 1966),
      new Video("Tora ! Tora ! Tora !", "Richard Fleischer", 1970),
      new Video("Guerre et Paix", "King Vidor", 1956),
      new Video("Apocalypse now", "Francis Ford Coppola", 1979)
    };
    Video[] tabCopie = new Video[tabObjets.length];
    for(int i = 0; i < tabObjets.length; i++)
      tabCopie[i] = tabObjets[i];
    
    if(Arrays.equals(tabObjets, tabCopie)){
      System.out.println("Les deux tableaux sont identiques !");
    }
        
    System.out.println("Tableau de valeurs entières :");
    for(int i = 0; i < tabEntiers.length; i++)
      System.out.println(i + "\t: " + tabEntiers[i]);
    System.out.println("Tableau des objets Video :");
    for(int i = 0; i < tabObjets.length; i++)
      System.out.println(i + "\t: " + tabObjets[i]);
    
    System.out.println("Tri numériques des valeurs entières :");
    Arrays.sort(tabEntiers);
    for(int i = 0; i < tabEntiers.length; i++)
      System.out.println(i + "\t: " + tabEntiers[i]);

    System.out.println("Tri des objets par année :");
    Comparator comparateur = new Comparator(){
      public int compare(Object o1, Object o2){
        if(!(o1 instanceof Video))
        throw new ClassCastException();
        return (new Integer(((Video)o1).obtenirAnnee())).compareTo(
                  new Integer(((Video)o2).obtenirAnnee()));
      }
    };
    Arrays.sort(tabObjets, comparateur);
    for(int i = 0; i < tabObjets.length; i++)
      System.out.println(i + "\t: " + tabObjets[i]);
    
    System.out.println("Affichage de la copie de tabObjets :");
    for(int i = 0; i < tabCopie.length; i++)
      System.out.println(i + "\t: " + tabCopie[i]);

    if(!Arrays.equals(tabObjets, tabCopie)){
      System.out.println("Les deux tableaux ne sont plus identiques !");
    }
  }
}

// Classe Video
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Video implements Comparable {
  private String titre, realisateur;
  private int annee;
  
  public Video(){
    this("Inconnu", "Inconnu", 0);
  }
    public Video (String[] infos) {
      this(infos[0], infos[1], Integer.parseInt(infos[3]));
    }
    public Video (String titre, String realisateur){
      this(titre, realisateur, (new GregorianCalendar()).get(Calendar.YEAR));
    }
  public Video (String titre, String realisateur, String annee){
    this(titre, realisateur, Integer.parseInt(annee));
  }
  public Video (String titre, String realisateur, int annee){
    if (titre == null || realisateur == null)
      throw new NullPointerException();
    this.titre = titre;
    this.realisateur = realisateur;
    this.annee = annee;
  }
  
  public String obtenirTitre(){
    return this.titre;
  }
  public String obtenirRealisateur(){
    return this.realisateur;
  }
  public int obtenirAnnee(){
    return this.annee;
  }

  public void fournirTitre(String titre){
    this.titre = titre;
  }
  public void fournirRealisateur(String realisateur){
    this.realisateur = realisateur;
  }
  public void fournirAnnee(int annee){
    this.annee = annee;
  }
  
  public int hashCode(){
    return annee * titre.hashCode() + realisateur.hashCode();
  }
  
  public boolean equals(Object o){
    if(!(o instanceof Video))
      return false;
    Video v = (Video)o;
    if(this.hashCode() == v.hashCode())
      return true;
    return false;
  }
  
  public int compareTo(Object o){
    if(!(o instanceof Video))
      throw new ClassCastException();
    Video v = (Video)o;
    int comparaison;
    if((comparaison = titre.compareTo(v.obtenirTitre())) != 0)
      return  comparaison;
    else if((comparaison = realisateur.compareTo(v.obtenirRealisateur())) != 0)
      return comparaison;
    else
      return (new Integer(annee)).compareTo(new Integer(v.obtenirAnnee()));
  }
  
  public String toString(){
    StringBuffer res = new StringBuffer("[");
    res.append(titre);
    res.append(", ");
    res.append(realisateur);
    res.append(", ");
    res.append(annee);
    return res.append("]").toString();
  }
}

26 / Le fichier source

Les fichiers sources contiennent une série d'instructions permettant de mettre en oeuvre un programme.

L'ensemble d'instructions se compose de la déclarations de paquetages, suivies des instructions d'importation et enfin des déclarations de classes et d'interfaces.

// fichier source : IdentificateurPrincipal.java
[package arborescence_paquetage;]

[import arborescence_paquetage.NomClasse;]
[...]
[import arborescence_paquetageN.NomClasseN;]

public modificateur class IdentificateurPrincipal {
  //Définition de la classe
}
[...]
[modificateur class IdentificateurN {
  //Définition de la classe N
}]
[modificateur interface IIdentificateur {
  //Définition de l'interface
}]
[...]
[modificateur interface IIdentificateurN {
  //Définition de l'interface N
}]

L'ordre de ces instructions doit obligatoirement suivre l'énumération précitée.

Toutefois, les instructions de paquetage et d'importation peuvent ne pas apparaître. Dans ce cas, cela signifie respectivement que Java s'occupera lui-même de déclarer un paquetage par défaut au fichier source et que ce dernier ne nécessite pas de classes importées pour être correctement compilé.

En ce qui concerne les déclarations de classes et d'interfaces, il est possible de ne définir au moins qu'une seule classe ou une seule interface dans le fichier source.

Une seule classe ou interface peut être déclarée à l'aide du modificateur d'accès public dans un fichier source.

De plus, le fichier source doit posséder exactement le même identificateur que la classe ou l'interface publique.
Par convention, le nom d'une interface commence par un I majuscule, le fichier source suivra la même direction.

Si d'autres classes évidemment non publiques sont déclarées dans un fichier source, elles ne pourront être utilisées que dans d'autres fichiers appartenant au même paquetage que leur propre fichier.

Par ailleurs, le nom du fichier source doit posséder l'extension .java. Après une compilation réussie, l'extension du nouveau fichier généré sera .class.

javac IdentificateurPrincipal.java
//La ligne de commande de compilation générera
//le fichier IdentificateurPrincipal.class

27 / Le système de fichiers

Le langage Java dispose de nombreuses bibliothèques concourant à la gestion des fichiers sur une unité de stockage locale ou distante.
Effectivement, il est possible de créer, de modifier, de consulter ou de supprimer des fichiers par l'intermédiaire de plusieurs classes comprises dans le paquetage java.io (io : input/output).

Cependant, la gestion des fichiers devient problématique lorsque la portabilité contraint une application Java à fonctionner d'une manière identique sur l'ensemble des plateformes cibles. Ainsi, des problèmes de codage de caractères et de convention de nommage des chemins devront être prises en considération afin d'assurer le bon fonctionnement du programme sur les plateformers sous-jacentes.

La gestion des fichiers nécessite l'emploi de certaines classes et en particulier java.io.File et les classes de flux telles que java.io.FileReader, java.io.FileReader, java.io.FileInputStream et java.io.FileOutputStream.

Dans un premier temps, il faut créer une instance d'une classe File, laquelle sera passée en argument à un constructeur de flux binaire ou de caractères et sortant ou entrant. Cette première étape permet la création d'un chemin abstrait vers un fichier et l'ouverture d'un canal de transmission vers ce fichier. A partir de ce moment, il devient possible de lire ou écrire dans le fichier.

import java.io.*;
class GestionFichier {
    public static void main(String args[]) throws IOException {
        File cheminAbstraitEntree = new File("poeme.txt");
        FileReader fluxLectureTexte = 
                                                        new FileReader(cheminAbstraitEntree);
        int car;
        StringBuffer contenu = new StringBuffer();
        while((car = fluxLectureTexte.read()) != -1){
            System.out.print ((char)car);
            contenu.append((char)car);
        }
        fluxLectureTexte.close();

        File cheminAbstraitSortie = new File("poeme_copie.txt");
        FileWriter fluxEcritureTexte = 
                                                      new FileWriter(cheminAbstraitSortie);
        fluxEcritureTexte.write(contenu.toString());
        fluxEcritureTexte.close();
    }
}

Dans le cas de la lecture de fichier, seule un accès caractères par caractères et possible par l'intermédiaire du flux FileReader, ce qui n'est certainement pas très pratique pour le traitement d'un fichier. Ainsi, une seconde étape permet de placer en mémoire tampon les caractères lus par le flux par le truchement de la classe BufferedReader.

import java.io.*;
class GestionFichier {
    public static void main(String args[]) throws IOException {
        File cheminAbstraitEntree = new File("poeme.txt");
        FileReader fluxLectureTexte = 
                                          new FileReader(cheminAbstraitEntree);
        BufferedReader tamponLecture = 
                                          new BufferedReader(fluxLectureTexte);
        String ligne;
        StringBuffer contenu = new StringBuffer();
        while((ligne = tamponLecture.readLine()) != null){
            System.out.print (ligne);
            contenu.append(ligne);
            contenu.append("\r\n");
        }
        tamponLecture.close();
        fluxLectureTexte.close();

        File cheminAbstraitSortie = new File("poeme_copie.txt");
        FileWriter fluxEcritureTexte = 
                                            new FileWriter(cheminAbstraitSortie);
        BufferedWriter tamponEcriture = 
                                            new BufferedWriter(fluxEcritureTexte);
        tamponEcriture.write(contenu.toString());
        tamponEcriture.flush();
        tamponEcriture.close();
        fluxEcritureTexte.close();
    }
}

L'utilisation d'une mémoire tampon associée à un flux améliore sensiblement les performances d'accès aux fichiers. C'est pourquoi, il est recommandée d'utiliser les classes BufferedWriter et BufferedReader, aussi bien avec les flux sortants qu'avec les flux entrants. Par ailleurs, des fonctionnalités supplémentaires sont proposées telles que la lecture par lignes (readLine()) et l'écriture d'un séparateur de lignes (newLine()).

Précédemment, des flux réservés aux caractères ont été appliqués sur des fichiers texte, dans l'exemple ci-dessous, des flux binaires permettent de travailler sur un fichier constitué d'une séquence d'octets (bytes), en l'occurrence une image GIF (Graphic Interchange Format).

import java.io.*;
import java.util.*;
class GestionFichier {
    public static void main(String args[]) throws IOException {
        File cheminAbstraitEntree = new File("java.gif");
        FileInputStream fluxLectureBinaire = 
                                     new FileInputStream(cheminAbstraitEntree);
        BufferedInputStream tamponEntree = 
                                     new BufferedInputStream(fluxLectureBinaire);
        int oct;
        Vector contenu = new Vector();
        while((oct = fluxLectureBinaire.read()) != -1){
            System.out.print (oct);
            contenu.add(new Integer(oct));
        }
        fluxLectureBinaire.close();

        File cheminAbstraitSortie = new File("java_copie.gif");
        FileOutputStream fluxEcritureBinaire = 
                                       new FileOutputStream(cheminAbstraitSortie);
        BufferedOutputStream tamponSortie = 
                                       new BufferedOutputStream(fluxEcritureBinaire);
        for(int i = 0; i < contenu.size(); i++)
            fluxEcritureBinaire.write(
                                          ((Integer)contenu.elementAt(i)).byteValue());
        fluxEcritureBinaire.close();
    }
}

Dans le cas des fichiers binaires, il est également possible de lire des données sur un flux en utilisant une mémoire tampon chargée de récupérer une séquence d'octets importantes qui restituera son contenu lors d'appels de la méthode read(). En écriture, le fonctionnement est identique à l'exception du sens du flux et de la méthode, dans ce cas il s'agît de write().

Télécharger l'ensemble des exemples

27.1 / Utilisation de la classe File

La classe java.io.File permet de parcourir le système de fichiers de n'importe quelle pla pateforme.

Il est nécessaire soit d'indiquer au compilateur que les méthodes de la classe File sont susceptibles de lancer des exceptions d'entrées/sorties (throws), soit de mettre en place un dispositif capable d'effectuer un traitement approprié (try... catch...).

import java.io.*;
public class GestionFichier {
  public static void main(String[] args) throws IOException {
    File oChemin = new File();
  }
}

L'instanciation de cette classe représente un chemin abstrait vers un fichier ou un répertoire. A partir de ce chemin, l'objet est capable d'accéder à tous les fichiers et répertoires environnant. C'est-à-dire, que l'objet File peut remonter aux parents (File getParentFile(), String getParent()) jusqu'aux noeuds racines (static File[] listRoots()), à ses frères (File[] getParentFile().listFiles(), string[] getParentFile().list()) et descendre à ses enfants (File[] listFiles(), String[] list()).

import java.io.*;
public class GestionFichier {
  public static void main(String[] args) throws IOException {
    File[] noeudsRacines = File.listRoots();
    for(int i = 0; i < noeudsRacines.length; i++){
      String[] oChemin = noeudsRacines[i].list();
      System.out.println(noeudsRacines[i]);
      if(oChemin != null){
        for(int j = 0; j < oChemin.length; j++){
            System.out.println("\t" + oChemin[j]);
        }
      }
    }
  }
}

Cet objet peut également fournir des informations à son propos, telles que le nom ou le répertoire désigné par l'instance (getName()), le chemin (String getPath()) absolue (String getAbsolutePath()) ou canonique (String getCanonicalPath()), la date de dernière modification (long lastModified()), ainsi que la taille du fichier (long length()).

import java.io.*;
import java.util.*;
public class GestionFichier {
  public static void main(String[] args) throws IOException {
    String chemin = "C:\\java\\projets\\exemple1\\GestionFichier.class";
    File oChemin = new File(chemin);
    File[] oCollection = oChemin.getParentFile().listFiles();
    for(int i = 0; i < oCollection.length; i++){
      System.out.println("Chemin : " + oCollection[i].getPath());
      System.out.println("Nom de la cible : " + oCollection[i].getName());
      System.out.println("Chemin absolu : " 
                                            + oCollection[i].getAbsolutePath());
      System.out.println("Taille du fichier : " + oCollection[i].length());
      System.out.println("Dernière modification : " 
                                            + new Date(oCollection[i].lastModified()));
    }
  }
}

Egalement, des indications sur la cible de l'objet peuvent être livrées par l'intermédiaire de méthodes. De cette manière, il est possible de vérifier si le chemin abstrait existe sur la plateforme sous-jacente (boolean exists()), désigne un fichier (boolean isFile()) ou un répertoire (boolean isDirectory()), ou s'il est caché (isHidden()), si une application peut y lire (boolean canRead()) ou y écrire (boolean canWrite()) ou encore si le chemin est absolu (isAbsolute()).

import java.io.*;
public class GestionFichier {
  public static void main(String[] args){
    try{
      File[] noeudsRacines = File.listRoots();
      afficheContenuRepertoire(noeudsRacines);
    }
    catch(Exception e){
      System.out.println("Une erreur s'est produite dans main()!");
    }
  }
  public static void afficheContenuRepertoire(File[] repertoire){
    try{
      if(repertoire != null){
        for(int i = 0; i < repertoire.length; i++){
          if(repertoire[i].exists()){
            File[] oChemin = repertoire[i].listFiles();
            System.out.println (repertoire[i] + "\t racine");
            for (int j = 0; j < oChemin.length; j++){
              if(oChemin[j].isDirectory()){
                  System.out.println (oChemin[j].getName() + "\t\trepertoire");
              }
              else{
                System.out.print("\t" + oChemin[j].getName());
                System.out.print("\t" + (oChemin[j].isFile() ? "fichier" : ""));
                System.out.print("\t" + (oChemin[j].isHidden() ? "cache" : ""));
                System.out.println("\t" + oChemin[j].length() + " octets");
              }
            }
          }
        }
      }
    }
    catch(Exception e){
      System.out.println("Une erreur s'est produite "
                                                  + "afficheContenuRepertoire() !");
    }
  }
}

D'autre part, un objet File est capable de créer un nouveau fichier (boolean createNewFile()) ou un répertoire (boolean mkdir(), boolean mkdirs()) et d'effacer un fichier ou un répertoire (boolean delete()).

import java.io.*;
public class GestionFichier {
  public static void main(String[] args){
    try{
      if(args.length > 0){
        String arborescence = args[0];
        File repertoire = new File(arborescence);
        if(!repertoire.exists()){
          repertoire.mkdirs();
          System.out.println(arborescence.toString() + " cree...");
        }
      }
    }
    catch(Exception e){
      System.out.println ("Un problème s'est produit " 
                                                    + "dans la méthode main() !");
    }
  }
}

Dans la classe File, plusieurs autres méthodes sont disponibles pour effectuer notamment des comparaisons entre chemins abstraits (boolean equals(), boolean compareTo()), un renommage de la cible de l'objet File (boolean renameTo(File fic)) ou encore la conversion de ce dernier en URI (URI toURI()) ou en URL (URL toURL()).

import java.io.*;
import java.net.*;
public class GestionFichier {
  public static void main(String[] args){
    try{
      File oChemin = new File("index.html");
      File nouveauChemin = new File("accueil.html");
      boolean resultat = oChemin.renameTo(nouveauChemin);
      URL adr_url = oChemin.toURL();
      URI adr_uri = nouveauChemin.toURI();
      System.out.println (oChemin.getPath() + "\n" 
                          + nouveauChemin.getPath() + "\n" 
                          + adr_url.toString() + "\n"
                          + adr_uri.toString());
    }
    catch(Exception e){
      System.out.println ("Un problème s'est produit " 
                                                    + "dans la méthode main() !");
    }
  }
}
Télécharger l'ensemble des exemples

28 / Compression et décompression

La lecture et l'écriture des fichiers compressés aux formats ZIP ou GZIP sont directement gérées par des classes adaptées fournies dans l'API Java. En effet, il suffit d'utiliser les classes appropriées se trouvant dans le paquetage java.util.zip.

import java.util.zip.*;

Pour la compression, on distingue la classe DeflaterOutputStream comprenant également deux sous-classes GZIPOutputStream et ZipOutputStream se chargeant de compresser les données transitant dans le flux, dans un format GZIP et ZIP.

import java.util.zip.*;
import java.io.*;
public class ZIP {
  public static void main(String args[]) throws Exception {
   //Déclaration de l'archive ZIP
   String repertoire = "c:java";
   String archive = "arc.zip";
   File fic = new File(repertoire, archive);
   FileOutputStream flux = new FileOutputStream(fic);
   ZipOutputStream ficZIP = new ZipOutputStream(flux);
   //Méthode de compression DEFLATED ou STORED
   ficZIP.setMethod(ZipOutputStream.DEFLATED);
   //Niveau de compression
   //de 1 (NO_COMPRESSION) à 9 (BEST_COMPRESSION)
   ficZIP.setLevel(Deflater.BEST_COMPRESSION);
   //Déclaration de la première entrée de l'archive
   String entreeFichier = "fichier.txt";
   ZipEntry entreeZIP = new ZipEntry(entreeFichier);
   ficZIP.putNextEntry(entreeZIP);
   //Envoie du contenu de la premiere entrée 
   //dans l'archive à travers un flux
   BufferedOutputStream tamponSortie = 
                                         new BufferedOutputStream(ficZIP);
   DataOutputStream ficDonnees = 
                                         new DataOutputStream(tamponSortie);
   ficDonnees.writeBytes("Un contenu à archiver !");
   ficDonnees.flush();
   //Fermeture de l'archive jusqu'à la prochaîne entrée
   ficZIP.closeEntry();
   System.out.println ("Taille 1ere entree : " 
                                                 + entreeZIP.getCompressedSize());
   //Déclaration de la seconde entrée de l'archive
   String entreeFichier2 = "poeme.rtf";
   ZipEntry entreeZIP2 = new ZipEntry(entreeFichier2);
   ficZIP.putNextEntry(entreeZIP2);
   BufferedOutputStream tamponSortie2 = 
                                        new BufferedOutputStream(ficZIP);
   DataOutputStream ficDonnees2 = 
                                        new DataOutputStream(tamponSortie2);
   ficDonnees2.writeBytes("Un second contenu à archiver !");
   ficDonnees2.flush();
   //Fermeture de l'entrée
   ficZIP.closeEntry();
   System.out.println ("Taille Snde entree : " 
                                                 + entreeZIP2.getCompressedSize());
   //Fermeture de l'archive et des flux
   ficZIP.close();
   ficDonnees.close();
   ficDonnees2.close();
   flux.flush();
   flux.close();
  }
}

Les archives compressées contiennent en général un à plusieurs fichiers. En Java, ces derniers sont représentés par des objets de type référence ZipEntry. Ainsi, à chaque archive ZIP ou GZIP doit être associée au moins une entrée dans laquelle devra être le conteneur de données compressées.

//Création d'un nouvelle entrée
ZipEntry entreeZIP = new ZipEntry(nomFichier);
//Récupération d'une entrée existante
ZipEntry entreeZIP = objZipInputStream.getNextEntry();

L'écriture des données dans l'archive est en général assurée par un objet DataOutputStream qui possède un arsenal de méthodes write() acceptant tous les types primitifs Java, ainsi que les chaînes de caractères.

En ce qui concerne la décompression, on trouve la classe InflaterInputStream possédant deux sous-classes GZIPInputStream et ZipInputStream constituant des filtres de flux pour la lecture de données compressées dans le format GZIP et ZIP.

import java.util.zip.*;
import java.io.*;
public class ZIP {
  public static void main(String args[]) throws Exception {
   //Déclaration de l'archive ZIP
   String repertoire = "c:java";
   String archive = "arc.zip";
   File fic = new File(repertoire, archive);
   FileInputStream flux = new FileInputStream(fic);
   ZipInputStream ficZIP = new ZipInputStream(flux);
   //Récupération de la première entrée
   ZipEntry entreeZIP = ficZIP.getNextEntry();
   BufferedInputStream tamponSortie = 
                                       new BufferedInputStream(ficZIP);
   DataInputStream ficDonnees = 
                                       new DataInputStream(tamponSortie);
   int car;
   System.out.println ("Archive ZIP : " + entreeZIP.getName());
   while((car = ficDonnees.read()) != -1)
       System.out.print ((char) car);
   //Fermeture de l'archive jusqu'à la prochaîne entrée
   ficZIP.closeEntry();
   System.out.println ("");
   //Récupération de la seconde entrée
   ZipEntry entreeZIP2 = ficZIP.getNextEntry();
   BufferedInputStream tamponSortie2 = 
                                         new BufferedInputStream(ficZIP);
   DataInputStream ficDonnees2 = 
                                         new DataInputStream(tamponSortie2);
   System.out.println ("Archive ZIP : " + entreeZIP2.getName());
   while((car = ficDonnees2.read()) != -1)
       System.out.print ((char) car);
   //Fermeture de l'archive
   ficZIP.close();
   ficDonnees.close();
   ficDonnees2.close();
   flux.close();
  }
}

L'objet ZipEntry possède des méthodes capables de fournir des informations sur le fichier compressé.

Méthodes Description
getComments() retourne le commentaire additionnel affecté à l'entrée.
getCompressedSize() retourne la taille du fichier compressé, exprimée en octets.
getMethod() retourne la méthode de compression du fichier (DEFLATED : compression, STORED : sans compression).
getName() retourne le nom associé à l'entrée, soit en général le nom du fichier.
getSize() retourne la taille du fichier non-compressé, exprimé en octets.
getTime() retourne la date (Date + heure) du fichier, exprimé sous la forme d'un entier long.

Les fichiers compressés à l'aide des outils proposés par le paquetage java.util, sont normalement compatibles avec les logiciels de décompression courant. Néanmoins, il arrive parfois qu'avec d'anciennes versions de ces logiciels, la décompression soit impossible.

Télécharger l'ensemble des exemples

29 / Gestion des entrées et sorties standards

Dans la plupart des cas, toutes les applications informatiques doivent être en mesure d'assurer une certaine interactivité entre la machine et un utilisateur. Les entrées provenant du clavier et les sorties affichées à l'écran fournissent un moyen de communication standard.

A cet effet, le langage Java dispose de la classe java.lang.System qui contient plusieurs champs et méthodes. Deux de ces champs sont particulièrement intéressants puisqu'ils fournissent un accès aux flux de sortie et d'entrée standards.

Pour une meilleure efficacité, le champ System.in, en fait un objet InputStream doit passer dans un premier temps par un objet InputStreamReader faisant office de pont entre un flux binaire et un flux de caractères, puis par un objet BufferedReader conservant dans une mémoire tampon un certain nombre de caractères saisis.

import java.io.*;
class InOut {
    public static void main(String args[]) throws IOException {
        BufferedReader entreeClavier = new BufferedReader(
                                       new InputStreamReader(System.in));
        System.out.println ("Saisissez une phrase :");
        String saisie = entreeClavier.readLine();
        System.out.println ("Merci !");
        System.out.println ("Votre phrase est : ");
        System.out.println (saisie);
    }
}

D'autres méthodes sont également utilisables pour récupérer le contenu du flux d'entrée standard, en mettant en oeuvre les méthodes de l'objet InputStream.

import java.io.*;
class InOut {
    public static void main(String args[]) throws IOException {
        byte[] tab = new byte[255];
        //Récupération dans le flux, de 255 caractères.
        int nb = System.in.read(tab, 0, tab.length);
        //Vide le contenu du flux d'entrée standard en
        //déchargeant la totalité des octets disponibles dans le flux.
        System.in.skip(System.in.available());
        String tampon = new String (tab);
        //Affiche la chaîne de caractères saisie 
        //en supprimant le terminateur de ligne.
        System.out.println(tampon.substring(0, 
                tampon.lastIndexOf(System.getProperty("line.separator"))));
    }
}

Désormais, la saisie en mode console résolue, il ne reste plus qu'à contrôler les entrées des utilisateurs afin de les incorporer dans un programme Java. Dans l'exemple ci-dessous, chaque type primitif Java fait l'objet d'un traitement particulier dans le but de récupérer effectivement une valeur correspondant à ce type.

import java.io.*;
import java.util.regex.*;
/**
* La classe Console fournit les moyens à des utilisateurs en mode console,
* de saisir des informations de différents types primitifs Java
* ou de chaînes de caractères.
* Cette classe est capable de lire un nombre d'un type primitif désiré
* et d'en contrôler la validité.
* Cette classe propose également de contrôler des chaînes de caractères
* selon un format précis, à l'image d'adresses email, IP ou URL.
*
* @author Pascal EMMA
* @version 1 du 24/08/2003
* @see java.io.PrintStream
* @see java.lang.System
*/
class Console { /**
* Le champ encodage contient le type d'encodage de caractères
* de la plateforme courante.
*/
public static String encodage = System.getProperty("file.encoding"); /**
* Le champ termintateur contient le le terminateur de lignes
* de la plateforme courante.
*/
private static String terminateur = System.getProperty("line.separator"); /**
* Le champ statique in représente une instance de la classe Console.
*/
public static final Console in = new Console(); /**
* Le champ statique out représente un flux vers la sortie standard.
* @see java.io.PrintStream
*/
public static final PrintStream out = new PrintStream(System.out, true); /**
* La méthode saisirLigne permet de lire une valeur saisie
* par l'utilisateur sur l'entrée standard.
* @return retourne la chaîne de caractères saisie par l'utilisateur
* ou la valeur 'null' dans le cas contraire.
*/
public String saisirLigne(){ try{ BufferedReader entreeClavier = new BufferedReader( new InputStreamReader(System.in)); return entreeClavier.readLine(); } catch (IOException e) { return null; } } /**
* La méthode verifNombre permet de vérifier la validité
* des nombres saisis par l'utilisateur.
* Il est possible de vérifier soit des entiers, soit des réels.
* @param valeur représente la valeur saisie par l'opérateur.
* @param type représente le type de nombres à vérifier.
* <ul>
* <li>La valeur 'reel' permet de tester les nombres réels,</li>
* <li>La valeur 'entier' permet de tester les nombres entiers.</li>
* </ul>
* @return retourne 'true' si la valeur testée est un nombre
* ou 'false' dans le cas contraire.
*/
private boolean verifNombre(String valeur, String type) { String regexp; if(type.equals("entier")) regexp = "[+-]?[0-9]*"; else regexp = "[+-]?[0-9]*[.Ee]?[+-]?[0-9]*"; Pattern modele = Pattern.compile(regexp); Matcher correspondance = modele.matcher(valeur); if(valeur != null && !valeur.equals("") && correspondance.matches()) return true; else return false; } /**
* La méthode saisirLong permet de lire des nombres entiers
* de type primitif 'long'.
* @return retourne une valeur entière de type 'long'.
* Si la valeur saisie par l'opérateur excède les limites du type 'long'
* alors la valeur entière maximum ou minimum selon le cas est retournée.
*/
public long saisirLong(){ double nb = 0; String valeur = saisirLigne(); if(verifNombre(valeur, "entier")) nb = Double.parseDouble(valeur); if(nb < Long.MAX_VALUE && nb > Long.MIN_VALUE) return Long.parseLong(valeur); else if(nb > 0) return Long.MAX_VALUE; else return Long.MIN_VALUE; } /**
* La méthode saisirInt permet de lire des nombres entiers de type primitif 'int'.
* @return retourne une valeur entière de type 'int'.
* Si la valeur saisie par l'opérateur excède les limites du type 'int'
* alors la valeur entière maximum ou minimum selon le cas est retournée.
*/
public int saisirInt(){ long valeur = saisirLong(); if(valeur < Integer.MAX_VALUE && valeur > Integer.MIN_VALUE) return (int)valeur; else if(valeur > 0) return Integer.MAX_VALUE; else return Integer.MIN_VALUE; } /**
* La méthode saisirShort permet de lire des nombres entiers
* de type primitif 'short'.
* @return retourne une valeur entière de type 'short'.
* Si la valeur saisie par l'opérateur excède les limites du type 'short'
* alors la valeur entière maximum ou minimum selon le cas est retournée.
*/
public short saisirShort(){ long valeur = saisirLong(); if(valeur < Short.MAX_VALUE && valeur > Short.MIN_VALUE) return (short)valeur; else if(valeur > 0) return Short.MAX_VALUE; else return Short.MIN_VALUE; } /**
* La méthode saisirByte permet de lire des nombres entiers de type primitif 'byte'.
* @return retourne une valeur entière de type 'byte'.
* Si la valeur saisie par l'opérateur excède les limites du type 'byte'
* alors la valeur entière maximum ou minimum selon le cas est retournée.
*/
public byte saisirByte(){ long valeur = saisirLong(); if(valeur < Byte.MAX_VALUE && valeur > Byte.MIN_VALUE) return (byte)valeur; else if(valeur > 0) return Byte.MAX_VALUE; else return Byte.MIN_VALUE; } /**
* La méthode saisirDouble permet de lire des nombres à virgule flottante
* de type primitif 'double'.
* @return retourne une valeur réelle de type 'double'.
* Si la valeur saisie par l'opérateur excède les limites du type 'double'
* alors la valeur entière maximum ou minimum selon le cas est retournée.
*/
public double saisirDouble(){ double nb = 0; String valeur = saisirLigne(); if(valeur.indexOf(",") != -1) valeur = valeur.replace(',','.'); if(verifNombre(valeur, "reel")) nb = Double.parseDouble(valeur); if(nb < Double.MAX_VALUE && nb > Double.MIN_VALUE) return nb; else if(nb > 0) return Double.MAX_VALUE; else return Double.MIN_VALUE; } /**
* La méthode saisirFloat permet de lire des nombres à virgule flottante
* de type primitif 'float'.
* @return retourne une valeur réelle de type 'float'.
* Si la valeur saisie par l'opérateur excède les limites du type 'float'
* alors la valeur entière maximum ou minimum selon le cas est retournée.
*/
public float saisirFloat(){ double valeur = saisirDouble(); if(valeur < Float.MAX_VALUE && valeur > Float.MIN_VALUE) return (float)valeur; else if(valeur > 0) return Float.MAX_VALUE; else return Float.MIN_VALUE; } /**
* La méthode saisirChar permet de lire un unique caractère
* de type primitif 'char'.
* @return retourne une valeur de type 'char'.
* Si la valeur saisie par l'opérateur est nulle ou vide
* alors la valeur minimum est retournée.
*/
public char saisirChar(){ String valeur = saisirLigne(); if(valeur != null && !valeur.equals("")) return valeur.charAt(0); else return Character.MIN_VALUE; } /**
* La méthode saisirAvecMasque permet de lire une chaîne de caractères
* respectant le format passé en argument.
* @param format représente le masque de format sous la forme
* d'une chaîne de caractères et respectant les standards
* des expressions régulières.
* @return retourne une chaîne de caractères respectant un certain format.
* Si la saisie est erronée, alors la valeur 'null' est retournée.
*/
public String saisirAvecMasque(String format){ String valeur = saisirLigne(); Pattern modele = Pattern.compile(format); Matcher correspondance = modele.matcher(valeur); if(valeur != null && valeur.length() > 0 && correspondance.matches()) return valeur; else return null; } /**
* La méthode saisirEmail permet de lire une chaîne de caractères
* respectant le format d'une adresse email.
* @return retourne une chaîne de caractères représentant une adresse email.
* Si la saisie est erronée, alors la chaîne de caractères
* 'utilisateur@domaine.ext' est retournée.
*/
public String saisirEmail(){ String masque = "^[a-zA-Z]+[a-zA-Z0-9\\._-]*[a-zA-Z0-9]@[a-zA-Z]+" + "[a-zA-Z0-9\\._-]*[a-zA-Z0-9]+\\.[a-zA-Z]{2,4}$"; String valeur = saisirAvecMasque(masque); if(valeur != null) return valeur; else return "utilisateur@domaine.ext"; } /**
* La méthode saisirEmail permet de lire une chaîne de caractères
* respectant le format d'une adresse IP (Internet Protocol).
* @return retourne une chaîne de caractères représentant une adresse IP.
* Si la saisie est erronée, alors la chaîne de caractères
* '000.000.000.000' est retournée.
*/
public String saisirIP(){ String masque = "^[0-2]?[0-9]{0,2}\\.[0-2]?[0-9]{0,2}\\.[0-2]?" + "[0-9]{0,2}\\.[0,2]?[0-9]{0,2}$"; String valeur = saisirAvecMasque(masque); if(valeur != null) return valeur; else return "000.000.000.000"; } /**
* La méthode saisirURL permet de lire une chaîne de caractères
* respectant le format d'une adresse URL (Uniform Resource Locator).
* @return retourne une chaîne de caractères représentant une adresse URL.
* Si la saisie est erronée, alors la chaîne de caractères
* 'protocole://domaine:port/repertoire/
* fichier.ext?champ=valeur&champ2=valeur' est retournée.
*/
public String saisirURL(){ String masque = "^[a-z]*://[a-z0-9\\._-]*(\\.[a-z]{2,4})?" + "(:[0-9]{1,5})?((/[a-z0-9\\.-_ ]*)*(\\.[a-z]{2,4}(\\?.*)?)?)?"; String valeur = saisirAvecMasque(masque); if(valeur != null) return valeur; else return "protocole://domaine:port/repertoire" + "/fichier.ext?champ=valeur&champ2=valeur"; } }
Télécharger l'ensemble des exemples

30 / Les flux (streams)

L'écriture et la lecture de fichiers impliquent l'utilisation des flux (streams). Ces derniers représentent des canaux de transmission de données à partir d'une source ou vers une destination.

Dans ces canaux, deux types d'informations peuvent transiter de l'application vers un fichier ou inversement. Il s'agît de flux de données binaires ou de caractères. Cette distinction permet de traiter différement les fichiers textes dont l'extension peut être .txt, .ini, .log, .xml, etc., et les fichiers binaires comme les images, vidéos, sons et autres...

Les flux sont également capables de faire transiter des informations provenant d'une entrée standard (System.in) telle que le clavier, ou allant vers une sortie standard (System.out) comme l'écran.

Ainsi, on distingue quatre familles de flux appelés également flots :

Les flots d'entrée et de sortie peuvent être utilisés pour n'importe quel périphérique, à l'image d'un écran, d'une imprimante, d'un fichier disque ou du réseau (sortie du programme) et d'un clavier, d'une souris, d'un ordinateur distant ou d'un fichier disque (entrée du programme).

Il est possible de combiner les flux ci-dessus, de cette façon :

Les flux sont unidirectionnels, et possèdent dont seulement une entrée et une sortie. Ils ne peuvent envoyer des informations que dans un seul et unique sens.

Les classes appropriées pour l'utilisation des flux se trouvent dans le paquetage java.io. Il en existe une kyrielle permettant d'accomplir des opérations de lecture et d'écriture adaptées à des besoins spécifiques.

On distingue quatre classes principales dont toutes les autres héritent des représentations et comportements propre à chaque famille.

Héritage des classes de flux sur trois niveaux
InputStreamOutputStream
AudioInputStream
ByteArrayInputStream
FileInputStream
FilterInputStream
BufferedInputStream
CheckedInputStream
CipherInputStream
DataInputStream
DigestInputStream
InflaterInputStream
LineNumberInputStream
ProgressMonitorInputStream
PushbackInputStream
InputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
StringBufferInputStream
ByteArrayOutputStream
FileOutputStream
FilterOutputStream
BufferedOutputStream
CheckedOutputStream
CipherOutputStream
DataOutputStream
DeflaterOutputStream
DigestOutputStream
PrintStream
ObjectOutputStream
OutputStream
PipedOutputStream
ReaderWriter
BufferedReader
LineNumberReader
CharArrayReader
FilterReader
PushbackReader
InputStreamReader
FileReader
PipedReader
StringReader
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
FileWriter
PipedWriter
PrintWriter
StringWriter

30.1 / Utilisation des flux

Le langage Java dispose d'un certain nombre de flux destinés à différentes utilisations d'entrée/sortie.

Les flux utilisables en mémoire sont ceux s'attachant aux tableaux et aux chaînes de caractères, c'est à dire, CharArrayReader, CharArrayWriter, ByteArrayInputStream, ByteArrayOutputStream pour les premiers et StringReader, StringWriter et StringBufferInputStream.

import java.io.*;
public class Flux {
    public static void main(String args[]) throws IOException {
        String chaine = "Un programme Java Simple";
        StringReader resLecture = new StringReader(chaine);
        int contenu;
        while((contenu = resLecture.read())!= -1) {
          // Affiche chacune des lettres de la chaîne de caractères
          System.out.println((char)contenu); 
        }
    }
}

La création d'un flux entrant connecté à un flux sortant au sein d'un tube (ou canal) est réalisable par l'intermédiaire des classes PipedReader et PipedWriter pour les flux de caractères, ainsi que PipedInputStream et PipedOutputStream pour les flux binaires. Toutes les données entrant dans le flux entrant, ressortent dans le même ordre dans le second associé.

import java.io.*;
public class Flux {
    public static void main(String args[]) throws IOException {
        PipedWriter sortie = new PipedWriter();
        PipedReader entree = new PipedReader(sortie);
        sortie.write('X');
        sortie.write('Y');
        sortie.write('Z');
        System.out.println((char)entree.read()); // Affiche X
        System.out.println((char)entree.read()); // Affiche Y
        System.out.println((char)entree.read()); // Affiche Z
    }
}

Le flux SequenceInputStream permet de concaténer plusieurs flux d'entrée en un seul.

import java.io.*;
import java.util.*;
class Flux {
    public static void main(String args[]) throws IOException {
        Vector vecFlux = new Vector();
        vecFlux.add(new FileInputStream("p1.txt"));
        vecFlux.add(new FileInputStream("p2.txt"));
        vecFlux.add(new FileInputStream("p3.txt"));
        Enumeration listeFlux = vecFlux.elements();
        SequenceInputStream poeme = 
                                                    new SequenceInputStream(listeFlux);
        BufferedReader lecture = new BufferedReader(
                                                    new InputStreamReader(poeme));
        String ligne;
        String contenu = "";
        int i = 1;
        while ((ligne = lecture.readLine()) != null) {
          System.out.println(ligne);
          contenu += i++ + ": " + ligne + "\r\n";
        }
        OutputStreamWriter sortie = new OutputStreamWriter(
                                    new BufferedOutputStream(
                                    new FileOutputStream("poeme.rtf")));
        sortie.write(contenu);
        sortie.flush();
        sortie.close();
        poeme.close();
        lecture.close();
    }
}

Les flux employés dans la sérialisation des objets sont représentés par les classes ObjectInputStream, ObjectOutputStream. Les objets cibles doivent implémenter l'interface java.io.Serializable, ou java.io.Externalizable.

import java.io.*;
import java.util.*;
class Flux {
    public static void main(String args[]) 
                                      throws IOException, ClassNotFoundException {
        String contenu = "Un contenu pour ce fichier !";
        ObjectOutputStream fluxSortieObjet = 
                                                    new ObjectOutputStream(
                                                    new FileOutputStream(
                                                    new File("fichier.txt")));
        fluxSortieObjet.writeObject(contenu);
        System.out.println ("Sauvegarde du fichier objet !");
        fluxSortieObjet.flush();
        fluxSortieObjet.close();
        
        String resultat;
        ObjectInputStream fluxEntreeObjet =new ObjectInputStream(
                                new FileInputStream(
                                new File("fichier.txt")));
        resultat = (String)fluxEntreeObjet.readObject();
        System.out.println ("Lecture du fichier objet !");
        System.out.println(resultat);
        fluxEntreeObjet.close();
    }
}

Pour la lecture de données de type primitif (char, byte, short, int, long, float et double) dans un format indépendant des machines sous-jacentes, sont utilisés les flux spéciaux DataInputStream, DataOutputStream.

import java.io.*;
class Flux {
    public static void main(String args[]) throws IOException {
        ByteArrayOutputStream sortie = new ByteArrayOutputStream();
        DataOutputStream sortieDonnee = 
                                                      new DataOutputStream(sortie);

        sortieDonnee.writeBytes("Une chaîne " 
                                                       + "de caractères quelconque !");
        System.out.println (sortieDonnee.size());
        sortieDonnee.writeInt(2003);
        System.out.println (sortieDonnee.size());
        sortieDonnee.writeDouble(16.32);
        System.out.println (sortieDonnee.size());
        sortieDonnee.flush();
        byte[] tableau = sortie.toByteArray();
        System.out.println(tableau.length);
    }
}

La conservation du nombre de lignes lors d'une opération de lecture est assurée par les flux de dénombrement LineNumberReader et LineNumberInputStream.

import java.io.*;
class Flux {
    public static void main(String args[]) throws IOException {
        System.out.println ("Veuillez saisir une ligne : ");
        InputStreamReader entreeStandard = 
                                        new InputStreamReader(System.in);
        LineNumberReader resLecture = 
                                        new LineNumberReader(entreeStandard);
        String ligne;
        while((ligne = resLecture.readLine()) != null) {
            if(ligne.equals("x")){
                resLecture.close();
                break;
            }
            System.out.println("Contenu de la ligne no" 
                                            + resLecture.getLineNumber() + ":\n" + ligne);
            System.out.println ("Veuillez saisir " 
                                            + "une nouvelle ligne (x pour sortir): ");
        }
    }
}

Les classes PushbackReader et PushbackInputStream sont employées pour une lecture anticipée suivie d'un retour des données lues dans le flux.

import java.io.*;
class Flux {
    public static void main(String args[]) {
        try{
            String repertoire = "c:/java/projets/flux/classes";
            String fichier = "poeme.txt";
            BufferedWriter sortie = new BufferedWriter(
                                    new FileWriter(
                                    new File(repertoire, fichier)));
            String poeme = "Es-tu plus belle es-tu moins belle\n\r"
                        + "qu'auparavant\n\r"
                        + "...\n\r"
                        + "en grave fidélité\n\r"
                        + "affirme chaque jour son évidence blanche";
            sortie.write(poeme);
            sortie.flush();
            sortie.close();

            PushbackReader entree = new PushbackReader(
                                    new BufferedReader(
                                    new FileReader(
                                    new File(repertoire, fichier))));
            int car;
            StringBuffer contenu = new StringBuffer();
            while((car = entree.read()) != -1){
                contenu.append((char)car);
            }
            System.out.println(contenu);
            entree.close();
        }
        catch(FileNotFoundException e){
            System.err.println("Fichier non trouvé !\n" + e);
        }
        catch(IOException e){
            System.err.println("Exception d'entree/sortie !\n" + e);
        }
    }
}
//Autre exemple
public String lireChiffres(PushbackReader pb) {
    char car;
    StringBuffer tampon = new StringBuffer();
    try {
        while (true) {
            car = (char)pb.read();
            if (!Character.isDigit(car))
                break;
            tampon.append(car);
        }
        if (car != -1)
            pb.unread(car);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    return tampon.toString();
}

Les flux utilisables pour des opérations d'impression de représentations de diverses données selon un format précis, sont PrintWriter et PrintStream.

import java.io.*;
class Flux {
    public static void main(String args[]) throws IOException {
        PrintWriter sortieStandard = new PrintWriter(System.out, true);
        sortieStandard.println("Un contenu quelconque !");
    }

}

La conversion des flux binaires en flux de caractères est réalisée par l'intermédiaire des classes InputStreamReader et OutputStreamWriter.

import java.io.*;
import java.math.BigInteger;
class Flux {
    public static void main(String args[]) {
        try {        
            OutputStreamWriter sortie = 
                            new OutputStreamWriter(
                            new BufferedOutputStream(
                            new FileOutputStream("fibonacci.xml")), "8859_1");

            BigInteger sup  = BigInteger.ONE;
            BigInteger inf = BigInteger.ONE;
            sortie.write("<?xml version=\"1.0\" ");
            sortie.write("encoding=\"ISO-8859-1\"?>\r\n");
            sortie.write("<Fibonacci_Numbers>\r\n");
            for (int i = 1; i <= 20; i++) {
                sortie.write("  <fibonacci index=\"" + i + "\">");
                sortie.write(inf.toString());
                sortie.write("</fibonacci>\r\n");
                BigInteger temp = sup;
                sup = sup.add(inf);
                inf = temp;
            }
            sortie.write("</Fibonacci_Numbers>\r\n");
            System.out.println ("Le fichier 'fibonacci.xml' a ete cree !");
            sortie.flush();
            sortie.close();
        }
        catch (IOException e) {
            System.out.println(e.getMessage());
        }
        catch (Exception e) {
            System.out.println("Une exception a ete levee : " + e);
        }
    }
}

L'écriture et la lecture dans les fichiers nécessitent l'emploi des flux FileReader et FileWriter pour les fichiers textes, ainsi que FileInputStream et FileOutputStream pour les fichiers binaires.

import java.io.*;
import java.util.*;
import java.util.regex .*;
class Flux {
    public static void main(String args[]) throws IOException {
        FileInputStream fluxEntrant = new FileInputStream("poeme.rtf");
        BufferedReader lecture = new BufferedReader(
                                 new InputStreamReader(fluxEntrant));

        String regexp = "^[0-9]*: ";
        Pattern modele = Pattern.compile(regexp);
        Matcher correspondance;
        String ligne, contenu = "";
        while ((ligne = lecture.readLine()) != null) {
            correspondance = modele.matcher(ligne);
            ligne = correspondance.replaceFirst("");
            System.out.println(ligne);
          contenu += ligne + "\r\n";
        }
        FileOutputStream fluxSortant = 
                              new FileOutputStream("poeme_sans_numero.rtf");
        OutputStreamWriter ecriture = new OutputStreamWriter(
                              new BufferedOutputStream(fluxSortant));
        ecriture.write(contenu);
        
        ecriture.flush();
        ecriture.close();
        fluxSortant.close();
        fluxEntrant.close();
        lecture.close();
    }
}

D'autres flux particulièrement utiles dans les opérations d'entrée/sortie permettent de placer en mémoire tampon le contenu des flots fournissant des informations séquentiellement. A cet effet quatre flux sont disponibles, il s'agît de BufferedReader et BufferedWriter pour traiter les caractères, ainsi que BufferedInputStream et BufferedOutputStream pour le traitement des données binaires. Ces flux améliorent sensiblement les performances d'entrée/sorities.

import java.io.*;
import java.util.*;
import java.text.*;
class Flux {
    public static void main(String args[]) {
        try{
            Date datejour = new Date();
            DateFormat dateFormat = DateFormat.getDateInstance(
                                            DateFormat.DEFAULT, Locale.FRENCH);
            String date = dateFormat.format(datejour);
            int nb = 10;
            double res;
            String fichier = "fichier.csv";
            BufferedWriter tampon = new BufferedWriter(
                                                            new FileWriter(fichier));
            PrintWriter sortie = new PrintWriter(tampon);
            for (int i = 1; i <= nb; i++){
                res = 3.14 * i * i / 4;
                sortie.println(date + ";" + i + ";" + res);
            }
            sortie.flush();
            sortie.close();
        }
        catch(IOException e){
           System.out.println (e);
        }
    }
}

Les classes BufferedInputStream et BufferedOutputStream sont dérivées respectivement des classes filtres FilterInputStream et FilterOutputStream. Ces dernières sont chargées de filtrer les flux de données en lecture ou en écriture. Ces deux classes possèdent plusieurs sous-classes souvent utilisées en association avec les flux :

FilterInputStream
FilterOutputStream
Télécharger l'ensemble des exemples

31 / Le paquetage NIO

Le nouveau paquetage java.nio (New-Input/Output), disponible depuis la version 1.4 du JDK (Java Development Kit), fournit des outils plus performants par rapport au paquetage java.io viellissant. L'amélioration des performances des opérations d'entrée/sortie est désormais réalisable sans avoir à écrire du code natif spécifique.

Le paquetage NIO gère les données en bloc, contrairement à IO qui les traite par flux. Chaque opération produit ou consomme un bloc de données en une étape, là ou IO utilise un flux d'entrée pour la production d'un octet et un flux de sortie pour la consommation d'un octet. Le traitement de données par bloc est souvent plus rapide qu'un traitement par flux d'octets. Mais, NIO manque de simplicité par rapport à IO qui est assez souple pour la création et la combinaison des flux.

Par ailleurs, de nouvelles fonctionnalités apparaissent avec ce paquetage. En effet, il devient notamment possible de poser des verrous sur les fichiers en cours de traitement par une application.

import java.nio.*;

Le paquetage NIO se décompose en trois types de classes :

31.1 / Les canaux (channels)

Les canaux sont des objets à partir desquels des données peuvent être lues ou écrites. Les canaux peuvent être assimilés aux flux du paquetage IO qui connectent une entité telle qu'un fichier ou un socket réseau. Cependant, les canaux diffèrent des flux, dans la mesure ou les premiers peuvent être bidirectionnels (lecture, écriture ou lecture/écriture), tandis que les derniers sont uniquement unidirectionnels (InputStream ou OutputStream).

ClasseDescription
Channelscontient des méthodes utilitaires pour les canaux et les flux.
DatagramChannelcontient des canaux sélectionnables pour les sockets orientés datagrammes.
FileChannelcontient un canal pour la lecture, l'écriture, le mapping et la manipulation des fichiers.
FileChannel.MapModecontient une énumération sans restriction de type (typesafe) pour les modes de fichier mappé.
Pipecontient une paire de canaux qui implémente un canal unidirectionnel.
Pipe.SinkChannelcontient un canal représentant la capacité d'écriture d'un objet Pipe.
Pipe.SourceChannelcontient un canal représentant la capacité en lecture d'un objet Pipe.
SelectableChannelcontient un canal qui peut être multiplexé via un objet Selector.
ServerSocketChannelcontient un canal sélectionnable pour les flux écoutant des sockets.
SocketChannelcontient un canal sélectionnable pour les flux connectés sur des sockets.

La classe Channels dispose de plusieurs méthodes statiques convertissant

Les canaux FileChannel sont spécialisés dans la manipulation des fichiers. A cet effet, ils implémentent des méthodes de lecture (read()), d'écriture (write()), de positionnement (position()), d'obtention de la taille et de troncature du fichier cible (size() et truncate()), mais aussi, et certainement les plus intéressantes, de mise en oeuvre d'un verrou sur le fichier courant (lock() et tryLock()). Des méthodes permettent également le transfert de données du canal courant vers un autre et vice versa (transferTo() et transferFrom()).

Un objet de type Pipe est constitué de deux canaux, l'un en lecture (Pipe.SourceChannel) et l'autre en écriture (Pipe.SinkChannel). Lorsque des données sont écrites dans le canal Pipe.SinkChannel, ces mêmes données sont lues d'une façon synchrone par le canal Pipe.SourceChannel.

Les objets SelectableChannel sont des canaux (DatagramChannel, Pipe.SinkChannel, Pipe.SourceChannel, ServerSocketChannel, SocketChannel) qui peuvent être sélectionnés par un sélecteur (objet Selector). Les canaux SelectableChannel doivent être prélablement enregistrés (register()) auprès d'un sélecteur, afin d'obtenir une clé de sélection (SelectionKey). Cette clé représentant le canal sélectionnable rejoindra d'autres clés au sein du sélecteur. De cette manière, un programme peut gérer un groupe de canaux, et déclencher un traitement lorsqu'un événement se produit sur l'un des canaux.

Les canaux ServerSocketChannel et SocketChannel consituent respectivement des tuyaux de communication vers un socket serveur et un socket client, utiles dans des applications réseaux. Les échanges asynchrones de tels systèmes, sont en général gérés par l'intermédiaire des sélecteurs de canaux, capables de sélectionner un canal à la moindre activité détectée sur un socket.

31.1.1 / utilisation des canaux

Les canaux s'obtiennent par l'intermédaire des méthodes getChannel() d'objets FileInputStream, FileOutputStream, ou RandomAccessFile pour les fichiers et ServerSocket, Socket pour les ressources provenant des réseaux.

FileInputStream fis = new FileInputStream(new File("chemin"));
FileChannel fc = fis.getChannel();

ServerSocket ss = new ServerSocket(8080);
ServerSocketChannel fc = ss.getChannel();

Un canal est dit ouvert lors de sa création. La fermeture de ce canal s'obtient suite à l'invocation de la méthode close(). Si un objet Channel est fermé, toutes tentatives d'y accèder provoquera la levée d'une exception ClosedChannelException. Afin d'éviter ce problème, il faut utiliser la méthode isOpen() pour tester si le canal concerné est encore disponible pour des opérations d'entrée/sortie.

if(fc.isOpen()){
    ByteBuffer buf = ByteBuffer.allocate(fc.size());
    fc.read(buf);
    fc.close();
}

L'ouverture des objets SocketChannel est aussi réalisable au moyen des méthodes open() disponibles dans les classes SocketChannel et ServerSocketChannel.

ServerSocketChannel ssc = ServerSocketChannel.open();

Les canaux disposent de plusieurs méthodes de lecture et d'écriture. Les interfaces ReadableByteChannel et WritableByteChannel fournissent respectivement une méthode read() et une autre write() permettant de lire et d'écrire dans un tampon d'octets (ByteBuffer). Ces deux méthodes implémentées dans les classes DatagramChannel, FileChannel, Pipe.SourceChannel et SocketChannel, retournent le nombre d'octets lus ou écrits.

int nb = 0;
while ((nb = fc_entree.read(buf)) == -1){
    buf.flip();
    fc_sortie.write(buf);
    buf.clear();
}

Si le canal est ouvert en lecture seule, une tentative d'écriture provoquera la levée d'une exception NonWritableChannelException, et inversement si le canal n'est pas ouvert en lecture, sera lancée une exception NonReadableChannelException.

Un canal ouvert à partir d'un objet FileInputStream, il est dit ouvert en lecture. Pour un flux FileOutputStream, le canal est ouvert en écriture. Dans le cas d'un objet RandomAccessFile, le type d'ouverture dépend du mode d'accès (r : lecture seule, w : écriture seule, rw : lecture et écriture) spécifié au moment de la création de l'objet. En ce qui concerne les sockets réseau, les canaux sont bidirectionnels.

FileInputStream fis = new FileInputStream("chemin_fichier");
FileOutputStream fos = new FileOutputStream("chemin_fichier");
RandomAccessFile raf = new RandomAccessFile("chemin_fichier", "rw");

FileChannel fc_lecture = fis.getChannel();
FileChannel fc_ecriture = fos.getChannel();
FileChannel fc_lecture_ecriture = raf.getChannel();

Les interfaces GatheringByteChannel et ScatteringByteChannel fournissent des méthodes d'écriture et de lecture sur des tableaux d'objets ByteBuffer. La méthode Gathering/Scattering IO (Assemblage/Division IO) permet de manipuler plusieurs tampons d'octets.

RandomAccessFile raf= new RandomAccessFile("chemin_fichier", "rw");
FileChannel canal = raf.getChannel();
ByteBuffer[] tampons = new ByteBuffer[10];
//Méthodes Gathering IO
long nb_octets = canal.write(tampons);
long nb_octets = canal.write(tampons, 0, 1024);
//Méthodes Scattering IO
long nb_octets = canal.read(tampons);
long nb_octets = canal.read(tampons, 0, 1024);

Ces méthodes de lecture et d'écriture sont utiles par exemple, pour diviser ou assembler un message réseau reçu ou à envoyer via un canal. Les deux deux parties distinctes d'une requête ou d'une réponse, l'entête et le corps, peuvent dans ce cadre être stockés dans deux objets ByteBuffer qui seront soumis à ce genre de méthode.

Exemple [voir]
package nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Copie {
    public static void main(String args[]) {
        File source = new File("source.txt");
        File destination = new File("destination.txt");

        Copie copie = new Copie();
        copie.copier(source, destination, true);
    }
    public void copier(File fic_source, File fic_destination, boolean rapide) {
        try {
          FileInputStream fis_source = 
                    new FileInputStream(fic_source);
          FileOutputStream fos_destination = 
                    new FileOutputStream(fic_destination);
  
          FileChannel fc_source = fis_source.getChannel();
          FileChannel fc_destination = fos_destination.getChannel();
  
          ByteBuffer tampon = null;
          if(rapide)
              tampon = ByteBuffer.allocateDirect(1024);
          else
              tampon = ByteBuffer.allocate(1024);
  
          int nb_octets = 0;
          while ((nb_octets = fc_source.read(tampon)) > -1) {
              tampon.flip();
  
              fc_destination.write(tampon);
  
              tampon.clear();
          }
        }
        catch(IOException e) {
            e.printStackTrace();
        }
    }
}

31.1.2 / Le verrouillage de fichier

Le paquetage NIO dispose des outils nécessaire à la mise en place d'un verrouillage de la totalité d'un fichier ou seulement de sa partie sensible. Les verrous constituent un moyen de coordonner le partage et l'acquisition de verrous. Un verrou peut être exclusif ou partagé. :

ClasseDescription
FileLockcontient un jeton (token) représentant un verrou sur une zone d'un fichier.

Les méthodes lock() de la classe FileChannel permet de verrouiller une partie d'un fichier. Le fichier cible peut être verrouillé entièrement (lock()) ou partiellement (lock(in, int, boolean)). Dans ce dernier cas, la délimitation de la partie à verrouiller est indiquée par deux valeurs entières exprimant la position de départ et la taille totale de la zone ciblée.

int debut = 10;
int taille = 20;
boolean acces_partage = false;
RandomAccessFile raf = new RandomAccessFile("fichier.txt", "rw");
FileChannel fc = raf.getChannel();

//La zone ... >> 10 <--> 30 << ... est verrouillée
FileLock verrou = fc.lock(debut, taille, acces_partage);
//ou
//Tout le fichier est verrouillé
FileLock verrou = fc.lock();
//Equivaut à fc.lock(0L, Long.MAX_VALUE, false);

L'équivalence à la méthode lock() utilise une taille égale à la valeur maximum des entiers long, car si la taille du fichier augmente, tout son contenu, malgré sa modification, continuera à être l'objet du verrou.

FileLock verrou = fc.lock(0L, fc.size(), false);
//Modification du fichier... 
//=> taille du fichier est égale à fc.size() + 20
int taille = verrou.size(); //taille est égale à fc.size()
Le verrouillage est maintenant partiel
//Verrouillage complet quelque soit les modifications de taille FileLock verrou = fc.lock(0L, Long.MAX_VALUE, false);

La méthode lock(in, int, boolean) possède un troisième paramètre booléen décidant du type du verrou à appliquer à la zone à verrouiller du fichier. Si l'argument spécifié est true, alors le verrou sera partagé. Dans le cas contraire, il sera exclusif.

FileLock verrou_partage = fc.lock(debut, taille, true);

Les méthodes lock() bloque le programme (ou l'un de ses threads) jusqu'à ce que le verrou soit acquis sur le fichier ou que le canal sous-jacent soit fermé ou que le thread invoquant une de ces méthodes soit interrompu. Afin d'éviter cet effet de blocage, il est possible d'invoquer les méthodes tryLock() qui effectuent une tentative d'acquisition d'un verrou et retourne immédiatement un objet FileLock, si le verrouillage est obtenu, ou la valeur null si la commande a échouée.

FileLock verrou = fc.tryLock();

FileLock verrou = fc.tryLock(debut, taille, false);

Plusieurs exceptions peuvent être lancées :

ExceptionMéthodes
Description
IllegalArgumentExceptionlock(int, int, boolean)
tryLock(int, int, boolean)
Si les paramètres ne sont pas conformes aux préconditions (position > 0, taille > 0 et taille + position > 0).
ClosedChannelExceptionlock()
tryLock()
lock(int, int, boolean)
tryLock(int, int, boolean)
Si le canal sous-jacent est fermé.
AsynchronousCloseExceptionlock()
tryLock()
Si un autre thread ferme le canal pendant que le thread invoquant la méthode lock() est bloqué dans cette méthode.
FileLockInterruptionExceptionlock()
tryLock()
Si le thread invoquant la méthode lock() est interrompu au moment bloqué dans cette méthode.
OverlappingFileLockExceptionlock()
tryLock()
lock(int, int, boolean)
tryLock(int, int, boolean)
Si un verrou qui recouvre la zone requise du fichier est déjà tenu par la JVM, ou si un autre thread est déjà bloqué par cette méthode et tente de verrouiller une zone recouverte du même fichier.
NonReadableChannelExceptionlock()
tryLock()
Si le verrou est partagé et que le canal sous-jacent n'a pas été ouvert pour la lecture.
NonWritableChannelExceptionlock()
tryLock()
Si le verrou n'est pas partagé et que le canal n'a pas été ouvert pour l'écriture.
IOExceptionlock()
tryLock()
lock(int, int, boolean)
tryLock(int, int, boolean)
Si une erreur d'entrée/sortie se produit.

Le verrou doit être libéré afin que d'autres programmes concurrents puissent éventuellement acquérir le verrou à leur tour. La méthode release() s'acquitte de cette tâche.

verrou.release();

Toutefois, si le canal associé au fichier est déjà fermé, sera lancée une exception ClosedChannelException si la méthode release() est invoquée.

Par ailleurs, la fermeture du canal (celui récupérable par channel()) ou l'arrêt de la machine virtuelle entraîne une libération automatique du verrou sur le fichier.

fc.close();
if(verrou.channel().isOpen()){
    //Si le canal est encore ouvert
}

La validité d'un verrou peut être testée par la méthode isValid(). Tant que le verrou n'est pas libéré, la méthode retournera une valeur booléenne true.

boolean actif = verrou.isValid();

La méthode overlaps() vérifie si une partie du fichier est (true) ou n'est pas verroullé (false). Un intervalle exprimé par une position de départ et une taille, est passé en argument à cette méthode.

boolean actif = verrou.overlaps(10, 20);
//dans ce cas, actif = true

La position de départ et la taille délimitant la zone d'un fichier verrouillé, sont disponibles à partir des méthodes position() et size().

int position = verrou.position();
int taille = verrou.size();
//position = 10 et taille = 20

Enfin, le type du verrou est déterminable par un appel à la méthode isShared(). En effet, si la méthode précitée retourn true, alors le verrou est partagé sinon, il est exclusif.

if(verrou.isShared()){
    //Le verrou est partagé
}
Exemple [voir]
package nio;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class Verrouillage extends Thread {
    private final int position = 10;
    private final int taille = 20;
    private int numero;
    private int pause;
    private boolean essai;

    public static void main(String args[]) {
        boolean essai = false;
        if (essai)
            System.out.println("*** Utilisation de tryLock() ***");
        else 
            System.out.println("*** Utilisation de lock() ***");
        for (int i = 0; i < 3; i++) {
            Verrouillage thread = new Verrouillage(i, i + 1, essai);
            thread.start();
        }
    }

    public Verrouillage(int numero, int s, boolean essai) {
        this.numero = numero;
        this.pause = s * 1000;
        this.essai = essai;
    }

    public void run() {
        this.executer();
    }

    public void executer() {
        try {
            RandomAccessFile raf = 
                    new RandomAccessFile("usefilelocks.txt", "rw");
            FileChannel fc = raf.getChannel();
            System.out.println("Ouverture du canal " + numero);

            FileLock verrou = null;
            if (essai)
                verrou = fc.tryLock(position, taille, false);
            else 
                verrou = fc.lock(position, taille, false);
            System.out.println("Acquisition du verrou n°" + numero 
                         + " verrou=" + verrou);

            System.out.println("\tPause de " + (pause / 1000)
                         + "s sur le verrou n°" + numero);
            try {
                Thread.sleep(pause);
                System.out.println("\tFin de la pause sur le verrou n°" 
                                + numero);
            }
            catch (InterruptedException ie) {
            }
            
            if(verrou != null) {
                System.out.println("\tLibération du verrou n°" + numero);
                verrou.release();
            }

            System.out.println("Fermeture du canal " + numero);
            raf.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

31.1.3 / Les sockets réseau

En cours de rédaction...

Exemple [voir]
package nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
public class ClientHTTP {
  public static void main(String args[]) {
    String hote = "www.laltruiste.com";
    SocketChannel sc = null;
    try {
      Charset latin = Charset.forName("ISO-8859-1");
      CharsetDecoder decodeur = latin.newDecoder();
      CharsetEncoder encodeur = latin.newEncoder();

      ByteBuffer bb = ByteBuffer.allocateDirect(1024);
      CharBuffer cb = CharBuffer.allocate(1024);

      InetSocketAddress adresse = new InetSocketAddress(hote, 80);
      sc = SocketChannel.open();
      sc.connect(adresse);

      String request = 
          "POST /cgi-bin/htsearch HTTP/1.1\r\n" +
          "Host: " + hote + "\r\n" +
          "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; fr; rv:1.5) " 
                          + "Gecko/20031007 Firebird/0.7\r\n" +
          "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,"
                    + "text/plain;q=0.8,video/x-mng,image/png,image/jpeg,"
                    + "image/gif;q=0.2,*/*;q=0.1\r\n" +
          "Accept-Language: fr,en;q=0.5\r\n" +
          "Accept-Encoding: gzip,deflate\r\n" +
          "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
          "Keep-Alive: 300\r\n" +
          "Connection: keep-alive\r\n" +
          "Referer: http://www.laltruiste.com/accueil.php?compteur=1&evolution=5\r\n" +
          "Content-Type: application/x-www-form-urlencoded\r\n" +
          "Content-Length: 117\r\n\r\n" +
          "words=java&method=and&format=builtin-long&sort=score&choix=site" 
              + "&config=laltruiste_htdig&restrict=&exclude=&evolution=\r\n";

      sc.write(encodeur.encode(CharBuffer.wrap(request)));

      while ((sc.read(bb)) != -1) {
        bb.flip();
        decodeur.decode(bb, cb, false);
        cb.flip();
        System.out.println(cb);
        bb.clear();
        cb.clear();
      }
    }
    catch (UnknownHostException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    finally {
      if (sc != null) {
        try {
          sc.close();
        }
        catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

31.1.4 / Le sélecteur de canaux

Les sélecteurs de canaux (Selector) sont utilisés pour des opérations d'entrée/sortie asynchrones, dans le cas notamment d'applications client/serveur.

ClasseDescription
SelectionKeycontient un jeton (token) représentant l'enregistrement d'un objet SelectableChannel avec un objet Selector.
Selectorcontient un multiplexeur d'objets SelectableChannel.

Les sélecteurs de canaux se créent suite à l'appel de la méthode statique open() de la classe Selector.

Selector selecteur = Selector.open();

Les canaux sélectionnables (SelectableChannel) doivent être référencés dans l'objet Selector par l'intermédiaire d'une clé (SelectionKey).

ServerSocketChannel sserveur = ServerSocketChannel.open();
//...
SelectionKey cle = sserveur.register(selecteur, SelectionKey.OP_ACCEPT);

La méthode register() prend deux arguments, le premier est le sélecteur qui sera chargé de sélectionner le canal vers le socket du serveur, et le second indique au sélecteur le genre d'événement pour lequel ce canal devra être sélectionné pour un traitement ultérieur. Dans le cas d'un objet ServerSocketChannel, la connexion d'un client sur le canal précité produit le lancement de l'événement OP_ACCEPT. Les autres événements possibles sont OP_CONNECT (connexion), OP_READ (lecture) et OP_WRITE (écriture).

Le sélecteur est maintenant prêt à sélectionner le canal qui produira l'événement enregistré avec la méthode register(). La méthode select() met en oeuvre cette observation événementielle en sélectionnant un jeu de clés correspondants aux canaux sur lesquels s'est produit une opération d'entrée/sortie.

while(true){
    int nbCles = selecteur.select();
    //...
}

La boucle infinie permet à l'application, de constamment consulter le sélecteur à propos du déclenchement d'un événement sur l'un des canaux référencés.

Les clés sélectionnées sont accessibles en invoquant la méthode selectedKeys().

Set scles = selecteur.selectedKeys();

Un ensemble de clés est retourné par la méthode selectedKeys(). Le parcours de cette collection peut s'effectuer par le truchement d'un itérateur.

Iterator ite = scles.iterator();
while(ite.hasNext()){
    SelectionKey scle = (SelectionKey)ite.next();
    //...
}

Afin de déclencher un traitement approprié à la clé sélectionnée, il faut vérifier quel événement est associé à cette clé. Il existe plusieurs méthodes qui permettent de contrôler l'effectivité des différents types d'événement : isAcceptable, isConnectable(), isReadable() et isWritable().

if(scle.isAcceptable()){
//ou if((scle.readyOps() & SelectionKey.OP_ACCEPT) != 0)
    //...
}

Connaissant le type d'événement produit et possèdant la clé sélectionnée, il devient possible d'exécuter un traitement approprié sur le canal concerné. La récupération de ce canal est possible en appelant la méthode channel().

ServerSocketChannel canal = (ServerSocketChannel)cle.channel();

Enfin, le traitement adéquat peut être exécuté sur le canal.

SocketChannel serveur = canal.accept();

Maintenant, le nouveau canal doit être placé dans le sélecteur au moyen de la méthode register(). Dans ce cas, le canal est chargé de lire les données transmises par le client, ainsi l'événement adéquat pour enregistrer ce canal est une opération de lecture.

SelectionKey cleserveur = 
        serveur.register(selecteur, SelectionKey.OP_READ);

Afin d'éviter de retrouver, lors d'une prochaine itération, la clé sélectionnée que l'on vient de traiter, il est impératif de supprimer cette clé de l'objet Iterator courant.

ite.remove();

Lorsque la connexion est établie, les sockets (client et serveur) peuvent alors communiquer entre eux. Ainsi, des données sont envoyées par le socket client vers le serveur. Le canal référencé en lecture est, dès lors, sélectionné par le sélecteur. Les données transmises peuvent être traitées en conséquence et si besoin est une réponse peut être retournée au client. Auparavant, à l'instar du contrôle de l'événement d'acceptation d'une connexion, il faut vérifier s'il s'agît effectivement de gérer une opération de lecture en appelant la méthode isReadable().

if(scle.isReadable()){
    SocketChannel serveur = (SocketChannel)scle.channel();
    //Traitement des données...
}
Exemple [voir]

31.2 / Les tampons (buffers)

Les tampons (buffers) sont des objets qui contiennent des données de différents types primitifs (byte, char, short, int, long, float et double).

Le tampon, le plus généralement utilisé, demeure l'objet ByteBuffer permettant de mainpuler aisément les données provenant des fichiers ou des sockets. Le tampon CharBuffer constituant une séquence de caractères est également couramment employé pour traiter des informations textuelles.

Il est évidemment possible de lire le contenu de ces objets, mais aussi d'y écrire des informations. Les tampons peuvent s'appuer sur des tableau d'octets, de caractères ou de nombres. Si tel est le cas, la méthode hasArray() retournerait true. D'ailleurs, le tableau est accessible via la méthode array().

if(tampon.hasArray()){
    byte[] octets = tampon.array();
}

Deux exceptions peuvent être levées si l'objet Buffer est en lecture seule (ReadOnlyBufferException) et s'il n'est pas renforcé par un tableau (UnsupportedOperationException).

Exemple [voir]
package nio;

import java.nio.DoubleBuffer;
import java.nio.IntBuffer;

public class Tampons {
    public static void main(String[] args) throws Exception {
        int taille = 10;
        DoubleBuffer tampon_double = DoubleBuffer.allocate(taille);
        IntBuffer tampon_int = IntBuffer.allocate(taille);

        for (int i = 0; i < tampon_double.capacity(); i++) {
            tampon_int.put(i);
            double resultat = i * Math.pow(10, i);
            tampon_double.put(resultat);
        }

        tampon_int.flip();
        tampon_double.flip();

        while (tampon_double.hasRemaining() && tampon_int.hasRemaining()) {
            int entier = tampon_int.get();
            double resultat = tampon_double.get();
            System.out.println(
                    entier + " * Math.pow(10, " + entier + ") = " + resultat);
        }
    }
}

31.2.1 / Les propriétés des tampons

Tous les tampons précités descendent de la classe abstraite Buffer qui propose l'essentiel des propriétés de ces objets.

Les différentes propriétés doivent obéir aux règles suivantes :

0 <= mark <= position <= limit <= capacity

Si la valeur de la position est plus grande que la limite du tampon ou si elle est négative, une exception IllegalArgumentException sera lancée. Le même événement se produira pour la limite, dans le second cas précité et si elle excéde la capacité du tampon.

A la création d'un nouvel objet Buffer, la position est égale à 0, la marque est indéfinie, tandis que la capacité et la limite dépendent du paramètrage d'allocation.

ByteBuffer tampon = ByteBuffer.allocate(1024);

Chacune de ces propriétés possèdent un accesseur ou/et un mutateur pour retourner ou fixer leur valeur.

int capacite = tampon.capacity();

int limite = tampon.limit();
Buffer tampon = tampon.limit(20);

int position = tampon.position();
Buffer tampon = tampon.position(5);

Buffer tampon = tampon.mark();

La méthode mark() fixe le repère de l'objet Buffer à la position spécifiée. Tant que la méthode mark() n'est pas invoquée, le repère n'est jamais défini. Toutefois, il est nécessaire que le repère soit défini avant tout appel de la méthode reset(). Dans le cas contraire, il sera lancé une exception InvalidMarkException.

Buffer tampon = tampon.mark();
//...
tampon = tampon.reset();

La méthode reset() réinitialise la position du tampon à la précédente position reprérée.

Plusieurs méthodes permettent de fixer les propriétés à des valeurs particulières, comme :

ByteBuffer tampon = ByteBuffer.allocate(1024);
tampon = tampon.clear();
int cap = tampon.capacity(); //cap = 1024
int pos = tampon.position(); pos = 0

tampon.position(512);
tampon = tampon.flip();
int lim = tampon.limit(); //lim = 512
int pos = tampon.position(); pos = 0

tampon = tampon.rewind();
int lim = tampon.limit(); //lim = 1024
int pos = tampon.position(); pos = 0

La récupération du nombre d'éléments entre la position courante et la limite s'effectue à partir de la méthode remaining(). Cette valeur indique la quantité d'octets ou autres qui peuvent être lus ou écrits avant d'atteindre la limite du tampon, soit celle spécifiée au moyen de la méthode limit(int nb), soit la capacité totale fournie lors de l'allocation de ce tampon. Une autre méthode, retournant une valeur booléenne, indique si des éléments sont compris (true) ou ne sont pas compris (false) entre la position courante et la limite.

int nb_restant = tampon.remaining();
if(tampon.hasRemaining()){
  //...
}
Exemple [voir]
package nio;

import java.nio.ByteBuffer;

public class Tampon {
    public static void main(String args[]) throws Exception {
        ByteBuffer tampon = ByteBuffer.allocate(1024);
        for (int i = 0; i < 254; i++) {
            tampon.put((byte) i);
        }
        afficherCaracteristiques(tampon);
        System.out.println("APRES CREATION");
        afficherProprietes(tampon);
        tampon.flip();
        System.out.println("APRES FLIP()");
        afficherProprietes(tampon);
        if (tampon.hasArray()) {
            byte[] octets = tampon.array();
            System.out.println("Contenu du tableau d'octets du tampon : ");
            for (int i = 0; i < octets.length; i++) {
                System.out.print((char) octets[i]);
            }
            System.out.println("\nAPRES AFFICHAGE DU TABLEAU");
            afficherProprietes(tampon);
        }
        System.out.println("Contenu du tampon : ");
        while (tampon.hasRemaining())
            System.out.print((char) tampon.get());
        System.out.println("\nAPRES AFFICHAGE DU TAMPON");
        afficherProprietes(tampon);
        tampon.rewind();
        System.out.println("APRES REWIND()");
        afficherProprietes(tampon);
        tampon.clear();
        System.out.println("APRES CLEAR()");
        afficherProprietes(tampon);
    }

    public static void afficherProprietes(ByteBuffer buffer) {
        System.out.println("\tCapacité      : " + buffer.capacity());
        System.out.println("\tPosition      : " + buffer.position());
        System.out.println("\tLimite        : " + buffer.limit());
    }

    public static void afficherCaracteristiques(ByteBuffer buffer) {
        System.out.println("Direct        : " + buffer.isDirect());
        System.out.println("Lecture seule : " + buffer.isReadOnly());
    }
}

31.2.2 / L'allocation des tampons

Les classes étendues de Buffer ne disposent pas de constructeurs. Ainsi, une instance s'obtient par l'intermédiaire des méthodes d'allocation statiques allocate().

CharBuffer cb = CharBuffer.allocate(2048);

Les sous-classes de Buffer peuvent être créées également par enveloppement (wrapping) d'un tableau de données comprenant des données d'un type primitif.

int[] entiers = new int[1024];
//Enveloppement complet du tableau
IntBuffer tampon1 = IntBuffer.wrap(entiers);
//Enveloppement partiel du tableau, 
//du 512éme élément jusqu'au 544éme.
IntBuffer tampon2 = IntBuffer.wrap(entiers, 512, 32);

Seule la classe ByteBuffer possède une seconde méthode d'allocation particulière allocateDirect(). Un objet ByteBuffer direct améliore les performances des opérations d'entrée/sortie. D'ailleurs, la méthode isDirect() permet de se renseigner à propos du type du tampon (direct : true; indirect : false).

ByteBuffer bb = ByteBuffer.allocateDirect(2048);

La différence de performances entre les objets ByteBuffer directs ou indirects réside dans le fait que les premiers sont créés à partir d'un code natif via JNI (Java Native Interface). L'amélioration des performances des tampons directs dépend donc de leur implémentation au sein la plateforme Java sous-jacente. D'autre part, une exception non-spécifiée peut être levée si un tampon direct fait référence à une région inaccessible de la mémoire.

Par ailleurs, un tampon en lecture seule peut s'obtenir au moyen de la méthode abstraite asReadOnlyBuffer().

ByteBuffer bbr = bb.asReadOnlyBuffer();

Un tampon en lecture seule est très pratique dans le cas où il est nécessaire de protéger des données contre toutes tentatives de modifications impromptues.

Enfin, la classe abstraite Buffer propose une méthode abstraite isReadOnly(), qui est destinée à fournir une indication quant à la caractéristique d'accès en lecture seule du tampon. Cette méthode retourne une valeur booléenne (lecture seule : true; lecture/écriture : false). Une exception ReadOnlyBufferException sera lancée dans le cas ou une tentative de modification d'un tampon paramétré en lecture seule.

Exemple [voir]
package nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Copie {
    public static void main(String args[]) {
        File source = new File("source.txt");
        File destination = new File("destination.txt");

        Copie copie = new Copie();
        copie.copier(source, destination, true);
    }
    public void copier(File fic_source, File fic_destination, boolean rapide) {
        try {
          FileInputStream fis_source = 
                    new FileInputStream(fic_source);
          FileOutputStream fos_destination = 
                    new FileOutputStream(fic_destination);
  
          FileChannel fc_source = fis_source.getChannel();
          FileChannel fc_destination = fos_destination.getChannel();
  
          ByteBuffer tampon = null;
          if(rapide)
              tampon = ByteBuffer.allocateDirect(1024);
          else
              tampon = ByteBuffer.allocate(1024);
  
          int nb_octets = 0;
          while ((nb_octets = fc_source.read(tampon)) > -1) {
              tampon.flip();
  
              fc_destination.write(tampon);
  
              tampon.clear();
          }
        }
        catch(IOException e) {
            e.printStackTrace();
        }
    }
}

31.2.3 / Les opérations get et put

Tous les descendants de la classe Buffer se définissent en deux catégories d'opérations get et put.

Exemple [voir]

31.2.3.1 / Les opérations typées

La classe ByteBuffer fournit des méthodes get et put pour chaque type primitif. De plus, les méthodes sont déclinées pour les opérations relatives et absolues.

//Méthodes get relatives
abstract char getChar()
abstract double getDouble()
abstract float getFloat()
abstract int getInt()
abstract long getLong()
abstract short getShort()
//Méthodes get absolues
abstract char getChar(int index)
abstract double getDouble(int index)
abstract float getFloat(int index)
abstract int getInt(int index)
abstract long getLong(int index)
abstract short getShort(int index)

//Méthodes put relatives
abstract ByteBuffer putChar(char value)
abstract ByteBuffer putDouble(double value)
abstract ByteBuffer putFloat(float value)
abstract ByteBuffer putInt(int value)
abstract ByteBuffer putLong(long value)
abstract ByteBuffer putShort(short value)
//Méthodes put absolues
abstract ByteBuffer putChar(int index, char value)
abstract ByteBuffer putDouble(int index, double value)
abstract ByteBuffer putFloat(int index, float value)
abstract ByteBuffer putInt(int index, int value)
abstract ByteBuffer putLong(int index, long value)
abstract ByteBuffer putShort(int index, short value)

Toutes les méthodes sont abstraites. Cela signifie que leur implémentation dépend la plateforme Java sous-jacente.

En parallèle, un objet peut avoir la capacité de créer des objets Buffer spécifiques à un type primitif.

CharBuffer cb = bb.asCharBuffer();
DoubleBuffer db = bb.asDoubleBuffer();
FloatBuffer fb = bb.asFloatBuffer();
IntBuffer ib = bb.asIntBuffer();
LongBuffer lb = bb.asLongBuffer();
ShortBuffer sb = bb.asShortBuffer();
Exemple [voir]

31.2.4 / La méthode slice()

La méthode slice() crée un nouvel objet Buffer à partir d'un tampon existant. Ce nouvel objet contient une partie des éléments du tampon d'origine. Cette partie est délimitée par la position et la limite de l'objet Buffer.

CharBuffer cb = CharBuffer.allocate(255);
//...
cb.position(32);
cb.limit(64);
CharBuffer ss_cb = cb.slice();
//ss_cb contient 32 éléments de cb
//de la position 32 jusqu'à la limite 64

Le sous-tampon et le tampon d'origine partagent leurs éléments communs, c'est-à-dire que toutes les modifications apportées dans les éléments partagés refléteront les mêmes valeurs dans l'un ou l'autre des objets précités.

//Modification des 32 valeurs de ss_cb
for(int i = 0; i < 32; i++){
    ss_cb.put(i, '_');
}
//Affichage de la représentation textuelle de cb
System.out.println(cb.toString());
//0 - 32 -------- 64 - 255
//... ^ _________ ^ ...
Exemple [voir]
package nio;

import java.nio.ByteBuffer;

public class SousTampon {
    static public void main(String args[]) throws Exception {
        String contenu = "Un contenu quelconque...";
        System.out.println("Tampon d'origine : " + contenu);
        ByteBuffer tampon = ByteBuffer.allocate(contenu.length());
        tampon.put(contenu.getBytes());

        tampon.position(3);
        tampon.limit(10);

        ByteBuffer decoupe = tampon.slice();

        System.out.print("Sous-tampon : ");
        for (int i = 0; i < decoupe.capacity(); i++) {
            byte o = decoupe.get(i);
            System.out.print((char)o);
        }

        System.out.println("\nModification du sous-tampon...");
        decoupe.position(0);
        decoupe.put("rapport".getBytes());

        tampon.position(0);
        tampon.limit(tampon.capacity());
        System.out.print("Tampon d'origine : ");
        while (tampon.remaining() > 0) {
            System.out.print((char)tampon.get());
        }
    }
}

31.2.5 / Le tampon MappedByteBuffer

Les tampons MappedByteBuffer possèdent la particularité de manipuler les données d'un fichier uniquement au travers de la mémoire. Ainsi, un fichier mappé en mémoire (Memory-mapped file) signifie que le canal envoie directement les données du fichier vers la mémoire de l'ordinateur, à partir de laquelle toutes les opérations d'enrée/sortie seront réalisées. Cette méthode améliore donc considérablement les performances des opérations de lecture et d'écriture sur un fichier, puisqu'elle ne nécessiterait aucun accès sur le disque dur. L'implémentation exacte de la technique des MappedByteBuffer dépend de la plateforme sous-jacente.

La création d'un objet MappedByteBuffer nécessite l'invocation de la méthode map() à partir d'un objet FileChannel.

File fichier = new File("c:\\source.txt");
RandomAccessFile raf= new RandomAccessFile(fichier, "rw");
FileChannel canal= raf.getChannel();
MappedByteBuffer tampon= 
        canal.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());

La méthode map() prend trois arguments. Les deux derniers sont des entiers longs représentant la position initiale du bloc de données à charger en mémmoire, et la taille de ce bloc. Un fichier peut être entièrement ou partiellement mappé en mémoire.

MappedByteBuffer tampon = 
        canal.map(FileChannel.MapMode.READ_WRITE, 512, 1024);

Le premier argument est une constante fournie par la classe imbriquée FileChannel.MapMode. Cette classe propose trois champs statiques impliquant un mode d'accès à un fichier mappé :

Un tampon MappedByteBuffer reste disponible tant qu'il n'a pas été fermé (close()) puis nettoyé par le collecteur de déchets (Garbage Collector). Ceci implique des précautions d'emplois, notamment lorsqu'un fichier mappé est ouvert par un programme, un autre programme ou un processus concurrent dans le même programme ne peut pas accéder à la totalité ou à la portion du fichier mappé. En conséquence, toutes tentatives d'accéder à un fichier mappé provoquera la levée d'une exception dépendant du système d'exploitation sous-jacent.

La classe MappedByteBuffer descendant de la classe ByteBuffer se comporte de la même façon qu'un tampon d'octets direct. Toutefois, trois méthodes supplémentaires sont proposées pour s'assurer d'un fonctionnement correct en mémoire.

La méthde load() charge le contenu du tampon en mémoire et retourne un objet MappedByteBuffer. L'effectivité du chargement en mémoire peut être contrôlée par la méthode isLoaded().

if(!tampon.isLoaded())
    tampon = tampon.load();

Suite à une modification du contenu d'un objet MappedByteBuffer avec un mode en lecture et écriture (FileChannel.MapMode.READ_WRITE), la méthode force() peut être utilisée pour forcer les changements à être écrit sur le périphérique de stockage contenant le fichier mappé.

//Modification du tampon...
byte o = 124;
tampon = tampon.put(o);
//Validation des modifications
tampon = tampon.force();
Exemple [voir]
package nio;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;

public class Fichier extends File {
    private FileChannel fc;
    private MappedByteBuffer mpb;
    private CharsetEncoder encodeur;
    private CharsetDecoder decodeur;

    public static void main(String[] args) {
        Fichier fichier = new Fichier("fichier.txt", "ISO-8859-1");
        fichier.ecrire("Un contenu quelconque...");
        System.out.println(fichier.lire());
        fichier.fermer();
    }
    public Fichier(String chemin, String encodage) {
        super(chemin);
    try{
        RandomAccessFile raf = new RandomAccessFile(this, "rw");
        fc = raf.getChannel();
        Charset latin = Charset.forName(encodage);
        encodeur = latin.newEncoder();
          decodeur = latin.newDecoder();
        mpb = fc.map( FileChannel.MapMode.READ_WRITE, 0, 1024);
    }
    catch (IOException e) {
      e.printStackTrace();
    }
        
    }
  public void ecrire(String contenu){
      try {
        mpb.limit(contenu.length());
        CharBuffer cb = CharBuffer.wrap(contenu);
          ByteBuffer bb = encodeur.encode(cb);
        mpb.put(bb);
        }
        catch (CharacterCodingException e) {
            e.printStackTrace();
        }
  }
  public String lire(){
        try {
            mpb.position(0);
            CharBuffer cb = decodeur.decode(mpb);
          return cb.toString();
        }
        catch (CharacterCodingException e) {
            e.printStackTrace();
        }
        return null;
  }
  public void fermer() {
      try {
            this.fc.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
  }
}

31.3 / Les jeux de caractères

Le langage Java utilisent est basé sur un jeu de caractères Unicode Standard version X (voir les spécifications de la classe Character du JDK employé). Par contre, les chaînes de caractères traitées dans une application Java dépendent souvent des jeu de caractères par défaut, du système d'exploitation sous-jacent pour le traitement des fichiers, ou du serveur distant dans le cas d'une communication réseau. Ainsi, le paquetage NIO possède des classes particulières dans le paquetage java.nio.charset, qui permettent d'encoder ou de décoder des blocs de données selon un jeu de caractères précis.

Le sous-paquetage java.nio.charset contient cinq classes, dont trois dédiées spécifiquement à la définition d'un jeu de caractères et aux opérations d'encodage et de décodage de caractères.

ClasseDescription
Charsetcontient des méthodes destinées à la gestion de jeux de caractères et en particulier à la création d'encodeurs et de décodeurs.
CharsetDecoderfournit les moyens de décodage de données par rapport à un jeu de caractères indiqué lors de l'instanciation de cette classe.
CharsetEncoderfournit les moyens d'encodage de caractères par rapport à un jeu de caractères indiqué lors de l'instanciation de cette classe.
CoderResultdécrit l'état résultant d'un traitement de données par un décodeur ou un encodeur.
CodingErrorActiondécrit une erreur d'encodage ou de décodage.

31.3.1 / L'encodage et décodage

Le décodage est un processus de transformation d'un bloc d'octets (bytes) en une chaine de caractères en fonction d'un jeu de caractères (charset).

//Séquence d'octets
99 104 97 105 110 101 32 100 101 32 
99 97 114 97 99 116 232 114 101 115
=> Transformation (décodage) =>
//Séquence de caractères
"chaine de caractères"

L'encodage est un processus de tranformation d'une séquence de caractères en un bloc de données selon un jeu de caractères précis.

//Séquence de caractères
"chaine de caractères"
=> Transformation (encodage) =>
//Séquence d'octets
99 104 97 105 110 101 32 100 101 32 
99 97 114 97 99 116 232 114 101 115

Chaque implémentation de Java dispose d'une liste de jeux de caractères disponibles pour l'encodage et le décodage de données sur le système d'exploitation sous-jacent. Cette liste est consultable à partir de la méthode statique availableCharsets() de la classe Charset. Cependant les jeux de caractères standards de Java sont supportés par toutes les implémentations.

Jeux de caractèresDescription
US-ASCII128 caractères (27) ASCII
ISO-8859-1contient les caractères de l'alphabet latin
UTF-8256 caractères (28)
UTF-16BE65536 caractères (216) ordre Big-Endian (le premier octet le plus significatif)
UTF-16LE65536 caractères (216), ordre Little-Endian (le premier octet le moins significatif)
UTF-1665536 caractères (216)
public class JeuxCaracteres {
    public static void main(String[] args) {
        SortedMap col = Charset.availableCharsets(); 
        Set ens = col.entrySet();
        Iterator ite = ens.iterator();
        while (ite.hasNext()) {
            Map.Entry entree = (Map.Entry) ite.next();
            System.out.println(entree.getKey() + " : " + entree.getValue());
        }
    }
}

Tous les jeux de caractères disponibles sont appropriés pour la création d'un objet Charset. La méthode statique forName() permet de récupérer une instance de la classe Charset.

String nom = "UTF-8";
if(Charset.isSupported(nom)){
    Charset utf8 = Charset.forName(nom);
    //...
}

Parfois, il peut être opportun de vérifier si le jeu de caractères est bien supporté par la plateforme Java. Pour s'en assurer, il suffit d'utiliser la méthode statique isSupported(). Si le jeu de caractères n'est pas supporté par la plateforme sous-jacente, sera levé une exception UnsupportedCharsetException.

L'obtention du nom représentant le jeu de caractères, de l'objet Charset s'effectue via un appel des méthodes displayName() ou name(). L'une d'elles permet d'obtenir le nom usité dans une langue grâce au passage d'un argument de type référence Locale.

Charset cp1252 = Charset.forName("windows-1252");
String nom = cp1252.displayName();
String nomLoc = cp1252.displayName(new Locale("us");
String nomCanonique = utf16.name();

La méthode aliases() retournent une liste des alias du jeu de caractères Charset courant.

Charset utf16 = Charset.forName("ISO-8859-1");
Iterator ite = utf16.aliases().iterator();
while (ite.hasNext()) {
     String alias = ite.next().toString();
     System.out.println(alias);
}

La méthode isRegistered() indique si le jeu de caractères est référencé par l'organisation IANA.

if(cp1252.isRegistered()){
    //...
}

La méthode contains() indique si un jeu de caractères est contenu par l'objet Charset courant. Par exemple, le jeu de caractères US-ASCII est contenu par plusieurs autres jeux de caractères, à l'image de ISO-8859-1, UTF-8, etc..

Charset cp1252 = Charset.forName("windows-1252");
System.out.println(cp1252.contains(Charset.forName("US-ASCII")));
System.out.println(cp1252.contains(Charset.forName("ISO-8859-1")));

31.3.2 / Les objets de codage

A partir d'un objet Charset, il devient possible d'obtenir un décodeur (CharsetDecoder) et/ou un encodeur (CharsetEncoder) au moyen respectivement des méthodes d'instances newDecoder() et newEncoder() de la classe Charset.

CharsetDecoder decodeur = utf8.newDecoder();
CharsetEncoder encodeur = utf8.newEncoder();

Le décodage des séquences d'octets s'opère par une invocation de la méthode decode() de la classe CharsetDecoder. Le paramètre de la méthode decode() est un tampon d'octets ByteBuffer, lequel contient les données provenant d'une source quelconque telle qu'un fichier ou d'un socket réseau. La méthode retourne un objet CharBuffer qui renferme la chaîne de caractères résultant du décodage.

ByteBuffer tampon = ByteBuffer.allocate(1024);
//Remplissage du tampon
CharBuffer cb = decoder.decode(tampon);

L'encodage des chaînes de caractères se réalise par un appel de l'une des méthodes encode() de la classe CharsetEncoder. La méthode encode() prend comme argument un tampon de caractères CharBuffer. Les méthodes retournent un tampon ByteBuffer contenant le résultat de l'encodage.

String chaine = "Une chaîne de caractères...";
CharBuffer cb = CharBuffer.wrap(chaine);
ByteBuffer bb1 = encoder.encode(cb);
ByteBuffer bb2 = encoder.encode("Une chaîne de caractères...");

La classe Charset dispose également des méthodes d'encodage et de décodage. Toutefois, ces méthodes convertissent des octets en caractères Unicode, ou inversement.

31.3.3 / Gestion du codage

Les classes CharsetEncoder et CharsetDecoder gèrent les erreurs de codage par un appel aux méthodes onMalformedInput() et onUnmappableCharacter() définies dans les classes CharsetDecoder et CharsetEncoder.

Charset utf16 = Charset.forName("UTF-16");
CharBuffer cb = utf16.newEncoder()
                     .onMalformedInput(CodingErrorAction.REPLACE)
                     .onUnmappableCharacter(CodingErrorAction.REPLACE)
                     .encode(bb);

ByteBuffer bb = utf16.newDecoder()
                     .onMalformedInput(CodingErrorAction.REPLACE)
                     .onUnmappableCharacter(CodingErrorAction.REPLACE)
                     .decode(bb);

Les méthodes onMalformedInput() et onUnmappableCharacter() sont chargées de traiter les erreurs de codage (entrée mal formée et caractère non référencé) en appliquant une action appropriée. Ces actions sont énumérées dans la classe CodingErrorAction.

ActionDescription
IGNOREindique qu'une erreur de codage doit être traitée de telle manière que l'entrée incorrecte soit ignorée et en reprenant l'opération de codage.
REPLACEindique qu'une erreur de codage doit être traitée de telle sorte que l'entrée incorrecte soit ignorée et que la valeur de remplacement soit ajoutée au tampon, puis l'oparation de codage reprend.
REPORTindique qu'une erreur de codage doit être signalée soit par le retour d'un objet CoderResult, soit par la levée d'une exception CharacterCodingException. L'opération de codage est arrêtée.

La valeur de remplacement d'une erreur de codage, dot être définie en invoquant la méthode replaceWith(). L'obtention de cette valeur s'effectue via un appel à la méthode replacement().

CharsetDecoder cs = decodeur.replaceWith("_");
String valeur = cs.replacement();

byte[] remplacement = new byte[]{99, 104, 97};
if(encodeur.isLegalReplacement(remplacement)){
    CharsetEncoder ce = encodeur.replaceWith(remplacement);
    byte[] valeur = ce.replacement();
}

La classe CharsetEncoder possède une méthode isLegalReplacement(), déterminant si le tableau d'octets passé en argument consitue une valeur de remplacement autorisée.

Les méthodes malformedInputAction() et unmappableCharacterAction() retournent les actions d'erreur de codage.

CodingErrorAction actionEntreeIncorrecte = 
                        utf16.malformedInputAction();
CodingErrorAction actionCaractereInconnu = 
                        utf16.unmappableCharacterAction();

La classe CharsetDecoder possède deux méthode décode(). La première prend un argument ByteBuffer, alors que la seconde en prend trois, deux tampons ByteBuffer (entrée) et CharBuffer (sortie) et une valeur booléenne, indiquant si l'appelant ne peut fournir aucune entrée supplémentaires au delà de ceux compris dans le tampon. Dans le cas, d'une erreur de codage, la première lévera une exception, tandis que la seconde retournera un objet CoderResult.

ByteBuffer entree = ByteBuffer.allocate(1024);
//remplissage du tampon d'octets
Charset latin = Charset.forName("ISO-8859-1");
CharsetDecoder decodeur = latin.newDecoder();
CharBuffer sortie = decodeur.decode(entree);
//ou
CharBuffer sortie = CharBuffer.allocate(1024);
CoderResult erreur = decodeur.decode(entree, sortie, false);

De la même façon, il existe deux méthodes encode() dans la classe CharsetEncoder. Les méthodes canEncode() indiquent si la séquence de caractères ou un seul caractère peut être encodée en bloc d'octets.

CharBuffer entree = CharBuffer.wrap("Une séquence d'entrée...");
Charset latin = Charset.forName("ISO-8859-1");
CharsetEncoder encodeur = latin.newEncoder();
if(encodeur.canEncode(entree)){
    ByteBuffer sortie = encodeur.encode(entree);
    //ou
    ByteBuffer sortie = CharBuffer.allocate(entree.length());
    CoderResult erreur = encodeur.encode(entree, sortie, false);
}

Un objet CoderResult détient des informations à propos du résultat de l'opération de codage. Une opération d'encodage ou de décodage est susceptible de se terminer pour :

La classe CoderResult possède plusieurs méthodes déterminant le type du résultat de codage.

ActionDescription
boolean isError()indique si l'objet courant décrit une condition d'erreur (entrée mal formée ou caractère inconnu).
boolean isMalformed()indique si l'objet décrit une erreur due à une entrée mal formée.
boolean isOverflow()indique si l'objet décrit une condition de débordement.
boolean isUnderflow()indique si l'objet décrit une condition d'incomplétude.
boolean isUnmappable()indique si l'objet décrit une erreur due à un caractère non référencé.

Il est possible de récupérer la longueur de l'entrée incorrecte par l'intermédiaire de la méthode length().

int longueur = resultat.length();

Des méthodes statiques de création d'objets CoderResult spécifiques complètent la panoplie de cette classe.

CoderResult erreurMalFormee = CoderResult.malformedForLength(1);

CoderResult erreurCaractere = CoderResult.unmappableForLength(1);

Deux méthodes permettent d'obtenir une approximation de la taille du tampon de sortie par rapport au tampon d'entrée.

La valeur moyenne obtenue par les méthodes averageCharsPerByte() (CharsetDecoder) et averageBytesPerChar() (CharsetEncoder) fournit une estimation de la taille du tampon de sortie (CharBuffer) ou ByteBuffer) en fonction d'une séquence d'entrée donnée.

CharsetEncoder ce = utf16.newEncoder();
float moy = utf16.averageBytesPerChar();

CharsetDecoder cd = utf16.newDecoder();
float moy = utf16.averageCharsPerByte();

Les méthodes maxCharsPerByte() et maxBytesPerChar() donnent un nombre maximum de caractères ou d'octets qui seraient produits pour respectivement chaque octet ou caractère d'entrée. Cette valeur peut servir à calculer la taille maximum du tampon de sortie requise pour une séquence d'entrée.

CharsetEncoder ce = utf16.newEncoder();
float max = utf16.maxBytesPerChar();

CharsetDecoder cd = utf16.newDecoder();
float max = utf16.maxCharsPerByte();

La réinitialisation des codeurs permet un effacement de l'état interne de l'objet courant. La méthode reset() est conçu à cet effet, toutefois, elle appelle une méthode protégée (implReset()) qui ne fait rien dans l'implémentation par défaut. Ainsi, pour obtenir un réel effacement de l'état interne d'un codeur, il faut surcharger la méthode implReset() dans la sous-classe d'un codeur.

public class Decodeur extends CharsetDecoder {
    //...
    protected void implReset(){
        super.charset = null;
        super.replacement = null;
        //...
    }
    //...
}
Exemple [voir]
package nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

public class FichierIO {
    private String encodage;

    public static void main(String[] args) {
        FichierIO io = new FichierIO("UTF-16");
        File fichier = new File("document.txt");
        io.ecrire("Un contenu quelconque...", fichier, false);
        System.out.println("Contenu :\n" + io.lire(fichier));
    }

    public FichierIO(String encodage) {
        this.encodage = encodage;
    }

    public void ecrire(String contenu, File fichier, boolean ajout) {
        try {
            FileOutputStream fos = new FileOutputStream(fichier, ajout);
            FileChannel fc = fos.getChannel();

            Charset latin = Charset.forName(this.encodage);
            CharsetEncoder encodeur = latin.newEncoder();

            if (contenu == null)
                return;
            CharBuffer cb = CharBuffer.wrap(contenu);
            int taille = (int)(cb.length() * encodeur.maxBytesPerChar());
            ByteBuffer bb = ByteBuffer.allocate(taille);
            System.out.println(this.getEtatInterne(encodeur));
            CoderResult code = encodeur.encode(cb, bb, false);
            if (code.isMalformed() || code.isUnmappable())
                System.out.println("Une erreur d'écriture s'est produite !");
            cb.flip();
            bb.flip();
            System.out.println("Taille Caractères / Octets / Maximum : " 
                                + contenu.length() + " / " 
                                + bb.limit() + " / " 
                                + taille);
            System.out.println("Ecriture du fichier " + fichier.toString());
            fc.write(bb);

            fc.close();
        }
        catch (java.io.FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String lire(File fichier) {
        try {
            if (fichier.exists()) {
                FileInputStream fis = new FileInputStream(fichier);
                FileChannel fc = fis.getChannel();
                int taille = (int) fc.size();
                MappedByteBuffer mpb = 
                                fc.map(FileChannel.MapMode.READ_ONLY, 0, taille);

                Charset latin = Charset.forName(this.encodage);
                CharsetDecoder decodeur = latin.newDecoder();
                CharBuffer cb = CharBuffer.allocate(taille);
                System.out.println(this.getEtatInterne(decodeur));
                CoderResult code = decodeur.decode(mpb, cb, false);
                if (code.isMalformed() || code.isUnmappable())
                    System.out.println("Une erreur de lecture s'est produite !");
                mpb.flip();
                cb.flip();
                fc.close();
                System.out.println("Lecture du fichier " + fichier.toString());
                return cb.toString();
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    private String getEtatInterne(Object codeur) {
        StringBuffer res = new StringBuffer("Jeu de caractères : ");
        if(codeur instanceof CharsetDecoder) {
            CharsetDecoder cd = (CharsetDecoder)codeur;
            res.append(cd.charset().toString());
            res.append("\nMoyenne de caractères par octet : ");
            res.append(cd.averageCharsPerByte());
            res.append("\nNombre de caractères maximum par octet : ");
            res.append(cd.maxCharsPerByte());
        }
        else if(codeur instanceof CharsetEncoder) {
            CharsetEncoder ce = (CharsetEncoder)codeur;
            res.append(ce.charset().toString());
            res.append("\nMoyenne d'octets par caractère : ");
            res.append(ce.averageBytesPerChar());
            res.append("\nNombre d'octets maximum par caractère : ");
            res.append(ce.maxBytesPerChar());
        }
        return res.toString();
    }
}

32 / Les propriétés systèmes

Les programmes Java ne peuvent lire les variables d'environnement de la même manière que le peuvent les programmes natifs. La raison est que les variables d'environnement sont dépendantes de la plateforme. Cependant, des mécanismes similaires existent afin de permettre aux applications de lire la valeur d'une ressource nommée.

Ces valeurs de ressources permettent une personnalisation du comportement d'une application basée sur des paramètres de sites spécifiques, tel que le type de l'hôte ou basée sur des préférences utilisateurs.

Les valeurs de ressource désignées sont spécifiées pour les applications dans la liste des propriétés système. Les applications peuvent lire les propriétés systèmes avec la méthode System.getProperty() ou peut lire la liste entière avec la méthode System.getProperties().

Les propriétés systèmes standards

Lorsque l'interpréteur Java démarre, il insère un nombre de propriétés standards à l'intérieur de la liste des propriétés systèmes. Ces propriétés et la signfication de leurs valeurs sont présentées dans le tableau ci-dessous.

Nom Valeur Accès Applet
java.version représente la version de l'interpréteur Java. oui
java.vendor représente l'identificateur spécifique au vendeur. oui
java.vendor.url représente l'adresse URL du vendeur. oui
java.class.version représente la version de l'API Java. oui
java.class.path représente la valeur du répertoire de classe classpath. non
java.home représente le chemin vers le répertoire d'installation de Java. non
java.compiler représente le compilateur JIT (Just In Time) utilisable. non
os.name représente le nom du système d'exploitation. oui
os.arch représente l'architecture matériel de la machine hôte. oui
os.version représente la version du système d'exploitation de la machine hôte. oui
file.separator représente le terminateur de fichier à l'image de / ou \. oui
path.separator représente le séparateur de chemin dépendant de la plateforme sous-jacente tel que : ou ;. oui
line.separator représente le terminateur de ligne tel que \n ou \r\n. oui
user.name représente le nom de l'utilisateur courant. non
user.home représente le répertoire racine de l'utilisateur courant. non
user.dir représente le répertoire de travail courant. non
user.language représente le code du langage par défaut sous la forme d'une chaîne de caractères de deux lettres. non
user.region représente le code de région par défaut sous la forme d'une chaîne de caractères de deux lettres. non
user.timezone représente la zone horaire par défaut. non
file.encoding représente l'encodage de caractères par défaut. non
file.encoding.pkg représente le paquetage qui contient les convertisseurs entre les encodage locaux et l'Unicode. non
import java.util.*;
public class Proprietes {
    public static void main(String[] args) {
        Properties proprietes = System.getProperties();
        Enumeration noms = proprietes.propertyNames();
        Vector tabObj = new Vector();
        Object nom;
        while((nom = getElements(noms)) != null){
            tabObj.add(nom);
        }
        for(int i = 0; i < tabObj.size(); i++){
            System.out.println (tabObj.elementAt(i)
            + "\t\t\t:\t" + proprietes.getProperty((String)tabObj.elementAt(i)));
        }
    }
    public static Object getElements(Enumeration enum){
        try{
            return enum.nextElement();
        }
        catch(NoSuchElementException e){
            return null;
        }
    }
}
Résultats sur une machine Windows 2000
java.runtime.name
Java(TM) 2 Runtime Environment, Standard Edition
sun.boot.library.path
C:\JavaTools\j2sdk1.4.0\jre\bin
java.vm.version
1.4.0-b92
java.vm.vendor
Sun Microsystems Inc.
java.vendor.url
http://java.sun.com/
path.separator
;
java.vm.name
Java HotSpot(TM) Client VM
file.encoding.pkg
sun.io
user.country
FR
sun.os.patch.level
Service Pack 2
java.vm.specification.name
Java Virtual Machine Specification
user.dir
D:\Usr\Exercices\Database\colHashtable\classes
java.runtime.version
1.4.0-b92
java.awt.graphicsenv
sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs
C:\JavaTools\j2sdk1.4.0\jre\lib\endorsed
os.arch
x86
java.io.tmpdir
C:\DOCUME~1\dupont\LOCALS~1\Temp\
line.separator
java.vm.specification.vendor
Sun Microsystems Inc.
user.variant
os.name
Windows 2000
sun.java2d.fontpath
java.library.path
C:\JavaTools\j2sdk1.4.0\bin;.;C:\WINNT\System32;C:\WINNT;C :\PROGRA~1\RATIONAL\RATION~1\NUTCROOT\bin;C:\PROGRA~1\RATIONAL\RATION~1\NUTCROOT \bin\x11;C:\PROGRA~1\RATIONAL\RATION~1\NUTCROOT\mksnt;C:\JAVATO~1\RATIONAL\RATIO N~1\NUTCROOT\mksnt;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;C:\Program Files\Microsoft SQL Server\80\Tools\BINN;C:\Program Files\Rational\common;C:\Pro gram Files\Rational\ClearQuest;C:\Program Files\Rational\Rose\TopLink\;C:\Progra m Files\Rational\Rational Test;c:\javatools\j2sdk1.4.0\bin\;C:\javatools\jwsdp-1 .2\jwsdp-shared\bin
java.specification.name
Java Platform API Specification
java.class.version
48.0
java.util.prefs.PreferencesFactory
java.util.prefs.WindowsPreferencesFactory
os.version
5.0
user.home
C:\Documents and Settings\dupont
user.timezone
java.awt.printerjob
sun.awt.windows.WPrinterJob
file.encoding
Cp1252
java.specification.version
1.4
user.name
dupont
java.class.path
D:\Usr\Exercices\Database\colHashtable\classes\;C:\JavaTools \j2sdk1.4.0\jre\lib\rt.jar;C:\JavaTools\j2sdk1.4.0\lib\dt.jar;C:\JavaTools\j2sdk 1.4.0\lib\tools.jar;C:\JavaTools\j2sdk1.4.0\jre\lib\ext\dnsns.jar;C:\JavaTools\j 2sdk1.4.0\jre\lib\ext\ldapsec.jar;C:\JavaTools\j2sdk1.4.0\jre\lib\ext\localedata .jar;C:\JavaTools\j2sdk1.4.0\jre\lib\ext\sunjce_provider.jar;D:\Usr\Commun\class es
java.vm.specification.version
1.0
sun.arch.data.model
32
java.home
C:\JavaTools\j2sdk1.4.0\jre
java.specification.vendor
Sun Microsystems Inc.
user.language
fr
awt.toolkit
sun.awt.windows.WToolkit
java.vm.info
mixed mode
java.version
1.4.0
java.ext.dirs
C:\JavaTools\j2sdk1.4.0\jre\lib\ext
sun.boot.class.path
C:\JavaTools\j2sdk1.4.0\jre\lib\rt.jar;C:\JavaTools\j2sd k1.4.0\jre\lib\i18n.jar;C:\JavaTools\j2sdk1.4.0\jre\lib\sunrsasign.jar;C:\JavaTo ols\j2sdk1.4.0\jre\lib\jsse.jar;C:\JavaTools\j2sdk1.4.0\jre\lib\jce.jar;C:\JavaT ools\j2sdk1.4.0\jre\lib\charsets.jar;C:\JavaTools\j2sdk1.4.0\jre\classes
java.vendor
Sun Microsystems Inc.
file.separator
\
java.vendor.url.bug
http://java.sun.com/cgi-bin/bugreport.cgi
sun.cpu.endian
little
sun.io.unicode.encoding
UnicodeLittle
sun.cpu.isalist
pentium i486 i386
Télécharger l'ensemble des exemples

33 / Les unités d'exécutions (threads)

Les unités d'exécution (ou threads) sont des séquences d'instructions d'un programme, exécutées indépendamment les unes des autres. Une application multithread est capable de lancer plusieurs threads simultanément dans un seul processus.

Par défaut, chaque programme Java s'exécute automatiquement dans un thread unique. Si une application Java a besoin d'exécuter plusieurs tâches en paralèlle, l'utilisation des threads semble indispensable. Par exemple, dans un programme séquentiel, un compteur comptabiliserait le nombre d'affichage d'une page Web et sauvegarderait à intervalle de mille les statistiques de ce compteur dans un fichier. Il apparaît évident que lorsque la sauvegarde sera exécutée, le compteur ne pourrait plus s'incrémenter normalement si des visiteurs accèdent à la page Web à ce moment précis.

La machine virtuelle Java (JVM) exécute toujours plusieurs threads en même temps. Effectivement, outre le programme lui-même, d'autres unités d'exécution propres au système sont activées en paralèlles, à l'image des opérations relatives à la gestion événementielle et au collecteur de déchets (Garbage Collector). Ils sont appelés les threads démons (daemons threads).

Le principe du multithreading consiste à exécuter réellement dans un système multi-processeurs, des tâches dans le même temps d'horloge. Tandis qu'un système mono-processeur ou seul un thread peut s'exécuter à un moment donné, fournira l'illusion d'un fonctionnement multithread grâce à une permutation rapide entre les tâches.

La création d'applications avec une interface graphique (GUI : Graphic User Interface) à l'aide des paquetages AWT et Swing, ainsi que la programmation réseau nécessite couramment l'utilisation de la technique du multithreading.

Bien que le multithreading possède des avantages incontestables, les programmes l'utilisant deviennent plus difficile à comprendre et bien plus complexe à déboguer. La réutilisabilité du code source ne peut être également assurée dans d'autres cas d'utilisation.

Tous les programmes Java s'exécute au sein d'un thread principal. Ce thread est accessible via la méthode statique Thread.currentThread().

public class Application {
    public static void main(String[] args){
        System.out.println("Le programme débute...");
        Thread thread = Thread.currentThread();
        thread.setName("Thread Principal");
        System.out.println("Thread : " + thread.toString());
    }
}

33.1 / Le fonctionnement des threads

Le fonctionnement des threads passe par plusieurs étapes décisives. En effet, une unité d'exécution peut prendre plusieurs états distincts dans son cycle de vie.

Fonctionnement d'un thread : start(), stop(), yield(), suspend(), sleep(), wait(), notify(), notifyAll(), resume()

En premier lieu, une sous-classe héritant de Thread permet de créer une nouvelle unité d'exécution.

L'appel de la méthode start() provoque la mise en état d'exécutable du nouveau thread. Si d'autres threads sont déjà dans cet état, alors le nouveau thread passe en file d'attente des exécutables jusqu'à ce qu'arrive son tour de devenir le thread courant. Eventuellement, une préemption autorise les nouvelles unités d'exécution de priorité élevée, à prendre le pas sur celles de basse priorité. En cas d'égalité, la position des threads dans la file d'attente, déterminera leur ordre d'exécution, c'est-à-dire que le premier passera d'abord.

L'appel de la méthode yield() constitue l'un des moyens de permutation d'unités d'exécutions, en entraînant la mise en file d'attente du thread courant et en donnant la main à un autre thread en attente.

L'utilisation des méthodes sleep() contraint le thread courant à se mettre en pause afin que d'autres threads prennent le contrôle. Pendant cette période, l'ancien thread courant est bloqué. Au terme de la pause, l'unité d'exécution rejoint la file d'attente des exécutables avant de prendre à nouveau la main lorsqu'il y sera autorisé.

/**
 * La classe Pause permet d'insérer 
 * une pause dans le thread courant.
 */
public class Pause {
  public static void ralentir() {
    try {
      Thread.sleep(1000);
    }
    catch (InterruptedException e) {
      e.printStackTrace();
    }
  }  
  public static void ralentir(long s) {
    try {
      Thread.sleep(s * 1000);
    }
    catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

/**
 * La classe Application utilise une pause 
 * lors du déroulement du programme.
 */
public class Application {
  public static void main(String[] args) {
    int temps = 0;
    System.out.println("Début des traitements...");
    while(temps < 60){
      System.out.println("Un traitement quelconque...");
      temps += 3;
      Pause.ralentir(3);
    }
    System.out.println("Fin des traitements...");
  }
}

En outre, un thread courant ou exécutable peut être bloqué suite à l'invocation de la méthode suspend() et ne rejoindra la file d'attente des exécutables qu'à partir du moment où la méthode resume() sera appelée.

La mise en état d'attente d'un thread se produit lors de l'appel de la méthode wait(). Cet état peut durer pendant un certain temps ou jusqu'à ce que soit invoquée l'une des méthodes suivantes : notify() ou notifyAll().

Enfin, un thread devient mort dans le cas où la méthode stop() est appelée à partir d'un thread dans l'état nouveau, exécutable ou actif. Arrivé au terme de la méthode run(), l'unité d'exécution meurt également.

public class Arret implements Runnable {
    public static void main(String[] args) {
        Arret arret = new Arret();
        Thread thread = new Thread(arret);
        System.out.println("Démarrage du thread...");
        thread.start();

        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Arrêt du thread par une méthode dépréciée
        thread.stop();
    }
    public void run() {
        int compteur = 0;

        while (true) {
            System.out.println("Compteur = " + compteur);
            compteur++;

            try {
                Thread.sleep(100);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Toutes les méthodes concourant au cycle de vie d'un thread possède des caractéristiques différentes, si bien que certaines peuvent être directement utilisées dans la sous-classe de Thread (méthodes statiques : yield(), sleep(), wait()) et d'autres seulement à partir de l'instance de la classe étendue (start(), stop(), suspend(), resume(), ...).

Par ailleurs, bien que les méthodes stop(), suspend() et resume() existent, il est fortement déconseillé de les utiliser car elles peuvent occasionner de graves dysfonctionnements de l'application. La mort d'un thread entraîne une impossiblité de connaître ce qu'il faisait juste avant cet instant . Si cela intervenait en pleine sauvegarde d'un objet, alors ce dernier risquerait de devenir incohérent, et partant, illisible par la machine virtuelle alors dans l'incapacité de continuer le déroulement du programme.

Exemple [voir]
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Application extends JFrame implements Runnable {

    private Thread thread_principal;
    private JTextField txtLettre;
    private JButton btnSuspendre;
    private JButton btnReprendre;
    private JButton btnArreter;
    private JButton btnQuitter;

    public static void main(String[] args) {
        Application application = new Application();
        Thread thread = new Thread(application);
        thread.start();

    }
    public Application() {
        super("Démonstration - suspend(), resume() et stop()");
        this.initialiser();
    }
    public void run() {
        try {
            thread_principal = Thread.currentThread();
            int compteur = 0;

            while (true) {
                if(compteur > 25) compteur = 0;
                txtLettre.setText(String.valueOf((char)('A' + compteur++)));

                Thread.sleep(300);
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            thread_principal = null;
        }
    }
    private void suspendre() {
        if (thread_principal != null) {
            thread_principal.suspend();
        }
    }
    private void reprendre() {
        if (thread_principal != null) {
            thread_principal.resume();
        }
    }
    private void arreter() {
        if (thread_principal != null) {
            thread_principal.stop();
        }
    }
    private void quitter() {
        this.arreter();
        thread_principal = null;
        System.exit(0);
    }
    private void initialiser() {
        this.initPanneau();
        this.initFenetre();
    }
    private void initPanneau() {
        txtLettre = new JTextField();
        txtLettre.setEditable(false);
        txtLettre.setFont(new Font("Verdana", Font.BOLD, 72));
        txtLettre.setHorizontalAlignment(JTextField.CENTER);

        btnSuspendre = new JButton("Suspendre");
        btnSuspendre.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                suspendre();
            }
        });
        btnReprendre = new JButton("Reprendre");
        btnReprendre.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                reprendre();
            }
        });
        btnArreter = new JButton("Arrêter");
        btnArreter.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                arreter();
            }
        });
        btnQuitter = new JButton("Arrêter");
        btnQuitter.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                quitter();
            }
        });
        GridBagLayout gbl = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints(); 
        JPanel pan = (JPanel)this.getContentPane();
        pan.setLayout(gbl);
        placerComposants(pan, gbl, gbc, txtLettre, 
                         GridBagConstraints.BOTH, 
                         0, 0, 4, 1, 1, 1, 3, 3, 3, 3);
        placerComposants(pan, gbl, gbc, btnSuspendre, 
                         GridBagConstraints.BOTH, 
                         0, 1, 1, 1, 1, 0, 3, 3, 3, 3);
        placerComposants(pan, gbl, gbc, btnReprendre, 
                         GridBagConstraints.BOTH, 
                         1, 1, 1, 1, 1, 0, 3, 3, 3, 3);
        placerComposants(pan, gbl, gbc, btnArreter, 
                         GridBagConstraints.BOTH, 
                         2, 1, 1, 1, 1, 0, 3, 3, 3, 3);
        placerComposants(pan, gbl, gbc, btnQuitter, 
                         GridBagConstraints.BOTH, 
                         3, 1, 1, 1, 1, 0, 3, 3, 3, 3);
    }
    private void initFenetre() {
        Dimension tailleFenetre = this.getSize();
        Dimension tailleEcran = Toolkit.getDefaultToolkit().getScreenSize();
        if (tailleFenetre.height > tailleEcran.height)
            tailleFenetre.height = tailleEcran.height;
        if (tailleFenetre.width > tailleEcran.width)
            tailleFenetre.width = tailleEcran.width;
        this.setBounds(tailleEcran.width / 3,
                       tailleEcran.height / 3,
                      (tailleEcran.width * 1) / 3,
                      (tailleEcran.height * 1) / 3);
        this.setVisible(true);
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
    public void placerComposants(
                                  JPanel pere,
                                  GridBagLayout gbl, 
                                  GridBagConstraints gbc, 
                                  JComponent composant,
                                  int remplissage,
                                  int x, int y, 
                                  int l, int h, 
                                  double px, double py,
                                  int haut, int gauche, 
                                  int bas, int droite){
        gbc.insets = new Insets(haut, gauche, bas, droite);
        gbc.fill = remplissage;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = l;
        gbc.gridheight = h;
        gbc.weightx = px;
        gbc.weighty = py;
        gbl.setConstraints(composant, gbc);
        pere.add(composant);
    }
}

33.2 / La création des threads

La création et le lancement des threads passent obligatoirement par l'extension de la classe Thread ou de l'implémentation de l'interface Runnable.

L'héritage de la classe Thread possède l'inconvénient d'empêcher la classe de pouvoir hériter d'autres classes. C'est pourquoi l'implémentation de l'interface Runnable est plutôt conseillée pour la création de threads.

Une classe implémentant l'interface Runnable doit impérativement déclarer la méthode run() chargée de décrire les instructions que doit exécuter l'unité d'exécution.

class PremierThread implements Runnable {
  // Le constructeur
  PremierThread(){
    //Instructions...
  } 
  public void run() {
    // Instructions relatives à l'unité d'exécution
  }
}
  // Création du processus thread
  PremierThread t = new PremierThread();
  Thread thread = new Thread(t);
  // Démarrage du thread et exécution t.run()
  thread.start();
  // start() est une méthode de la classe Thread

Il est également possible de créer une classe héritant de Thread, dans laquelle la méthode run() est redéfinie en surchargeant la méthode héritée.

class PremierThread extends Thread {
  // Le constructeur
  PremierThread(){
    //Instructions...
  } 
  public void run() {
    // Instructions relatives à l'unité d'exécution
  }
}
  // Création du processus thread
  PremierThread thread = new PremierThread();
  // Démarrage du thread et exécution thread.run()
  thread.start();
    // start() est une méthode de la classe Thread

Une classe Thread encapsule les données et les méthodes associées à l'unité d'exécution.

L'héritage multiple n'étant pas autorisé par la plateforme Java, l'extension de la classe Thread ne peut être utilisée dans tous les cas de programmation orientée objet, notamment lorsqu'une classe doit hériter d'un composant graphique.

public class CreationThread extends Thread {
  private int opG;
  private int opD;
  private long temps;
  public CreationThread(int opD, int opG, long temps) {
    this.opD = opD;
    this.opG = opG;
    this.temps = temps;
    //Définit un thread démon
    setDaemon(true);
  }
  
  public void run(){
    int resultat = 0;
    try{
      while(true){
        resultat = opD + opG;
        System.out.print(opG + " + ");
        //Temporisation du thread courant
        sleep(temps);
        System.out.print(opD + " = " + resultat);
        System.out.print(" (Normalement : " _
                      + opD + " + " + opG + ")\n");
      }
    }
    catch(InterruptedException e){
      e.printStackTrace();
    }
  }
}

import java.io.*;
public class Test {
  public static void main(String[] args){
    try{
      System.out.println("Appuyez sur la touche "
                       + "'Entrée' pour arréter le programme !");
      //Instanciation et démarrage de 5 threads...
      Thread t1 = new CreationThread(10, 101, 100L);
      Thread t2 = new CreationThread(20, 202, 200L);
      Thread t3 = new CreationThread(30, 303, 300L);
      Thread t4 = new CreationThread(40, 404, 400L);
      Thread t5 = new CreationThread(50, 505, 500L);
      t1.start();
      t2.start();
      t3.start();
      t4.start();
      t5.start();
      System.in.read();
      System.out.println("Fin du programme !");
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }
}

33.3 / Le thread principal

Le thread principal et les éventuels nouveaux threads interagissent entre eux d'une certaine façon.

Le thread principal constitue l'assise des threads utilisateurs et plus particulièrement des threads démons.

Dans le cas d'emploi de threads utilisateur, ceux-ci prolongent le déroulement du thread principal. Ainsi, tant que tous les threads utilisateur ne sont pas terminés, le thread principal continue à exister.

public class RelationThreads extends Thread {
    public RelationThreads() {
      super();
    }
    public void run() {
        for ( int i = 0; i < 20; i++ ) {
            afficher(i + " - Exécution du Thread");
            try {
                Thread.sleep(10);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void afficher(String msg) {
        Thread t = Thread.currentThread();
        System.out.println(msg + " : " + t.getName());
        try {
            Thread.sleep(10);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        RelationThreads t = new RelationThreads();
        t.setName("Thread utilisateur");
        t.start();

        for ( int i = 0; i < 10; i++ ) {
            t.afficher(i + " - Programme principal");
        }
    }
}

/* Affiche : 
Début du thread principal
0 - Programme principal : main
0 - Exécution du Thread : Thread utilisateur
1 - Exécution du Thread : Thread utilisateur
1 - Programme principal : main
2 - Exécution du Thread : Thread utilisateur
2 - Programme principal : main
3 - Exécution du Thread : Thread utilisateur
3 - Programme principal : main
4 - Programme principal : main
4 - Exécution du Thread : Thread utilisateur
5 - Programme principal : main
5 - Exécution du Thread : Thread utilisateur
6 - Programme principal : main
6 - Exécution du Thread : Thread utilisateur
7 - Exécution du Thread : Thread utilisateur
7 - Programme principal : main
8 - Exécution du Thread : Thread utilisateur
8 - Programme principal : main
9 - Exécution du Thread : Thread utilisateur
9 - Programme principal : main
10 - Exécution du Thread : Thread utilisateur
Fin du thread principal
11 - Exécution du Thread : Thread utilisateur
12 - Exécution du Thread : Thread utilisateur
13 - Exécution du Thread : Thread utilisateur
14 - Exécution du Thread : Thread utilisateur
15 - Exécution du Thread : Thread utilisateur
16 - Exécution du Thread : Thread utilisateur
17 - Exécution du Thread : Thread utilisateur
18 - Exécution du Thread : Thread utilisateur
19 - Exécution du Thread : Thread utilisateur*/

Le thread principal influe directement sur le déroulement d'un thread démon, puisque lorsque le thread principal s'arrête, le thread démon termine immédiatement son exécution.

public class RelationThreads extends Thread {
    public RelationThreads() {
      super();
    }
    public void run() {
        for ( int i = 0; i < 100; i++ ) {
            afficher(i + " - Exécution du Thread");
        }
    }
    public void afficher(String msg) {
        Thread t = Thread.currentThread();
        System.out.println(msg + " : " + t.getName());
        try {
            Thread.sleep(10);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        System.out.println("Début du thread principal");
        RelationThreads t = new RelationThreads();
        t.setDaemon(true);
        t.setName("Thread démon");
        t.start();

        for ( int i = 0; i < 10; i++ ) {
            t.afficher(i + " - Programme principal");
        }
        System.out.println("Fin du thread principal");
    }
}

/* Affiche : 
Début du thread principal
0 - Programme principal : main
0 - Exécution du Thread : Thread démon
1 - Exécution du Thread : Thread démon
1 - Programme principal : main
2 - Exécution du Thread : Thread démon
2 - Programme principal : main
3 - Programme principal : main
3 - Exécution du Thread : Thread démon
4 - Exécution du Thread : Thread démon
4 - Programme principal : main
5 - Exécution du Thread : Thread démon
5 - Programme principal : main
6 - Exécution du Thread : Thread démon
6 - Programme principal : main
7 - Exécution du Thread : Thread démon
7 - Programme principal : main
8 - Exécution du Thread : Thread démon
8 - Programme principal : main
9 - Exécution du Thread : Thread démon
9 - Programme principal : main
10 - Exécution du Thread : Thread démon
Fin du thread principal
11 - Exécution du Thread : Thread démon
12 - Exécution du Thread : Thread démon
*/

Plusieurs threads sont démarrés automatiquement par la machine virtuelle Java et fonctionnent indépendamment des threads créés par l'utilisateur. Ces threads permettent d'accomplir des tâches précises, telles que l'activation du collecteur de déchêts (Finalizer), la gestion de composants graphiques (AWT-Windows), la gestion événementielle (AWT-EventQueue-0), etc..

public class Interruption extends Thread {
  public Interruption() {
    super();
  }
  public void run() {
    long i = 0;
    while (true) {
      long premier = -1;
      if (verifierPremier(i)) {
        premier = i;
        NombrePremier objet = new NombrePremier(
                                       String.valueOf(premier));
      }
      i++;
    }
  }
  public boolean verifierPremier(long nombre) {
    if (nombre < 0)
      return false;
    else if (nombre < 4)
      return true;
    else {
      for (int i = 4; i <= nombre / 2; i++) {
        if (nombre != i && nombre % i == 0)
          return false;
      }
    }
    return true;
  }

  public static void main(String[] args) {
    Interruption thread = new Interruption();
    thread.start();
    while (thread.isAlive()) {
      try {
        Thread.sleep(500);
      }
      catch (InterruptedException e) {
      }
    }
  }
}

public class NombrePremier {
  private String valeur;
  public NombrePremier(String valeur) {
    this.valeur = valeur;
  }
  public String getValeur() {
    return this.valeur;
  }
  public void setValeur(String valeur) {
    this.valeur = valeur;
  }
  protected void finalize() throws Throwable {
    System.out.println("Invocation de la méthode finalize()");
    System.out.println("Contenu de l'objet : " + valeur);
    System.out.println("Nom du thread courant : "
                       + Thread.currentThread().getName());
    this.valeur = null;
  }
}
/* Affiche
...
Invocation de la méthode finalize()
Contenu de l'objet : 70879
Nom du thread courant : Finalizer
Invocation de la méthode finalize()
Contenu de l'objet : 72617
Nom du thread courant : Finalizer
Invocation de la méthode finalize()
Contenu de l'objet : 73453
Nom du thread courant : Finalizer
...
*/

33.4 / Les threads démons et utilisateurs

Les unités d'exécution (ou threads) peuvent être du type démon ou utilisateur, respectivement dépendant ou indépendant du thread d'où ils ont été lancés.

Un thread démon dépend du thread parent qui l'a lancé et s'exécute en arrière plan de ce-dernier. Par exemple, lorsque la méthode principale (main) du thread parent se termine, les éventuels threads démons lancés cessent également d'exister et cela même si leurs traitements étaient en cours d'exécution.

Afin de pallier à cette situation, il est possible d'utiliser la méthode isAlive() afin de tester si le thread démon est encore actif, et de prendre les mesures appropriées dans le but de retarder la fin du thread courant.

while (threadDemon.isAlive()){
  //Mise en sommeil du thread courant...
  Thread.sleep(100);
}

Un thread utilisateur peut poursuivre son exécution même si son thread parent est terminé. Par exemple, si la méthode main() du thread parent s'arrête, les éventuels threads utilisateurs continuent malgré cela, leur traitement.

Un thread démon ou utilisateur se définit par l'intermédiaire d'une méthode setDaemon() de la classe Thread.

//Définit un thread en tant que démon
unThread.setDaemon(true);
//Définit un thread utilisateur
Thread.setDaemon(false);

La méthode setDaemon() doit impérativement être appelée avant que l'unité d'exécution ne soit démarrée, dans le cas contraire une exception IllegalThreadStateException serait levée.

Thread unThread = new ClasseThread(arguments);
unThread.setDaemon(true);
unThread.start();

Il est possible également, qu'une exception SecurityException puisse être levée si le thread courant n'est pas autorisé à modifier une unité d'exécution fils.

La méthode isDaemon() retournant une valeur booléenne, permet de tester si un unité d'exécution, est (true) ou n'est pas (false) un thread démon.

//Classe Boucle descendante de la superclasse Thread
public class Boucle extends Thread {
  int fin;
  int n;
  //Le constructeur définit le nombre d'itération à accomplir.
  public Boucle (int fin, int n) {
    this.fin = fin;
    this.n = n;
  }
  //Redéfinition de la méthode run().
  public void run() {
    System.out.println(this.getName() + " démarre...");
    //Boucle
    for (int i = 1; i <= fin ; i++) {
      //Affichage du nom du thread courant et du compteur.
      System.out.println(this.getName() + " ("
                                 + (this.isDaemon() ? "   Démon   " : "Utilisateur") 
                                 + ") " + i);
      try{
        //Pause de n ms.
        Thread.sleep(n);
      }
      catch(InterruptedException e){
        e.printStackTrace();
      }
    }
    System.out.println(this.getName() + " se termine...");
  }
}

//Classe Application
public class Application {
  public static void main (String args[]) {
    //Instanciation de deux threads...
    int n = 50;
    Thread t0 = new Boucle (12, n);
    Thread t1 = new Boucle (90, n);
    Thread t2 = new Boucle (60, n);
    Thread t3 = new Boucle (30, n);
    //Déclaration de ce thread en tant qu'utilisateur.
    t0.setDaemon(false);
    //Déclaration des threads en tant que démons.
    t1.setDaemon(true);
    t2.setDaemon(true);
    t3.setDaemon(true);
    //Démarrage des threads...
    t0.start();
    t1.start();
    t2.start();
    t3.start();
    //Tant que des threads démons sont actifs...
    while (t1.isAlive() || t2.isAlive() || t3.isAlive()) {
      try {
        System.out.println("Au moins un thread est encore actif !");
        //Mise en sommeil du thread courant pendant n ms...
        Thread.sleep(n);
      } 
      catch (InterruptedException e) {
        e.printStackTrace();
        return;
      }
    }
    System.out.println("\nFin de la méthode main() !\n");
  }
}

Dans cet exemple simple, on peut remarquer qu'un thread démon s'arrête lorsque la méthode main() se termine, c'est-pourquoi, il est nécessaire de tester si les threads démons (t1, t2 et t3) sont encore actifs par l'intermédiaire de la méthode isAlive() afin de prolonger avec la méthode sleep() le cycle de vie du thread courant, c'est-à-dire, celui qui exécute la méthode principale et encapsule les autres threads. En outre, le thread utilisateur (t0) continue effectivement son exécution, y compris lorsque la méthode main() s'est effectivement terminée.

Par ailleurs, la synchronisation des threads est assurée en fournissant, lors de l'instanciation de toutes les unités d'exécution, une valeur n en millisecondes, employée dans les méthodes sleep() des deux classes mises en jeu. L'affectation d'une valeur différente entraînera indubitablement un fonctionnement asynchrone «cahotique».

Dans le cas où le thread utilisateur t0 possèderait un nombre d'itérations supérieur aux threads démons, en l'occurrence que t0 ait une espérance de vie plus longue que les threads t1, t2 et t3. Alors ces derniers se termineront correctement en bénéficiant du temps d'exécution du thread utilisateur au sein de la méthode main(). Autrement dit, tant qu'il existe au moins un thread utilisateur actif, des threads démons pourront s'exécuter.

//Classe Application
public class Application {
  public static void main (String args[]) {
    //Instanciation de deux threads...
    int n = 50;
    Thread t0 = new Boucle (120, n);
    Thread t1 = new Boucle (90, n);
    Thread t2 = new Boucle (60, n);
    Thread t3 = new Boucle (30, n);
    //Déclaration de ce thread en tant qu'utilisateur.
    t0.setDaemon(false);
    //Déclaration des threads en tant que démons.
    t1.setDaemon(true);
    t2.setDaemon(true);
    t3.setDaemon(true);
    //Démarrage des threads...
    t0.start();
    t1.start();
    t2.start();
    t3.start();
    System.out.println("\nFin de la méthode main() !\n");
  }
}

Enfin, dans cet exemple cinq threads s'exécutent simultanément, quatre sont créés artificiellement et un autre, englobant ceux précités, est créé automatiquement lors du démarrage du programme. C'est pourquoi, si l'on modifie la valeur n de l'instruction Thread.sleep(n) dans la boucle while, le nombre d'exécution des threads enfants se modifieront proportionnellement par rapport au temps de pause du thread parent.

public class Application extends Thread {
  private static int n = 0; //nombre d'applications lancées
  private static int nb = 0; //nombre de threads exécutés
  Application () {
        n++;
        System.out.println("Le thread " 
                  + (this.isDaemon() ? "démon " : "utilisateur ") 
                  + Thread.currentThread().getName() 
                  + "-" + n + " démarre..." );
    }

    public void run() {
    int loc = nb;
        System.out.println(Thread.currentThread().getName() + " ("
            + (this.isDaemon() ? "   Démon   " : "Utilisateur")
                + ") demarre..." );
         try {
             Thread.sleep(100);
         }
         catch (InterruptedException e) {
           e.printStackTrace();
            return;
         }
    loc++;
    nb = loc;
    System.out.println("loc = " + loc + "; nb = " + nb);
        System.out.println(Thread.currentThread().getName() 
                                                                               + " se termine.");
    }

    public static void main(String args[]) {
        System.out.println("Le thread main() principal demarre..");
        // Création de 3 threads
        for (int i=0; i < 3; i++) {
            Thread app = new Application();
            app.start();
        }
        System.out.println("nb = " + nb + "; n = " + n);
        System.out.println("Le thread main() principal se termine.");
    }
}

Dans cet exemple, si l'on supprime le bloc try... catch permettant d'appliquer une pause au thread courant, le programme fonctionne très différemment puisque la simultanéité des threads n'est plus effective. Chaque thread main s'exécute les uns après les autres et se termine lorsque le thread principal s'arrête. Quant aux threads utilisateurs, on remarquera qu'ils s'exécutent séquentiellement, lorsqu'un s'arrête, le suivant prend le relai.

Les variables statiques n et nb fournissent un résultat différent avant la fin du programme, car la première compte les instanciation de la classe Application et la seconde tente de dénombrer les threads main au sein de la méthode run() sans y parvenir.
Le résultat nul de nb est dû au fonctionnement simultané des threads.

En supprimant le bloc try... catch de la méthode run(), le contenu des variables n et nb devient identique, dû à un fonctionnement séquentiel des threads.

Téléchargez les exemples

33.5 / L'arrêt des threads

Les threads se terminent de différentes manières selon qu'ils soient démons ou utilisateurs.

La méthode Runtime.exit() arrête tous les threads en cours d'exécution.

Un thread démon continue indéfiniment si aucune précaution n'a été prise pour l'arrêter.

Les threads utilisateurs se finissent lorsque les instructions au sein de leur méthode run() sont toutes exécutées.

La méthode stop() est à prohiber pour stopper un thread. Cette méthode a été dépréciée en raison des risques qu'elle engendre. En effet, des blocages sévères (deadlock) ou des incohérences de données peuvent survenir suite à l'emploi de cette méthode. En outre, l'appel de la méthode stop() sur un objet Thread peut entraîner la levée d'une erreur ThreadDeath, qu'il est très difficile de gérer correctement.

De la même façon, la suspension et la reprise d'un thread ne peuvent être accomplis respectivement par les méthodes suspend() et resume(). Ces fonctionnalités doivent être programmés d'une manière différente.

Il existe plusieurs solutions pour simuler le fonctionnement des méthodes stop(), suspend() et resume(). L'une d'elles consite à utiliser des champs qui indiqueront au thread comment se comporter.

Exemple [voir]
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class AppliCompteur extends JPanel implements Runnable {
    private Thread threadEnCours;
    private JTextField txtCompteur;
    //Champs concourrant à remplacer les méthodes dépréciées
    //suspend(), resume() et stop()
    private volatile boolean demarre;
    private volatile boolean suspension;
    private volatile boolean arret;

    public AppliCompteur() {
        demarre = true;
        arret = true;

        txtCompteur = new JTextField();
        txtCompteur.setEditable(false);

        JButton btnSuspension = new JButton("Suspendre");
        JButton btnReprendre = new JButton("Reprendre");
        JButton btnDemarrer = new JButton("Démarrer");
        JButton btnSortir = new JButton("Sortir");

        btnSuspension.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                suspendre();
            }
        });
        btnReprendre.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                reprendre();
            }
        });
        btnDemarrer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                demarrer();
            }
        });
        btnSortir.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                sortir();
            }
        });
        this.setLayout(new GridLayout(5, 1, 3, 3));
        this.add(txtCompteur);
        this.add(btnDemarrer);
        this.add(btnSuspension);
        this.add(btnReprendre);
        this.add(btnSortir);
    }
    private void suspendre() {
        suspension = true;
    }
    private void reprendre() {
        suspension = false;
    }
    private void demarrer() {
        if(demarre)
        arret = false;
    }
    public void sortir() {
        arret = true;
        if (threadEnCours != null) {
            threadEnCours.interrupt();
        }
        System.exit(0);
    }
    private void attendreSuspension() throws InterruptedException {
        while (suspension) {
            Thread.sleep(200);
        }
    }
    private void attendreDemarrage() throws InterruptedException {
        while (demarre && arret) {
            Thread.sleep(200);
        }
        demarre = false;
    }

    public void run() {
        try {
            threadEnCours = Thread.currentThread();
            //Attendre jusqu'à activation du bouton Démarrer
            attendreDemarrage();
            int compteur = 1;
            //Continuer tant que le bouton Sortir n'a pas été activé
            while (!arret) {
                txtCompteur.setText(String.valueOf(compteur));
                Thread.sleep(500);
                if(compteur % 10 == 0) 
                    compteur = 1;
                else
                    compteur++;
                //Attendre jusqu'à activation du bouton Suspendre
                attendreSuspension();
            }
        }
        catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        finally {
            threadEnCours = null;
        }
    }

    public static void main(String[] args) {
        AppliCompteur appli = new AppliCompteur();
        Thread t = new Thread(appli);
        t.start();

        JFrame f = new JFrame("Démonstration");
        f.setContentPane(appli);
        f.pack();
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

33.5.1 / La méthode sleep()

Le thread courant peut subir une interruption temporaire d'un certain nombre de millisecondes en employant la méthode statique Thread.sleep().

//Applique une pause de une seconde
Thread.sleep(1000);

Cette méthode ne doit pas s'utiliser sur une instance de la classe Thread.

Il est donc possible d'interrompre temporairement un thread et de le reprendre après qu'une condition soit vérifiée.

public static void patienter(Thread[] operations) {
    for (int i = 0; i < operations.length; i++) {
        //Teste l'activité du thread
        if (operations[i].isAlive()) {
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            i = 0; // Réinitialise la boucle for
        }
    }
}

Une boucle infinie se poursuit tant que tous les threads operations sont encore en activité. Dès que tous les threads operations ont été parcourus par la boucle for, alors le thread courant reprend à son tour son déroulement.

La méthode sleep() peut lancer une interruption InterruptedException, signifiant que le thread courant est interrompu par l'appel de la méthode interrupt() sur un autre thread.

public class DemoSleep extends Thread {
    private long debut;
    public DemoSleep() {
      debut = System.currentTimeMillis();
    }

    public void run() {
        for ( int i = 0; i < 20; i++ ) {
            afficher(i + " - Exécution du Thread", 100);
        }
    }
    public void afficher(String msg, int pause) {
        Thread t = Thread.currentThread();
        System.out.println(msg + " : " + t.getName() 
                        + "(" + (temps - debut) + " ms)");
        try {
            Thread.sleep(pause);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        System.out.println("Début du thread principal");
        RelationThreads t = new RelationThreads();
        t.setName("Thread utilisateur");
        t.setDaemon(false);
        t.start();

        for ( int i = 0; i < 10; i++ ) {
            t.afficher(i + " - Programme principal", 300);
        }
        System.out.println("Fin du thread principal");
    }
}
/*Affiche :
Début du thread principal
0 - Programme principal : main
0 - Exécution du Thread : Thread utilisateur
1 - Exécution du Thread : Thread utilisateur
2 - Exécution du Thread : Thread utilisateur
1 - Programme principal : main
3 - Exécution du Thread : Thread utilisateur
4 - Exécution du Thread : Thread utilisateur
5 - Exécution du Thread : Thread utilisateur
2 - Programme principal : main
6 - Exécution du Thread : Thread utilisateur
7 - Exécution du Thread : Thread utilisateur
8 - Exécution du Thread : Thread utilisateur
3 - Programme principal : main
9 - Exécution du Thread : Thread utilisateur
10 - Exécution du Thread : Thread utilisateur
11 - Exécution du Thread : Thread utilisateur
4 - Programme principal : main
12 - Exécution du Thread : Thread utilisateur
13 - Exécution du Thread : Thread utilisateur
14 - Exécution du Thread : Thread utilisateur
5 - Programme principal : main
15 - Exécution du Thread : Thread utilisateur
16 - Exécution du Thread : Thread utilisateur
17 - Exécution du Thread : Thread utilisateur
6 - Programme principal : main
18 - Exécution du Thread : Thread utilisateur
19 - Exécution du Thread : Thread utilisateur
7 - Programme principal : main
8 - Programme principal : main
9 - Programme principal : main
Fin du thread principal
*/

33.5.2 / La méthode yield()

La méthode yield() applique une pause à l'exécution du thread courant, afin de libérer le processeur pour d'autres unités d'exécution en attente.

A l'instar de la méthode sleep(), la méthode yield() étant déclarée statique, ne peut être invoquée sur une instance de la classe Thread.

public class Pause {
    public static void main(String args[]) {
        Tache thread1 = new Tache("1");
        Tache thread2 = new Tache("2");
        thread1.start();
        thread2.start();

        while (true) {
            System.out.println("Thread principal");
            Thread.yield();
        }
    }
}
class Tache extends Thread {
    public Tache(String s) {
        super(s);
    }
    public void run() {
        while (true) {
            System.out.println("Thread n° " + this.getName());
            Thread.yield();
        }
    }
}

Dans cet exemple, trois threads sont mis en concurrence (thread1, thread2 et le thread principal). Chacun, après un tour de boucle, cède sa place à un autre thread, si bien que les threads se chevauchent, évitant ainsi que l'un d'eux s'exécute deux fois de suite.

La méthode yield() s'avère particulièrement utile dans un contexte où d'autres threads possèdent la même priorité. Toutefois, l'ordonnanceur ne garantit pas quel sera le prochain thread à être exécuté.

33.5.3 / La méthode interrupt()

La méthode interrupt() permet d'interrompre un thread en cours d'exécution d'une méthode sleep(), join() ou wait().

Thread thread = new Thread(...);
thread.interrupt();

Les méthodes sleep(), join() et wait() produisent une exception InterruptedException, lorsqu'une interruption a été demandée. Si le thread n'exécute pas une des méthodes précitées, la méthode interrupt() modifie l'état d'un indicateur qui pourra être consulté pour gérer éventuellement l'événement survenu.

L'interruption n'affecte que le déroulement d'une méthode susceptible de produire une exception InterruptedException. Le thread en lui même continue à exécuter les instructions de la méthode concernée.

public class Interruption extends Thread {
  public Interruption() {
      super();
  }
  public void run() {
    for (int i = 0; i < 5; i++) {
        try {
          for (int j = 0; < 10; j++) {
            System.out.println(i + " " + j);
            Thread.sleep(1000);
          }
        }
        catch (InterruptedException e) {
          System.out.println("Interruption du thread utilisateur !");
        }
    }
  }
  public static void main(String[] args) {
    Interruption thread = new Interruption();
    thread.start();
    while(thread.isAlive()) {
     try {
       Thread.sleep((long)(Math.random() * 10000));
       thread.interrupt();
     }
     catch (InterruptedException e) {
     }
    }
  }
}

/* Affiche :
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
Interruption du thread utilisateur !
1 0
1 1
1 2
1 3
1 4
1 5
Interruption du thread utilisateur !
2 0
2 1
Interruption du thread utilisateur !
3 0
3 1
3 2
Interruption du thread utilisateur !
4 0
4 1
Interruption du thread utilisateur !
*/

Il est possible de détecter l'appel de la méthode d'interruption, ou plus exactement le positionnement d'un indicateur, au sein de l'objet Thread, enjoignant au thread courant de s'interrompre. La méthode isInterrupted() peut être utilisée pour découvrir ce changement d'état de l'indicateur. Dans le cas ou le thread n'exécute pas une méthode sleep(), join() et wait(), cette méthode peut s'avérer très utile.

public class Interruption extends Thread {
    public Interruption() {
        super();
    }
    public void run() {
        long i = 0;
        while (true) {
            long premier = -1;
            if (verifierPremier(i))
                premier = i;
            i++;
            if (premier > 0 && this.isInterrupted()) {
                System.out.println("Le thread a été interrrompu !");
                System.out.println("Nombre premier : " + premier);
                premier = -1;
                break;
            }
        }
    }
    public boolean verifierPremier(long nombre) {
        if (nombre < 0) {
            return false;
        }
        else if (nombre < 4) {
            return true;
        }
        else {
            for (int i = 2; i <= nombre / 2; i++) {
                if (nombre != i && nombre % i == 0) {
                    return false;
                }
            }
        }
        return true;
    }
    public static void main(String[] args) {
        Interruption thread = new Interruption();
        thread.start();
        while (thread.isAlive()) {
            try {
                Thread.sleep((long) (Math.random() * 500));
                thread.interrupt();
            }
            catch (InterruptedException e) {
            }
        }
    }
}
/* Affiche :
Le thread a été interrrompu !
Nombre premier : 3761
*/

Une aute méthode interrupted() retourne le même indicateur d'appel de la méthode interrupt(). La différence par rapport à la méthode isInterrupted() réside que celle-ci est une méthode de classe et donc s'applique sur le nom de la classe Thread.

if(Thread.interrupted())
  System.out.println("Le thread a été interrrompu !");
//Equivalent à
if(Thread.currentThread().interrupted())
  System.out.println("Le thread a été interrrompu !");

Lorsqu'une unité d'exécution est interrompue par l'invocation de la méthode interrupt(), une exception InterruptedException est lancée par certaines méthodes, en l'occurrence sleep(), join() et wait(). L'interruption peut donc être gérée à partir d'un bloc catch().

public class EstimationPI extends Object implements Runnable {
    public static void main(String[] args) {
        EstimationPI estimPI = new EstimationPI(0.000000001);
        Thread thread = new Thread(estimPI);
        thread.start();

        try {
            Thread.sleep(10000);
            thread.interrupt();
        }
        catch (InterruptedException e) {
        }
    }

    private double estimationPI;
    private double precision;

    public EstimationPI(double precision) {
        this.precision = precision;
        this.estimationPI = 0.0;
    }
    public void run() {
        try {
            System.out.println("CALCUL APPROCHE DE PI "
                             + "AVEC UNE PRECISION DE " + precision);
            System.out.println(Math.PI + " -> Math.PI");
            calculerPI(this.precision);
            afficherEstimation();
        }
        catch (InterruptedException e) {
            System.out.println("FIN DE LA PAUSE SUR "
                             + "LE THREAD PRINCIPAL !");
            afficherEstimation();
        }
    }
    private void calculerPI(double precision) 
                                   throws InterruptedException {
        long iteration = 0;
        int signe = -1;

        while (Math.abs(estimationPI - Math.PI) > this.precision) {
            if (Thread.interrupted()) {
                throw new InterruptedException();
            }
            iteration++;
            signe = -signe;
            this.estimationPI += signe * 4.0 / ((2 * iteration) - 1);
        }
    }
    private void afficherEstimation() {
        System.out.println(estimationPI + " -> ESTIMATION DE PI");
    }
}

33.5.4 / La méthode isAlive()

Un thread indique qu'il est encore en vie (true) ou mort (false), par l'intermédiaire de la méthode d'instance isAlive().

if(thread.isAlive())
    System.out.println("Le thread est toujours actif !");
else
    System.out.println("Le thread est terminé !");

Bien que l'objet Thread soit encore accessible, il n'est plus possible, si le résultat de la méthode isAlive() est false, de relancer l'exécution du thread mort. Puisqu'inutilisable, il peut être utile de libérer ses ressources en le déréférençant par l'intermédiaire d'une valeur null.

if(thread.isAlive())
    thread = null;

Dans le cas des threads démons, la vérification de l'existence de ce type d'unités d'exécution peut se révéler très utile pour maintenir actif le thread principal.

public class RelationThreads extends Thread {
    private long debut;
    private int pause;

    public RelationThreads(int pause) {
        this.debut = System.currentTimeMillis();
        this.pause = pause;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            afficher(i + " - Exécution du Thread", pause);
        }
    }
    public void afficher(String msg, int pause) {
        long temps = System.currentTimeMillis();
        Thread t = Thread.currentThread();
        System.out.println(msg + " : " + t.getName() 
                        + "(" + (temps - debut) + " ms)");
        try {
            Thread.sleep(pause);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        System.out.println("Début du thread principal");
        RelationThreads t1 = new RelationThreads(100);
        t1.setName("Thread utilisateur 1");
        t1.setDaemon(true);
        t1.start();

        RelationThreads t2 = new RelationThreads(200);
        t2.setName("Thread utilisateur 2");
        t2.setDaemon(true);
        t2.start();

        boolean fin1 = false;
        boolean fin2 = false;
        while (true) {
            if (!fin1 && !t1.isAlive()) {
                System.out.println("Fin de " + t1.getName());
                t1 = null;
                fin1 = true;
            }
            if (!fin2 && !t2.isAlive()) {
                System.out.println("Fin de " + t2.getName());
                t2 = null;
                fin2 = true;
            }
            if(fin1 && fin2) break;
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Fin du thread principal");
    }
}
/* Affiche :
Début du thread principal
0 - Exécution du Thread : Thread utilisateur 2(0 ms)
0 - Exécution du Thread : Thread utilisateur 1(0 ms)
1 - Exécution du Thread : Thread utilisateur 1(94 ms)
1 - Exécution du Thread : Thread utilisateur 2(204 ms)
2 - Exécution du Thread : Thread utilisateur 1(204 ms)
3 - Exécution du Thread : Thread utilisateur 1(297 ms)
2 - Exécution du Thread : Thread utilisateur 2(407 ms)
4 - Exécution du Thread : Thread utilisateur 1(407 ms)
5 - Exécution du Thread : Thread utilisateur 1(500 ms)
3 - Exécution du Thread : Thread utilisateur 2(594 ms)
6 - Exécution du Thread : Thread utilisateur 1(610 ms)
7 - Exécution du Thread : Thread utilisateur 1(704 ms)
4 - Exécution du Thread : Thread utilisateur 2(797 ms)
8 - Exécution du Thread : Thread utilisateur 1(813 ms)
9 - Exécution du Thread : Thread utilisateur 1(907 ms)
5 - Exécution du Thread : Thread utilisateur 2(1000 ms)
Fin de Thread utilisateur 1
6 - Exécution du Thread : Thread utilisateur 2(1204 ms)
7 - Exécution du Thread : Thread utilisateur 2(1407 ms)
8 - Exécution du Thread : Thread utilisateur 2(1594 ms)
9 - Exécution du Thread : Thread utilisateur 2(1797 ms)
Fin de Thread utilisateur 2
Fin du thread principal
*/

33.6 / La jointure de threads

Une technique de jointure de thread est proposée par l'API Java pour l'enchaînement d'unités d'exécution.

La méthode join() permet d'implémenter cette technique. Un thread invoquant cette méthode place le thread courant (Thread.currentThread()) en état d'attente, jusqu'à ce que le thread soit achevé. De cette manière, d'autres threads se lançant après cette instruction s'exécuteront réellement dès que le thread, invoquant la méthode join(), soit effectivement achevé, c'est à dire qu'il ne soit plus considéré comme en activité (!thread.isAlive()).

Thread thread = new Thread();
Thread autreThread = new Thread();
thread.start();
thread.join();
autreThread.start();

L'ordre des instructions doit être respecté car dans le cas contraire, un fonctionnement inattendu se produirait. Le démarrage des threads à enchaîner doit se faire forcément après un appel à la méthode join().

La technique de jointure de threads permet de s'assurer que des threads dépendants entre eux et en particulier de leurs résultats finaux, puissent s'exécuter réellement chacun leur tour afin d'obtenir les résultats souhaités et non des résultats intermédiaires.

L'utilisation de la méthode join() est semblable au fonctionnement d'un unique appel de méthode, dans laquelle les tâches sont exécutées les unes après les autres. Il est, également, possible d'obtenir le même résultat avec une combinaison des méthodes sleep() et isAlive().

Exemple [voir]
public class Jointure implements Runnable {
    private int numThread;
    private int compteur;
    private int temps;
    private int valeur;

    public Jointure(int numThread, int compteur, int temps) {
        this.numThread = numThread;
        this.compteur = compteur;
        this.temps = temps;
        this.valeur = 0;
        System.out.println("Construction du thread  n°" + numThread);
    }
    public void run() {
        int increment = 1;
        while (true) {
            System.out.println("\tThread n°" + numThread 
                             + " : Compteur = " + increment);
            try {
                Thread.sleep(temps);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            valeur++;
            if (increment++ == compteur) {
                System.out.println("Thread n°" + numThread + " achevé !");
                valeur = compteur * numThread;
                break;
            }
        }
    }
    private static void lancerTraitement() {
        try {
          Jointure jointure1 = new Jointure(1, 8, 1500);
          Jointure jointure2 = new Jointure(2, 10, 1000);
          Thread thread1 = new Thread(jointure1);
          thread1.start();
          Thread thread2 = new Thread(jointure2);
          System.out.println("Jointure sur le premier thread...");
          thread1.join();
          System.out.println("Fin du premier thread et démarrage du second...");
          thread2.start();
          System.out.println("Jointure sur le second thread...");
          thread2.join();
          System.out.println("Fin du second thread "
                               + "et continuation du thread courant...");
          System.out.println("\tRésultat final du thread n°1 : " 
                               + jointure1.valeur);
          System.out.println("\tRésultat final du thread n°2 : " 
                               + jointure2.valeur);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        System.out.println("Démarrage de l'application...");

        lancerTraitement();

        System.out.println("Fin de l'application...");
    }
}

33.7 / Les groupes de threads

Le langage Java fournit un mécanisme de regroupement des threads. Les unités d'exécution regroupées peuvent ainsi être manipulées plus facilement par l'intermédaire d'un seul objet appelé ThreadGroup.

Plutôt que d'appeler une méthode d'interruption ou de destruction pour chaque threads, l'appel d'une seule méthode interrupt() ou destroy() dans ces cas serait nécessaire pour appliquer à un ensemble de threads une opération particulière.

Le système d'exécution place un thread à l'intérieur d'un groupe de threads durant sa construction. Lors de la création d'un thread, il est possbible soit d'autoriser le système d'exécution à mettre le nouveau thread dans un groupe de threads par défaut adéquat, soit de créer explicitement un nouveau groupe de threads. L'unité d'exécution est un membre permanent du groupe de threads qu'il rejoint lors de sa création. Il n'est pas possible de déplacer un thread vers un nouveau groupe après que le thread ait été créé.

Lorsqu'une application Java démarre, le système d'exécution crée un objet ThreadGroup dénommé main. Dans le cas des applets Java, le nom du groupe de threads sera différent. Ainsi, tous les threads créés à l'intérieur du thread principal (main ou autre) deviennent, par défaut des membres de ce groupe de threads.

public class GroupeDefaut extends Thread {

  private static int n = 0; //nombre d'applications lancées

  public GroupeDefaut () {
    n++;
    System.out.println("Le groupe de threads parent : " 
          + Thread.currentThread().getThreadGroup().getName() 
          + " [" + Thread.currentThread().getName() 
          + "-" + n + "]" );
  }

  public void run() {
    System.out.println("Le groupe de threads parent : " 
          + Thread.currentThread().getThreadGroup().getName() 
          + " [" + Thread.currentThread().getName() + "]");
    try {
      Thread.sleep(100);
    }
    catch (InterruptedException e) {
      e.printStackTrace();
      return;
    }
  }

  public static void main(String args[]) {
    System.out.println("Le groupe de threads par défaut : " 
          + Thread.currentThread().getThreadGroup().toString());
    // Création de 5 threads enfants
    for (int i=0; i < 5; i++) {
      Thread ue = new GroupeDefaut();
      //Déclaration de threads démons
      if (i % 2 == 0) ue.setDaemon(true);
      //Démarrage des threads...
      ue.start();
    }
    System.out.println("Nombre total de threads dans le groupe : " 
          + Thread.currentThread().getThreadGroup().activeCount());
  }
}

L'obtention de l'objet ThreadGroup d'appartenance au thread courant est possible en invoquant la méthode getThreadGroup().

ThreadGroup groupe = ue.getThreadGroup();

Lors de la création d'un nouveau thread, il est possible de spécifier son groupe d'appartenance dans un constructeur de la classe Thread, en spécifiant l'objet ThreadGroup désiré.

public class NouveauGroupeThread {
  public static void main(String[] args) {
    ThreadGroup groupe1 = new ThreadGroup("Nouveau groupe 1");
    ThreadGroup groupe2 = new ThreadGroup("Nouveau groupe 2");
    int i;
    System.out.println("Evolution des threads par groupes");
    System.out.println("Représentation : Nombre de threads "
                     + "dans les différents groupes et dans le groupe principal");
    Classe obj = new Classe();
    for (i = 0; i < 5; i++) {
      Thread ue;
      if (i == 0) 
        ue = new Classe();
      else if (i % 2 == 0)
        ue = new Thread(groupe1, obj, "L'unite d'execution " + i);
      else
        ue = new Thread(groupe2, obj, "L'unite d'execution " + i);
      ue.start();
      System.out.println(ue.getThreadGroup() + " : " 
               + ue.getThreadGroup().activeCount() + " " + Thread.activeCount());
    }
    Thread[] liste = new Thread[i + 1];
    Thread.currentThread().getThreadGroup().enumerate(liste);
    System.out.println("
Nom des threads (" + liste.length 
                     + ") dans le groupe principal");
    for(i = 0; i < liste.length; i++){
      System.out.println("	" + liste[i].getName());
    }
    int nbGrp = Thread.currentThread().getThreadGroup().activeGroupCount();
    ThreadGroup[] GroupesThreads = new ThreadGroup[nbGrp];
    Thread.currentThread().getThreadGroup().enumerate(GroupesThreads);

    System.out.print("
Nombre total de threads actifs dans le groupe courant : " 
            + Thread.currentThread().getThreadGroup().activeCount()
            + "
Nombre total de threads dans le premier groupe : " 
            + groupe1.activeCount()
            + "
Nombre total de threads dans le second groupe : " 
            + groupe2.activeCount()
            + "
Nombre total de groupe de threads dans le groupe courant : " 
            + Thread.currentThread().getThreadGroup().activeGroupCount()
            + "
Nombre total de threads dans les groupes enfants du groupe courant :");
    for(i = 0; i < GroupesThreads.length; i++){
      System.out.print(" " + GroupesThreads[i].activeCount());
    }
  }
}

// Classe étendant la classe Thread
public class Classe extends Thread {
  public static int cpt;
  public Classe(){
    cpt++;
  }

  public void run() {
    try {
      Thread.sleep(100);
    }
    catch (InterruptedException e) {
      e.printStackTrace();
      return;
    }
  }
}

Le décompte des threads actifs dans le groupe principal, reflète le nombre total de threads actifs dans tous les groupes, auquel s'ajoute le nombre des groupes créés. C'est-pourquoi dans cet exemple, l'expresssion Thread.currentThread().getThreadGroup().activeCount() comptabilise sept threads, en fait 5 threads utilisateurs, et 2 groupes de threads.

Téléchargez les exemples

33.8 / La priorité des threads

L'ordre d'exécution des threads en attente peut être géré par l'intermédiaire de l'affectation d'un niveau de priorités déterminé à chaque unité d'exécution créée.

La gestion des threads est parfois dépendante du système d'exploitation sous-jacent, si bien que le thread possèdant la priorité la plus élevé, peut ne pas être exécuté prioritairement. Sur les systèmes Unix et Macintosh, les priorités sont gérées rigoureusement, ce qui n'est pas le cas de tous les systèmes Microsoft, tel que Windows 95.

Normalement, le système d'exploitation devrait exécuter le thread possèdant la priorité la plus grande. Lorsque des threads possèdent des priorités égales, alors le premier dans la file d'attente est exécuté par le processeur.

Afin d'obtenir un fonctionnement identique sur n'importe quel système d'exploitation, il peut être préférable de contrôler l'ordre d'exécution des threads par l'intermédiaire des méthodes sleep() ou yield(), permettant de mettre en pause le thread courant afin que d'autres puissent s'exécuter également.

Les priorités des threads se situent dans un intervalle de 1 à 10. Trois constantes représentent les valeurs limites et médianes. Plus la valeur de la priorité est élevée, plus grande sera la priorité du thread pour l'accès au processeur.

MIN_PRIORITY : priorité minimum (1)
NORM_PRIORITY : priorité normale (5)
MAX_PRIORITY : priorité maximum (10)

La priorité normale est affectée par défaut à un nouveau thread.

Les threads exécutés automatiquement par la machine virtuelle Java, possèdent des niveaux de priorités prédéterminés. Par exemple, la priorité du thread Finalizer est fixée à 8, tandis que celle du thread principal vaut 5.

NiveauThread
4Screen Updater
5Thread utilisateur (défaut)
5main
5SunToolkit.PostEventQueue-0
5Signal dispatcher
5AWT-Windows
6AWT-EventQueue-0
8Finalizer
10Reference Handler
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AppliCompteur extends JPanel implements Runnable {
  private Thread threadEnCours;

  private JTextField txtCompteur;

  private volatile boolean demarre;
  private volatile boolean suspension;
  private volatile boolean arret;

  public AppliCompteur() {
    afficherInfos("Construction de l'interface graphique");
    demarre = true;
    arret = true;
    suspension = false;

    txtCompteur = new JTextField();
    txtCompteur.setEditable(false);

    JButton btnSuspension = new JButton("Suspendre");
    JButton btnReprendre = new JButton("Reprendre");
    JButton btnDemarrer = new JButton("Démarrer");
    JButton btnTerminer = new JButton("Terminer");

    btnSuspension.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        afficherInfos("Suspension");
        suspendre();
      }
    });
    btnReprendre.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        afficherInfos("Reprendre");
        reprendre();
      }
    });
    btnDemarrer.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        afficherInfos("Démarrer");
        demarrer();
      }
    });
    btnTerminer.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        afficherInfos("Terminer");
        sortir();
      }
    });
    this.setLayout(new GridLayout(5, 1, 3, 3));
    this.add(txtCompteur);
    this.add(btnDemarrer);
    this.add(btnSuspension);
    this.add(btnReprendre);
    this.add(btnTerminer);
  }
  private void suspendre() {
    suspension = true;
  }
  private void reprendre() {
    suspension = false;
  }
  private void demarrer() {
    if (demarre)
      arret = false;
  }
  public void sortir() {
    arret = true;
    demarre = true;
  }
  private void attendreDemarrage() throws InterruptedException {
    while (demarre && arret) {
      Thread.sleep(200);
    }
    demarre = false;
  }
  private void attendreSuspension() throws InterruptedException {
    while (suspension) {
      Thread.sleep(200);
    }
  }
  private void afficherInfos(String origine) {
    System.out.println(origine + " -> " 
                     + Thread.currentThread().getName() + " ( " 
                     + Thread.currentThread().getPriority() + " )");
  }
  public boolean verifierPremier(long nombre) {
    if (nombre < 0) {
      return false;
    }
    else if (nombre < 4) {
      return true;
    }
    else {
      for (int i = 2; i <= nombre / 2; i++) {
        if (nombre != i && nombre % i == 0) {
          return false;
        }
      }
    }
    return true;
  }
  public void run() {
    try {
      threadEnCours = Thread.currentThread();
      afficherInfos("Exécution du thread utilisateur");
      while(true) {
        this.attendreDemarrage();
        long compteur = 0;
        while (!arret) {
          if (verifierPremier(compteur)) {
            NombrePremier objet = new NombrePremier(
                                           String.valueOf(compteur));
            this.txtCompteur.setText(objet.getValeur());
            Thread.sleep(500);
          }
          compteur++;
          this.attendreSuspension();
        }
      }
    }
    catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    finally {
      threadEnCours = null;
    }
  }
  public static void main(String[] args) {
    final AppliCompteur appli = new AppliCompteur();
    appli.afficherInfos("Programme principal");
    final Thread t = new Thread(appli);
    t.setName("Compteur");
    t.start();
    JFrame f = new JFrame("Démonstration");
    f.setContentPane(appli);
    f.pack();
    f.setVisible(true);
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        appli.afficherInfos("Gestionnaire de fenêtre");
        t.interrupt();
        System.exit(0);
      }
    });
  }
}

public class NombrePremier {
  private String valeur;
  public NombrePremier(String valeur) {
    this.valeur = valeur;
  }
  public String getValeur() {
    return this.valeur;
  }
  public void setValeur(String valeur) {
    this.valeur = valeur;
  }
  protected void finalize() throws Throwable {
    System.out.println("Nombre premier [ " + valeur + " ] -> " 
         + Thread.currentThread().getName() + " ( " 
         + Thread.currentThread().getPriority() + " )");
    this.valeur = null;
  }
}

/* Affiche :
Construction de l'interface graphique -> main ( 5 )
Programme principal -> main ( 5 )
Exécution du thread utilisateur -> Compteur ( 5 )
Démarrer -> AWT-EventQueue-0 ( 6 )
Nombre premier [ 257 ] -> Finalizer ( 8 )
Nombre premier [ 251 ] -> Finalizer ( 8 )
Nombre premier [ 241 ] -> Finalizer ( 8 )
...
Nombre premier [ 2 ] -> Finalizer ( 8 )
Nombre premier [ 1 ] -> Finalizer ( 8 )
Nombre premier [ 0 ] -> Finalizer ( 8 )
Suspension -> AWT-EventQueue-0 ( 6 )
Reprendre -> AWT-EventQueue-0 ( 6 )
Terminer -> AWT-EventQueue-0 ( 6 )
Gestionnaire de fenêtre -> AWT-EventQueue-0 ( 6 )
*/

33.8.1 / L'affectation des priorités

La modification et l'obtention de la priorité d'une unité d'exécution s'effectuent en invoquant respectivement les méthodes setPriority() et getPriority().

// Affectation d'une nouvelle priorité de niveau 9.
unThread.setPriority(9);

// Récupération du niveau de priorité.
int priorite = unThread.getPriority();

Si l'argument fourni à la méthode setPriority() n'est pas compris entre 1 et 10, une exception IllegalArgumentException risque d'être levée.

Dans une application multi-threads, les priorités doivent être distribuées d'une manière cohérentes. En général, il existe un thread prédominant et d'autres de plus ou moins grande importance. Le premier doit possèder la priorité la plus élevée par rapport aux autres threads.

Exemple [voir]
public class Priorite extends Thread {
  private int temps;
  private int iterations;
  public static void main(String[] args) {
    Thread t1 = new Priorite(20, 50);
    Thread t2 = new Priorite(20, 50);
    Thread t3 = new Priorite(20, 50);
    t1.setName("Thread Priorite elevee");
    t2.setName("Thread Priorite basse");
    t3.setName("Thread Priorite normale");
    t1.setPriority(Thread.MAX_PRIORITY);
    t2.setPriority(Thread.MIN_PRIORITY);
    t2.setPriority(Thread.NORM_PRIORITY);
    t1.start();
    t2.start();
    t3.start();
  }
  public Priorite(int temps, int iterations) {
    this.temps = temps;
    this.iterations = iterations;
  }
  public void run() {
    for (int i = 0; i < iterations; i++) {
      System.out.println(this.getName() 
                              + " [" + this.getPriority() + "] : " 
                              + i);
      try {
        Thread.sleep(temps);
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

33.9 / La synchronisation des threads

Les unités d'exécution (ou threads) sont capables de s'exécuter simultanément en utilisant des ressources communes. Dans ce cas, il s'avère nécessaire de synchroniser les modifications apportées aux données, afin d'obtenir des valeurs cohérentes.

Deux utilisateurs agissant sur une variable au sein de threads distincts, simultanés et asynchrones, risqueraient de provoquer une dégradation du résultat, et dans le pire des cas un dysfonctionnement et un blocage (deadlock) du programme.

Le partage de données entre différents threads oblige le programmeur, à considérer l'état et l'activité de chacune des unités d'exécution et de gérer précisément l'accès concurrentiel aux ressources par les threads.

La plateforme Java possède un mécanisme de synchronisation des threads par l'obtention d'un moniteur. Ce mécanisme se dénomme l'exclusion mutuelle. Si plusieurs thrads tentent d'accéder simultanément à des portions de code synchronisées d'un objet particulier, alors un et un seul obtiendra le moniteur lui permettant d'exécuter le code synchronisé. Lorsque ce thread terminera le traitement de ce code, alors le moniteur se libérera afin qu'un autre thread puisse à son tour accédé à sa portion de code synchronisée. Ainsi, il devient impossible à des threads concurrents de modifier simultanément les données partagées d'un objet. L'intégrité des données est donc assurée par ce moyen.

Il existe deux moyens de synchroniser du code :

public class Synchronisation {
  private String nom;
  private String prenom;

  private static String[][] personnes = {
                             { "Theodore", "Roosevelt" },
                             { "George", "Marshall" }, 
                             { "Omar", "Bradley" },
                             { "Dwight", "Einsenhower" }, 
                             { "George", "Patton" },
                             { "Norman", "Cota" }, 
                             { "Matthew", "Ridgway" },
                             { "Thomas", "Barton" }, 
                             { "Lawton", "Collins" },
                             { "Douglas", "MacArthur" }
                                      };

  public synchronized void assigner(String nom, String prenom) {
    this.nom = nom;
    try {
      Thread.sleep((long) (Math.random() * 2000));
    }
    catch (InterruptedException x) {
    }
    this.prenom = prenom;
    afficher();
  }
  private void afficher() {
    String nom = Thread.currentThread().getName();
    System.out.println(Thread.currentThread().getName() 
                    + " produit " + this.prenom + " " + this.nom);
  }
  public static void main(String[] args) {
    final Synchronisation sync = new Synchronisation();
    for (int i = 0; i < personnes.length; i++) {
      final int indice = i;
      Runnable r = new Runnable() {
        public void run() {
          sync.assigner(
                        personnes[indice][0], 
                        personnes[indice][1]);
        }
      };
      Thread t = new Thread(r, "Thread-" + i);
      t.start();
      try {
        Thread.sleep(500);
      }
      catch (InterruptedException x) {
      }
    }
  }
}
/* Affiche sans le modificateur synchronized
Thread-1 produit Marshall George
Thread-0 produit Roosevelt Omar
Thread-3 produit Einsenhower George
Thread-4 produit Patton Norman
Thread-2 produit Bradley Norman
Thread-5 produit Cota Thomas
Thread-6 produit Ridgway Thomas
Thread-7 produit Barton Lawton
Thread-9 produit MacArthur Douglas
Thread-8 produit Collins Douglas

* Affiche avec le modificateur synchronized
Thread-0 produit Roosevelt Theodore
Thread-1 produit Marshall George
Thread-2 produit Bradley Omar
Thread-3 produit Einsenhower Dwight
Thread-4 produit Patton George
Thread-5 produit Cota Norman
Thread-6 produit Ridgway Matthew
Thread-7 produit Barton Thomas
Thread-8 produit Collins Lawton
Thread-9 produit MacArthur Douglas
*/

33.9.1 / Les sections critiques

Le langage Java fournit un mécanisme de synchronisation permettant de partager des ressources entre plusieurs threads. Cela a pour effet d'éviter des incohérences dans le fonctionnement d'un système multithreads, telles que la corruption des données partagées.

Les méthodes contenant du code critique, c'est à dire un ensemble d'opérations atomiques agissant sur des données sensibles, doivent être synchronisées.

Les opérations atomiques constituent des tâches qui ne fournissent pas de résultats intermédiaires. Par exemple, l'ajout d'un élément au sein d'une liste contenant des objets d'un type spécifique et dont la taille est limitée, demanderait :

33.9.2 / Le modificateur synchronized

Le modificateur synchronized permet de synchroniser des méthodes ou des blocs de codes.

Lorsqu'une classe déclare une ou plusieurs zones synchronisées, un verrou mutex (mutual exclusion) est créé par la machine virtuelle Java pour la classe ou pour son instance. C'est ce verrou qui doit être acquis par les threads pour accèder au code synchronisée. Le verrou mutex ressemble à une porte qui se ferme dès qu'une personne est dans un espace déterminé et s'ouvre dès qu'elle en est sortie pour laisser entrer une autre personne. La maison représente l'objet auquel est associé le verrou.

Si plusieurs instances d'une classe possèdant des zones synchronisées, sont utilisées par différents threads, alors il existera un verrou pour chacune des instances. Dans ce cas, les threads peuvent exécuter des sections critiques simultanément sur les objets auprès desquels, ils détiennent le verrou. Ainsi, plusieurs maisons peuvent ouvrir leur porte à plusieurs personnes dans le même laps de temps. Evidemmment, les personnes sont invitées à entrer un par un.

Un verrou possède une portée bien délimitée. Ces limites sont le début et la fin d'une section critique, c'est-à-dire, la première et la dernière instruction d'une méthode ou d'un bloc de code synchronisé. Réduire la portée d'un verrou permet d'optimiser les performances d'une application multi-threads. En effet, il est souhaitable d'englober essentiellement le code vraiment sensible dans un bloc synchronisé et de laisser les instructions non-critiques dans un espace qui pourra être exécuter parallèlement par plusieurs threads. Pour des opérations lourdes ne mettant pas en jeu des variables sensibles, telles que le chargement de fichier ou de ressources distantes, cela s'avère décisif afin de profiter pleinement des avantages qu'offrent les threads.

En outre, synchroniser des méthodes peut conduire à des interblocages dans des cas précis.

public class Interblocage {
  public int variableSensible = -1;
  public synchronized void ecrire(){
    while(true){
      try{
        if(variableSensible == -1){
          variableSensible = (int)(Math.random() * 1000);
          break;
        }
        Thread.sleep(100);
      }
      catch(InterruptedException e){}
    }
  }
  public synchronized int lire(){
    int valeur = variableSensible;
    variableSensible = -1;
    return valeur;
  }
}

Cette situation est un cas particulier d'interblocage mettant en jeu une condition variableSensible == -1 et un verrou mutex. La solution à ce problème consiste à synchroniser le bloc de code contenant la variable sensible. De cette manière, la boucle infinie n'empêche plus d'autres threads d'obtenir le verrou pour accèder à l'une et à l'autre des méthodes.

public void ecrire(){
  while(true){
    try{
      synchronized(this){
        if(variableSensible == -1)
          variableSensible = (int)(Math.random() * 1000);
      }
        Thread.sleep(100);
    }
    catch(InterruptedException e){}
  }
}

Les performances d'un objet, qui déclare des méthodes ou/et des blocs synchronisés, sont indubitablement affectées par l'acquisition du verrou d'exclusion mutuelle. Cela est inhérent à la synchronisation. Par exmple, la collection Vector sécurisée pour des accès concurrents, demeure assurément moins rapide qu'un objet ArrayList. Sécuriser des sections critiques améliore le fonctionnement d'une application multi-threads, mais se ressent aux niveaux de ses performances. Il faut donc un habile dosage entre la synchronisation indispensable et l'exigence d'optimisation des accès concurrents.

L'invocation de méthodes synchronisées au sein d'une méthode elle même synchronisée ne pose pas de problèmes. En effet, le thread peut accéder aux méthodes synchronisées imbriquées puisqu'il détient déjà le verrou depuis qu'il est entré dans la méthode parente. A partir de l'instant ou un verrou est acquis, toutes les méthodes synchronisées peuvent être appeleées par un thread exécutant une méthode synchronisée.

public synchronized int ecrire(){
  if(autoriser())
    variableSensible = (int)(Math.random() * 1000);
  return lire();
}
public synchronized boolean autoriser(){
 return variableSensible == -1;
}
public synchronized int lire(){
  int valeur = variableSensible;
  variableSensible = -1;
  return valeur;
}

Les blocs synchronisés peuvent être imbriqués. Les objets sur lesquels s'applique la synchronisation sont choisis en fonction des traitements qu'ils doivent subir dans la méthode. Effectivement, tant q'un objet sensible est concerné par des opérations, il doit être sécurisé. Dans le cas contraire, il risquerait de se retrouver dans un état instable préjudiciable pour le bon fonctionnement d'une application.

public void ajouterFragment(DocumentXML document, FragmentXML fragment){
  if(fragment == null || document == null) return;
  synchronized(fragment){
    if(fragment.hasChildNodes()){
      NodeList enfants = frgament.getChildNodes();
      synchronized(document){
        NodeList liste = document.getElementsByTagName(nom);
        String nom = fragment.getFirstChild().getNodeName();
        for(int i = 0; i < enfants.getLength(); i++){
          booelan trouve = false;
          for(int j = 0; j < liste.getLength(); j++){
            if(liste.item(j).isEqualNode(enfants.item(i)){
              trouve = true;
              break;
            }
          }
          if(!trouve)
            document.getDocumentElement().appendChild(fragment);
        }
      }
    }
  }
}
public void extraireFragment(DocumentXML document, FragmentXML fragment){
  XpathFactory fabrique = XPathFactory.newInstance();
  XPath xpath = fabrique.newXPath();
  XPathExpression expression = xpath.compile("/racine/element");
  synchronized(document){
    NodeList liste = (NodeList)expression.evaluate(
                                    document, 
                                    XPathConstants.NODESET);
    if(liste != null){
      synchronized(fragment){
        for(int i = 0; i < liste.getLength(); i++){
          fragment.appendChild(liste.item(i));
        }
      }
  }
}

Pour ce scénario, on imagine que les deux objets document et fragment sont communs à deux threads A et B et qu'ils accèdent simultanément et respectivement aux méthodes ajouterFragment() et extraireFragment.

Les interblocages représentent un risque inéluctable si lors de la conception d'une application, les accès concurrents n'ont pas été suffisamment étudiés. Outre le cas d'interblocage précité du à un problème entre un verrou et une condition, d'autres cas mettent en adéquation plusieurs threads, plusieurs verrous mutex et des circonstances délétères.

33.9.3 / La synchronisation de bloc

Le modificateur synchronized s'applique également à des blocs de codes critiques au sein des méthodes.

L'utilisation de cette technique peut être opportune lorsqu'une méthode ne requiert pas une synchronisation globale.

public void uneMethode(){
  //...
  synchronized(objet){
    //code synchroniée
  }
  //...
}

L'objet de synchronisation peut être une référence à l'instance de la classe courante, ou à tout autre objet présent dans la machine virtuelle.

synchronized(this){
  //Bloc de code
}

public Object verrou = new Object();
//...
synchronized(verrou){
  //Bloc de code
}

Par exemple, il est possible d'obtenir une synchronisation sur l'objet qu'il est nécessaire de modifier.

public class Bloc implements Runnable{
  private String adresse;
  public Bloc(String adresse){
    this.adresse = adresse;
  }
  public String lireURL(String adresse) {
    //Lecture d'une adresse URL...
  }
  public void traitement(DocumentXML doc) {
    String sourceXML = lireURL(this.adresse);
    synchronized (doc) {
      doc.chargerDocument(sourceXML);
    }
    enregistrerFichier(sourceXML, 
               this.adresse.replaceFirst("http:/", "c:"));
    //...
  }
  public void run(){
    DocumentXML doc = new DocumentXML();
    traitement(doc);
    //...
  }
  public static void main(String[] args){
    for(int i = 0; i < 3; i++){
      Bloc bloc = new Bloc("http://site.com/fichier" + i + ".xml");
      Thread t = new Thread(bloc);
      t.start();
    }
  }
}

public class DocumentXML {
  private Document document;
  public DocumentXML() {
    this.document = null;
  }
  public synchronized void chargerDocument(String source) {
    try {
      DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
      fabrique.setNamespaceAware(true);
      fabrique.setValidation(true);
      DocumentBuilder constructeur = fabrique.newDocumentBuilder();
      this.document = constructeur.parse(new File(source));
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  public synchronized Document getDocument() {
    return document;
  }
  //...
}

Une portion de code synchronisée peut appeler une autre méthode synchronisée puisqu'un seul thread possède le moniteur sur l'ensemble du code synchronisé de l'objet courant.

Toutes les méthodes d'instance et les méthodes statiques d'une classe peuvent être synchronisées. Dans le cas d'un accès synchronisé entre une méthode d'instance et une méthode statique, le bloc accédant à la méthode statique doit être synchronisé par rapport à un objet commun, tel que l'objet Class de la classe courante.

public void methodeInstance(){
  synchronized(this.getClass()){ //Si l'objet est disponible
  //synchronized(NomClasse.class){
  methodeStatique();
  }
  //...
}

public static void methodeStatique(){
  //...
}

La sécurisation de l'accès à une champ statique doit passer par la création d'un moniteur auquel toutes les instances de la classe courante peuvent se référer. L'objet Class retourné par la méthode getClass() est tout à fait indiquer pour servir de verrou à ce moniteur.

public class Exemple {
  private static int acces = 0;
  private int valeur;
  public Exemple(){
    this.valeur = 0;
  }
  public synchronized void setValeur(int valeur) {
    this.valeur = valeur;
    synchronized (this.getClass()) {
      acces++;
    }
  }
  public int getValeur() {
    synchronized (this.getClass()) {
      acces++;
    }
    return this.valeur;
  }
  public int getAcces() {
    return acces;
  }
}

Les méthodes statiques doivent être synchronisées

public class Compteur implements Runnable {
  private static int compteur = 1;

  public synchronized static int getCompteur() {
    int etat = compteur;
    try {
      Thread.sleep((long) (Math.random() * 1000));
      compteur++;
    }
    catch (InterruptedException x) {
    }
    return etat;
  }
  private void afficher(int etat) {
    System.out.println(Thread.currentThread().getName() 
                     + " : compteur = " + (compteur - 1) 
                     + " / " + etat);
  }
  public void run() {
    this.afficher(getCompteur());
  }
  public static void main(String[] args) {
    try {
      Compteur compteur = new Compteur();
      for (int i = 0; i < 12; i++) {
        Thread t = new Thread(compteur, "Thread-" + i);
        t.start();
        Thread.sleep((long) (Math.random() * 1000));
      }
    }
    catch (InterruptedException x) {
    }
  }
}

/* Affiche sans synchronized :
Thread-0 : compteur = 1 / 1
Thread-1 : compteur = 2 / 2
Thread-2 : compteur = 3 / 3
Thread-4 : compteur = 4 / 4
Thread-3 : compteur = 5 / 4
Thread-5 : compteur = 6 / 6
Thread-7 : compteur = 7 / 7
Thread-6 : compteur = 8 / 7
Thread-9 : compteur = 9 / 8
Thread-8 : compteur = 10 / 8
Thread-10 : compteur = 11 / 10
Thread-11 : compteur = 12 / 11

* Affiche avec synchronized :
Thread-0 : compteur = 1 / 1
Thread-1 : compteur = 2 / 2
Thread-2 : compteur = 3 / 3
Thread-3 : compteur = 4 / 4
Thread-4 : compteur = 5 / 5
Thread-5 : compteur = 6 / 6
Thread-6 : compteur = 7 / 7
Thread-7 : compteur = 8 / 8
Thread-8 : compteur = 9 / 9
Thread-9 : compteur = 10 / 10
Thread-10 : compteur = 11 / 11
Thread-11 : compteur = 12 / 12

33.9.4 / La synchronisation de méthodes de classe

Les méthodes de classe peuvent étre synchronisées, à l'instar des méthodes d'instance. Toutefois, le verrou de classe utilisé par défaut est un objet Class qui représente la classe courante. Pour les méthodes d'instances, il s'agissait de l'objet courant this qui faisait office de verrou.

public static synchronized void uneMethodeDeClasse(){
  //...
}

En ce qui concerne les blocs de code synchronisés dans des méthodes de classe, le verrou dépend des variables sensibles à sécuriser.

public static boolean sauvegarder(DocumentXML document){
public static boolean sauvegarder(Document document) {
    if(document ==  null || repertoire == null) return false;
    try {
        DOMImplementationLS implLS = null;
        if(document.getImplementation().hasFeature("LS", "3.0")) {
            implLS = (DOMImplementationLS)
                                      document.getImplementation();
        }
        else { 
            DOMImplementationRegistry enregistreur = 
                                          DOMImplementationRegistry.newInstance();
            implLS = (DOMImplementationLS)
                                enregistreur.getDOMImplementation("LS 3.0");
        }
        if(implLS == null){
            System.out.println(
                "Votre implémentation ne supporte "
              + "pas l'API DOM Load and Save !");
             return false;
         }
        LSSerializer serialiseur = implLS.createLSSerializer();
        LSOutput sortie = implLS.createLSOutput();
        sortie.setEncoding("ISO-8859-1");
        synchronized(document){
            File fichier = new File(
                    document.getDocumentElement().getNodeName() + ".xml");
            FileOutputStream fluxSortie = new FileOutputStream(fichier);
            sortie.setSystemId(fichier.toString());
            sortie.setByteStream(fluxSortie);
            serialiseur.write(document, sortie);
            fluxSortie.flush();
            fluxSortie.close();
        }
        return true;
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

L'imbrication des zones synchronisées dans des méthodes de classe peut entraîner une utilisation de verrous de classe et d'objet. S'il est nécessaire de protéger un objet particulier dans une section critique de méthode de classe synchronisée, alors il est possible de synchroniser l'exécution sur cet objet. Ainsi, le thread devra acquérir le verrou de classe en entrant dans la méthode, puis devra acquérir le verrou d'objet document pour accèder au bloc de code synchronisé.

public static synchronized boolean sauvegarder(Document document) {
    //...
    synchronized(document){
        File fichier = new File(
                document.getDocumentElement().getNodeName() + ".xml");
        FileOutputStream fluxSortie = new FileOutputStream(fichier);
        sortie.setSystemId(fichier.toString());
        sortie.setByteStream(fluxSortie);
        serialiseur.write(document, sortie);
        fluxSortie.flush();
        fluxSortie.close();
    }
    return true;
    //...
}

A l'inverse, si une méthode d'instance tente de manipuler des champs statiques sensibles, il faut englober ces dernières dans un bloc de code synchronisé, lequel peut prendre comme verrou soit un objet statique, soit un objet Class de la classe à laquelle appartiennent ces champs.

public class UneClasse {
    public static int champSensible = 0;
    public synchronized uneMethode(){
        synchronized(Class.forName("UneClasse")){
        // ou synchronized(this.getClass()){
        // ou synchronized(UneClasse.class){
            champSensible++;
        }
    }
}

La méthode getClass() ou le champ class retourne la classe d'exécution d'un objet. L'objet Class obtenu est le verrou de classe exploité par les méthodes statiques synchronisées de la classe courante. Tandis que celui fourni par le chargeur de classe constitue un objet Class qui n'est pas lié à l'instance de la classe en cours d'exécution.

Un objet statique commun à toutes les instances de la classe courante, peut être utiliser comme verrou.

public class UneClasse {
    private static Object verrou = new Object();
    public static int champSensible = 0;
    public synchronized uneMethode(){
        synchronized(verrou){
            champSensible++;
        }
    }
}

33.9.5 / Exemple

Des cas typiques de programmation mettent souvent en concurrence un producteur créant un flux de données et un consommateur utilisant le flux de données précité. Par exemple, un thread producteur peut écrire un texte dans un fichier, tandis qu'un consommateur lit ce-dernier, ou respectivement qu'un crédite un compte bancaire et que l'autre débite ce même compte, etc..

Il faut synchroniser les méthodes ou les blocs d'instructions critiques, c'est à dire ceux qui agissent directement sur les données communes.

public class Fichier {
    public synchronized String lire() {
      //Instructions...
    }
    public synchronized void ecrire(String txt) {
      //Instructions...
    }
}
//ou...
public class Compte {
    public synchronized debiter(double somme) {
      //Instructions...
    }
    public synchronized crediter(double somme) {
      //Instructions...
    }
}

De cette manière, lorsqu'un thread accède à une donnée partagée d'un objet particulier, par l'intermédiaire d'une des méthodes synchronisées, l'autre devient inaccessible aux autres threads concurrents au même moment. A la fin du traitement opéré par la méthode synchronisée accédée, les autres méthodes synchronisées deviennent à nouveau accessibles par les threads concurrents.

Evidemment, s'il existe plusieurs instances d'une classe particulière, alors une méthode d'instance synchronisée pourra être exécutée par objet simultanément, par d'autres threads.

//...
compte1 = new Compte();
compte2 = new Compte();

Thread debit1 = new Thread(new Debit(compte1, 100.00));
Thread debit2 = new Thread(new Debit(compte2, 2050.00));
Thread debit3 = new Thread(new Debit(compte1, 820.00));
Thread credit = new Thread(new Credit(compte1, 2500.00));

debit1.start();
debit2.start();
debit3.start();
credit.start();
//...

public class Debit implements Runnable {
    private Compte compte;
    private double somme;
    public Debit(Compte compte, double somme){
      this.compte = compte;
      this.somme = somme;
    }
    public void run(){
      compte.debiter(somme);
    }
}

public class Credit implements Runnable {
    private Compte compte;
    private double somme;
    public Credit(Compte compte, double somme){
      this.compte = compte;
      this.somme = somme;
    }
    public void run(){
      compte.crediter(somme);
    }
}

Dans cet exemple, il existe deux comptes, à partir desquels, il est possible d'accéder en même temps à une opération de débit par deux threads différents, en l'occurrence debit1 et debit2. Par contre, les threads debit3 et credit devront attendre que debit1 ait terminé avec l'opération débitrice.

Les méthodes non-synchronisées peuvent être sollicitées à n'importe quel moment et par n'importe quel thread, indépendamment des méthodes synchronisées.

La synchronisation permet d'éviter des problèmes de sureté (safety), mais engendre d'autres risques durant l'activité des threads (liveness).

Le principal écueil réside dans l'interblocage du programme, c'est à dire que tous les threads s'attendent mutuellement et, donc, aucun ne peut prendre le moniteur. Autrement dit, le programme est bloqué, car chaque thread attend la libération du verrou en vain.

public class Compte {
  public synchronized void retirer(double somme) {
    // Effectue un retrait...
  }
  public synchronized void verser(double somme) {
    // Effectue un versement
  }
  public synchronized void virer(Compte dest, double somme){
    this.retirer(somme);
    dest.verser(somme);
  }
}
public class Virement extends Thread {
  private Compte dest;
  private Compte ori;
  private double somme;
  public void Virement(
                       Compte destinataire, 
                       Compte origine, 
                       double somme){
    this.dest = destinataire;
    this.ori = origine;
    this.somme = somme;
  }
  public void run(){
    ori.virer(dest, somme);
  }
}
public static void main(String[] args) {
  Compte cptDest = new Compte(...);
  Compte cptOri = new Compte(...);
  Thread t1 = new Virement(cptDest, cptOri, 2000);
  Thread t2 = new Virement(cptOri, cptDest, 1000);
  t1.start();
  t2.start();
}

Dans ce cas, le thread t1 appelle la méthode verser() de la classe Compte et obtient le verrou sur l'instance de cette classe (cptOri). De même, le thread t2 obtient le verrou sur l'objet cptDest en invoquant la méthode verser(). L'invocation de la méthode retirer() par les threads t1 et t2 se déroule sans difficulté, mais lorsque les threads tentent respectivement d'appeler simultanément la méthode verser() sur les objets cptOri et cptDest(), un conflit se produit puisqu'un verrou est déjà posé sur les deux objets. La solution dans ce cas, consisterait à écrire le processus de virement directement dans le thread.

public void run(){
    ori.retirer(somme);
    dest.verser(somme);
}

De cette manière, le thread t1 obtient le verrou sur l'objet cptOri en invoquant la méthode retirer(), puis le libère à la fin de l'exécution de cette méthode. Le thread t2 fait la même chose pour l'objet cptDest. L'appel de la méthode verser() par les deux threads, entraîne le verrouillage des objets précédemment libérés. Au terme de l'exécution de la méthode verser(), les verrous se libèrent.

Il peut également se produire des problèmes de conflit (contention) :

Pour résoudre ce problème, les threads avec une priorité elevée doivent périodiquement invoquer les méthodes sleep() ou yield() pour donner aux threads ayant une priorité moins élevée, les mêmes occasions de s'exécuter.

La mise en sommeil prolongée des threads (dormancy) se produit lorsqu'un thread qui est en attente ne peut jamais redevenir exécutable. Le thread a invoqué la méthode wait(), puis aucun des autres threads n'invoque la méthode notify() ou notifyAll(). L'endormissement des threads peut être évité en prenant des précautions quant à l'utilisation de la méthode wait() sur un thread, sans s'être assuré d'invoquer la méthode notify() ou notifyAll() sur d'autres threads.

Exemple [voir]
// Fichier :  Credit.java
public class Credit implements Runnable {
    private Compte compte;
    private double somme;

    public Credit(Compte compte, double somme) {
        this.compte = compte;
        this.somme = somme;
    }
    public void run() {
        double solde = compte.getSolde();
        compte.crediter(somme);
        System.out.println("################## CREDIT ###################"
                + "\n# Référence Client : " + compte.getReference()
                + "\n# Solde AvO : " + solde 
                + "\n# Somme créditée : " + somme
                + "\n# Solde ApO : " + compte.getSolde());
    }
}

// Fichier :  Debit.java
public class Debit implements Runnable {
    private Compte compte;
    private double somme;

    public Debit(Compte compte, double somme) {
        this.compte = compte;
        this.somme = somme;
    }
    public void run() {
        double solde = compte.getSolde();
        compte.debiter(somme);
        System.out.println("################### DEBIT ###################"
                + "\n# Référence Client : " + compte.getReference()
                + "\n# Solde AvO : " + solde 
                + "\n# Somme débitée : " + somme
                + "\n# Solde ApO : " + compte.getSolde());
    }
}

// Fichier :  Compte.java
public class Compte {
    private int refClient;
    private double solde;
    private int nbOperations;

    public Compte(int ref, double solde) {
        this.refClient = ref;
        this.solde = solde;
        nbOperations = 0;
    }
    public synchronized void debiter(double somme) {
        solde -= somme;
        nbOperations++;
    }
    public synchronized void crediter(double somme) {
        solde += somme;
        nbOperations++;
    }
    public synchronized double getSolde() {
        return solde;
    }
    public synchronized int getNbOperations() {
        return nbOperations;
    }
    public int getReference() {
        return refClient;
    }
}

// Fichier :  Banque.java
import java.util.Random;

public class Banque {
    private static int nbComptes = 3;
    private static int nbOperations = 10;
    private static int sommeMax = 100000;
    private static Random generateur = new Random();

    public static void main(String[] args) {
        Compte[] comptes = creerComptes();
        afficherEtatComptes(comptes);
        Thread[] operations = creerOperations(comptes);
        lancerOperations(operations);
        patienter(operations);
        afficherEtatComptes(comptes);
    }
    public static Compte[] creerComptes() {
        Compte[] comptes = new Compte[nbComptes];
        for (int i = 0; i < comptes.length; i++) {
            comptes[i] = new Compte(i, generateur.nextInt(sommeMax));
        }
        return comptes;
    }
    public static Thread[] creerOperations(Compte[] comptes) {
        Thread[] operations = new Thread[nbOperations];
        for (int i = 0; i < operations.length; i++) {
            if (i % 3 == 0)
                operations[i] = new Thread(new Credit(comptes[generateur
                        .nextInt(nbComptes)], generateur.nextInt(sommeMax)));
            else operations[i] = new Thread(new Debit(comptes[generateur
                    .nextInt(nbComptes)], generateur.nextInt(sommeMax)));
        }
        return operations;
    }
    public static void lancerOperations(Thread[] operations) {
        for (int i = 0; i < operations.length; i++) {
            operations[i].start();
        }
    }
    public static void afficherEtatComptes(Compte[] comptes) {
        System.out.println("############# ETATS DES COMPTES #############");
        for (int i = 0; i < comptes.length; i++) {
            System.out.println("############## ETAT DU COMPTE ###############"
                    + "\n# Référence Client    : " + comptes[i].getReference()
                    + "\n# Solde               : " + comptes[i].getSolde()
                    + "\n# Nombre d'opérations : "
                    + comptes[i].getNbOperations());
        }
        System.out.println("#############################################");
    }
    public static void patienter(Thread[] operations) {
        for (int i = 0; i < operations.length; i++) {
            if (operations[i].isAlive()) {
                try {
                    Thread.sleep(10);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
                i = 0;
            }
        }
    }
}

33.9.6 / Le modificateur volatile

Les variables précédées par le modificateur volatile afin d'obliger la machine virtuelle Java à relire la valeur des variables au sein de la mémoire partagée à chaque fois qu'elles sont accédées.

Les compilateurs Java s'autorisent à mettre en cache les variables membres dans les registres mémoires. Cette optimisation entraîne des problèmes lors d'accès concurrentiels. En effet, lorsqu'un thread modifie une copie d'un champ partagé, cette copie modifiée est mise en cache et n'est pas stockée en mémoire centrale. Si bien que si un autre thread tente d'accéder au champ en question, il ne pourra pas voir les modifications apportées à ce champ puisqu'il n'accède pas à la copie précédemment modifiée et de plus ce thread travaillera, lui aussi, sur une copie du champ d'origine. Autrement dit, les threads utilisant une variable membre partagée, n'accède qu'à des copies de cette variable dont les modifications ne peuvent être visibles pour ces threads concurrents. Une incohérence de la variable a de forte probabilité de déclencher un fonctionnement inattendu du programme.

les variables possèdant le modificateur volatile, sont chargées (load) à partir de la mémoire centrale avant chaque utilisation. Suite à leur exploitation (read ou write), les variables volatiles sont stockées (stored) en mémoire centrale. Par ce moyen, la valeur réelle d'une telle variable est assurée d'être cohérente à l'intérieur de chaque thread.

int volatile indice = 0;

D'ailleurs, les actions (chargement, stockage, lecture et écriture) sur des variables volatiles sont dites atomiques (indivisibles) de même que pour des variables de type long ou double.

Il est important de comprendre que l'utilisation du modificateur volatile nécessite de se conformer à plusieurs règles.

Si plusieurs threads sont susceptibles d'accéder à une même variable membre, et qu'un ou plusieurs threads peuvent modifier la valeur de cette variable, ainsi que tous ces threads n'utilisent pas de méthodes ou de blocs synchronisés pour lire et écrire les valeurs, alors cette variable membre doit être déclarée volatile afin de s'assurer que tous les threads puissent voir ses modifications de valeur.

Exemple [voir]
public class Volatile extends Thread {
    private volatile boolean arret = false;
    private volatile int compteur;
    private volatile int temps;

    public static void main(String args[]) throws Exception {
        Exemple thread = new Exemple();
        System.out.println("Démarrage du thread...");
        thread.start();
        thread.compteur = 0;
        thread.temps = 1000;
        Thread.sleep(thread.temps / 3);
        thread.compteur = 0;
        Thread.sleep(thread.temps);
        System.out.println("Demande d'arrêt du thread...");
        // Utilisation de arret par le thread principal Thread.currentThread()
        thread.arret = true;
        Thread.sleep(300);
        System.out.println("Fin du programme");
        System.exit(0);
    }

    public void run() {
        while (temps > 0 && !arret) {
            System.out.println("Thread en cours d'exécution : " 
                                       + compteur++ + " " + temps);
            try {
                Thread.sleep(temps / 10);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            temps = temps - compteur * 10;
        }
        System.out.println("Arrêt effectif du thread");
    }
}

33.10 / La communication entre threads

La synchronisation possède un mécanisme de notification de threads. Ce mécanisme permet de faire communiquer différents threads entre eux. Ce genre de communication repose sur un système d'attente et de notification.

La classe Object définit, à cet effet, trois méthodes wait(), notify() et notifyAll(). Tous les objets d'un programme Java, héritant directement ou indirectement de la classe Object, peuvent tous utiliser les méthodes précitées.

Les threads exécutant des opérations sur un objet partagé, peuvent avoir besoin de dialoguer entre eux, afin d'indiquer par exemple qu'un traitement spécifique (ex. : lecture sur un socket) est terminé et donc qu'un autre (ex.: mise en forme d'un résultat) peut prendre le relai. Dans ce système, un thread attend donc de recevoir une notification d'un thread concurrent qui devra avoir libéré le verrou d'objet, pour qu'il puisse constater qu'une condition soit satisfaite afin d'exécuter sa tâche. S'il ne reçoit pas de notification, il reste en attente ou si la condition n'est pas bonne, il se rendort.

Les méthodes wait(), notify() et notifyAll() ne peuvent être utilisées que depuis des méthodes ou des blocs de code synchronisés. Dans le cas contraire, une exception IllegalMonitorStateException sera immanquablement levée si ces méthodes sont invoquées par du code qui ne possède pas le moniteur sur l'objet courant.

public synchronized void methode(){
    //...
    this.wait();
    //...
}

synchronized(this){
    //...
    this.notifyAll();
    //...
}

La méthode wait() correspond à une mise en attente du thread qui l'invoque, jusqu'à la réception d'une notification. Cette mise en attente s'accompagne d'une libération de tous les moniteurs que ce thread aurait placés sur des objets communs. Ainsi, les verrous mutex de ces objets deviennent disponibles pour d'autres threads concurrents.

Deux autres méthodes wait(), prenant des valeurs temporelles en millisecondes ou/et en nanosecondes en arguments, permettent de mettre en attente un thread jusqu'à ce qu'une période de temps déterminée se soit écoulée.

La méthode notify() ou notifyAll() indique respectivement à un thread ou à tous les threads précédemment mis en attente par la méthode wait(), de se réveiller. Dans la plupart des cas, la méthode notifyAll() est utilisée car si plusieurs threads synchronisés sur un objet ont invoqué la méthode wait(), alors il est nécessaire de leur envoyer une notification afin que chacun puisse vérifier leur condition de reprise. Dans le cas contraire, un seul thread est réveillé et celui-ci peut voir sa condition de redémarrage non satisfaite.

Ce mécanisme de communication peut se substituer à une boucle de scrutation avec une bien meilleure efficacité en terme de commodité et de performance. En effet, l'invocation de la méthode sleep() retarde du temps qui lui est imposé, la vérification d'une condition. L'utilisation de la méthode wait() évite ce temps de latence, puisque le thread ne se réveillera que lorsqu'il sera notifié par un autre thread qui aura vérifié la condition.

public class Exemple {
  private int a;
  public synchronized void scruter(){
    while(a >= 10){
      try {
        //Traitement...
        Thread.sleep(100);
      }
      catch(InterruptedException e){
        e.printStackTrace();
      }
    }
  }
  public synchronized void remettreAZero(){
    if(a > 0) a = 0;
  }
}

public class Exemple {
private int a;
  public synchronized void scruter(){
    while(a > 0){
      try {
        //Traitement conditionné...
        this.wait();
      }
      catch(InterruptedException e){
      }
    }
  }
  public synchronized void remettreAZero(){
    if(a > 0){
      a = 0;
      this.notify();
    }
  }
}

Dans un programme plus complexe, la boucle contenant l'appel de la méthode wait() doit être conservée car au possible réveil des threads concurrents par l'une des méthodes de notification, la condition attendue peut ne pas être satisfaite. Si le thread en attente se réveille, il ne testera pas la condition et sortira de la méthode, engendrant des risques pernicieux pour le déroulement du programme.

public synchronized void scruter(){
  if(condition == false){
    try {
      //Traitement conditionné...
      this.wait();
    }
    catch(InterruptedException e){
    }
  }
}

La mise en attente temporisée par deux des méthodes wait() s'avère particulièrement utile dans les cas où il est nécessaire d'arrêter prématurément le sommeil d'un thread et évidemment avant qu'il ne reçoive une notification d'un autre thread. Ces méthodes procure un avantage décisif. Si le thread chargé de notifier, ne peut être en mesure d'accomplir son action, le réveil programmé comblera cette lacune.

public synchronized void effectuerTraitement(){
  while(condition == false){
    try {
      //Traitement conditionné...
      //Au bout de 12 secondes, le thread se réveille
      this.wait(12000);
    }
    catch(InterruptedException e){
    }
  }
}

Les méthodes de classe ne peuvent utiliser directement ce mécanisme de notification et de mise en attente. Toutefois, il est possible d'utiliser un objet statique lié par une relation un à un à la classe courante, à partir duquel les méthodes wait, notify() et notifyAll() pourront être appelées. Ce genre d'objet peut être le verrou de classe.

public class UneClasse {
  private static Object verrou = new Object();

  public static void scruter(){
    synchronized(verrou){
      while(a > 0){
        try {
          //Traitement conditionné...
          verrou.wait();
        }
        catch(InterruptedException e){
        }
      }
    }
  }
  public static void avertir(){
    synchronized(verrou){
      if(a > 0){
        a = 0;
        verrou.notify();
      }
    }
  }
}

33.10.1 / Exemple

Le mécanisme de cooordination des threads est particulièrement utile dans un système Producteur/Consommateur. Par exemple, un producteur fabrique des articles pendant que les consommateurs attendent de les acquérir. Lorsqu'il y a suffisamment d'articles, les consommateurs peuvent acheter ces articles tandis que le producteur attend les premiers résultats des ventes. Lorsqu'un épuisement des articles survient, alors les consommateurs attendent de nouveau que le producteur génère une nouvelle série d'articles.

import java.util.ArrayList;
public class Coordination {
    public Produits produits;
    public static void main(String[] args) {
        Coordination coord = new Coordination();
        coord.produits = new Produits();
        Producteur producteur = new Producteur(coord.produits);
        for(int i = 0; i < 25; i++) {
            Consommateur consommateur = 
                                      new Consommateur(coord.produits);
            consommateur.setName(String.valueOf((char)('A' + i)));
            consommateur.start();
        }
        producteur.start();
        while(producteur.isAlive()) {
            try {
                Thread.sleep(10);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Producteur extends Thread {
    public Produits produits;
    public Producteur(Produits produits) {
        this.produits = produits;
    }
    public void run() {
        int nb = 0;
        while(true) {
            produits.ajouter(nb);
            System.out.println("PRODUCTION : " + produits.size() 
                             + " Numero " + nb + " à " + produits.size());
            nb = produits.size();
            try {
                Thread.sleep(10000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Consommateur extends Thread {
    public Produits produits;
    public Consommateur(Produits produits) {
        this.produits = produits;
    }
    public void run() {
        while(true) {
            if(produits.size() > 0) {
                Article article = (Article)produits.obtenir();
                System.out.println("VENTE : " + article.toString() 
                                 + " à " + this.toString());
            }
            try {
                Thread.sleep((int)(Math.random() * 1000));
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
// Objet partagé entre les threads
class Produits extends ArrayList {
    public synchronized void ajouter(int nb) {
        while(this.size() > 0) {
            try {
                this.wait();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notifyAll();
        if(nb == 0) 
            nb = 10;
        else
            nb *= 2;
        for (int i = 0; i < nb; i++) {
            Article article = new Article(nb == 10 ? i : nb + i, 100, "lampe");
            super.add(article);
        }
    }
    public synchronized Article obtenir() {
        while(this.size() == 0) {
            try {
                this.wait();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notifyAll();
        Article article = (Article)this.get(0);
        this.remove(0);
        return article;
    }
}
class Article {
    private int numero;
    private double prix;
    private String designation;
    public Article(int reference, double prix, String designation) {
        this.numero = reference;
        this.prix = prix;
        this.designation = designation;
    }
    public String toString() {
        StringBuffer res = new StringBuffer("[");
        res.append(this.numero);
        res.append(", ");
        res.append(this.prix);
        res.append(", ");
        res.append(this.designation);
        return res.append("]").toString();
        
    }
}

33.11 / La classe SwingWorker

Il peut être parfois utile de créer des threads en tâche de fond, dans le but d'exécuter des tâches qui nécessitent beaucoup de temps. Justement, Sun Microsystems a développer la classe SwingWorker à cet effet.

La classe de SwingWorker est mise en oeuvre dans le fichier SwingWorker.java, disponible en téléchargement sur le site de Sun Microsystems.

La classe SwingWorker s'occupe de l'implémentation d'un thread se déroulant en tâche de fond. Bien que beaucoup de programmes n'aient pas besoin de ce genre de threads, ils peuvent s'avérer nécessaires pour accomplir de longues opérations, comme le chargement d'images ou la construction de tout objet lourd. Ceci améliorera sans conteste le fonctionnement d'un programme.

L'emploi de la classe SwingWorker, nécessite en premier lieu d'étendre la classe SwingWorker. La sous-classe doit implémenter la méthode construct(). Cette méthode doit contenir le code destiné à exécuter la longue tâche.

public class MonThread extends SwingWorker {
    //...
    public Object construct(){
        //Construction graphique...
        return objet;
    }
    //...
}

Ensuite, il suffit d'instancier la sous-classe de SwingWorker, puis de démarrer la tâche à partir de l'objet résultant en invoquant la méthode start(). Cette dernière se charge d'appeler la méthode construct() auparavant définie.

MonThread tache = new MonThread();
tache.start();

En cas d'un besoin ponctuel, il est possible de créer une classe anonyme à partir de la classe SwingWorker.

SwingWorker tache = new SwingWorker() {
    public Object construct() {
        //Construction graphique...
        return Object;
    }
};
tache.start();

S'il est nécessaire de récupérer l'objet retourné par la méthode construct(), il faut appeler la méthode get() de la classe SwingWorker.

Object objet = MonThread.get();

L'utilisation de la méthode get() est susceptible de provoquer un blocage du programme. Une solution consisterait à invoqué la méthode interrupt() sur l'instance de la classe SwingWorker, puis d'appeler la méthode get().

tache.interrupt();
Object  objet = tache.get();

En fait, si un traitement particulier doit être opéré sur l'objet retourné par la méthode construct(), il est préférable de rester dans le cadre de la classe SwingWorker et de confier ce traitement à la méthode finished(). Cette méthode est exécutée aussitôt après que la méthode construct() ait retournée sa valeur. Ainsi, il devient inutile de prendre des risques avec la méthode get().

public class MonThread extends SwingWorker {
    Object objet = null;
    //...
    public Object construct(){
        //Construction graphique...
        return objet;
    }
    //...
    public void finished(){
        traitement(objet);
    }
}

34 / L'introspection

L'introspection (reflection) permet à un programme Java de découvrir dynamiquement des informations sur une classe.

Ainsi, les champs, constructeurs, méthodes et autres caractéristiques d'une classe peuvent être livrés sans connaissance préalable du code source d'une classe.

Ce mécanisme introspectif est généralement utilisé par des outils de développement IDE (Integrated Development Environnement). Par exemple, les interpréteurs et inspecteurs d'objets de ces applications s'appuient largement sur cette technique.

Les classes nécessaires à l'introspection sont contenues dans les paquetages java.lang et java.lang.reflect.

34.1 / Les objets Class

Les instances de la classe Class représentent des objets, dits descripteurs de classe, qui sont créés automatiquement par la Machine Virtuelle Java lors du chargement des classes durant l'exécution d'un programme.

Les instances de la classe Class représentent des objets, dits descripteurs de classe, qui sont créés automatiquement par la Machine Virtuelle Java lors du chargement des classes durant l'exécution d'un programme.

Toutes les classes Java héritant de la superclasse racine java.lang.Object hérite d'une méthode getClass() chargée de retourner l'objet Class de l'instance de classe courante.

LinkedList liste = new LinkedList();
Class classe = liste.getClass();

Cette classe ne possède pas de constructeurs, mais peut être instancier par l'intermédiaire de l'une des méthodes statiques ForName().

public class Introspection {
  public static void main(String[] args) {
    if (args.length > 0){
      try {
        Class classe = Class.forName(args[0]);
        System.out.println("Le nom de la classe = " + classe.getName());
      }
      catch (ClassNotFoundException e) {
        System.out.println("La classe n'a pu être déterminée !");
      }
    }
  }
}

La méthode forName() a pour fonction de charger dynamiquement une classe spécifiée sous la forme d'une chaîne de caractères. Cette méthode retourne un objet de type Class qui pourra être utilisé avec toutes les méthodes d'instance de la classe Class.

Class clsObjet = forName("java.lang.StringBuffer");

D'autre part, la classe Class contient essentiellement des méthodes capables de délivrer dynamiquement des informations relatives à une classe ou une interface cible.

La méthode getName() et toString() retournent le nom d'une classe ou d'une interface sous la forme d'une chaîne de caractères.

System.out.println(clsObjet.getName());

Si le type de la classe est un tableau, alors une chaîne de caractères spécifique est retournée par la méthode getName(). Cette chaîne de caractères débute par une séquence de caractère [ indiquant le nombre de dimensions du tableau. Puis une lettre représente le type primitif ou le type référence des éléments du tableau.

CaractèreTypeExemple
Breprésente un type byte.byte[] t;
[B
Creprésente un type char.char[][] t;
[[C
Dreprésente un type double.double[] t;
[D
Freprésente un type float.float[] t;
[F
Ireprésente un type int.int[][][] t;
[[[I
Jreprésente un type long.long[][] t;
[[L
LnomClasse;représente une classe ou une interface.Object[] t;
[Ljava.lang.Object;
Sreprésente un type short.short[][][][] t;
[[[[S
Zreprésente un type boolean.boolean[] t;
[Z

Les méthodes getDeclaredFields(), getDeclaredConstructors(), getDeclaredMethods() permettent de retourner respectivement, tous les champs, les constructeurs et les méthodes déclarés par la classe ou l'interface cible.

Field[] tabChamps = clsObjet.getDeclaredFields();
Method[] tabMethodes = clsObjet.getDeclaredMethods();
Constructor[] tabConstructeurs = clsObjet.getDeclaredConstructors();

Les méthodes getFields(), getMethods() et getConstructors() ressemblent à celles précitées, mais à la différence qu'elles retournent essentiellement les champs, méthodes et constructeurs publics de la classe courante mais également de ses classes et interfaces parentes.

Field[] tabChamps = clsObjet.getFields();
Method[] tabMethodes = clsObjet.getMethods();
Constructor[] tabConstructeurs = clsObjet.getConstructors();

Le type référence des tableaux retournés par ces méthodes se trouvent dans le paquetage java.lang.Reflect. C'est à partir des classes appropriées de ce paquetage qu'il sera possible de manipuler ces objets.

import java.lang.Reflect;

L'obtention d'une méthode ou d'un constructeur individuel nécessite de renseigner son nom (essentiellement pour les méthodes) et ses éventuels types de paramètres au sein respectivement, des méthodes getMethod() ou getDeclaredMethod() ou getConstructor() ou getDeclaredConstructor(). Les types de paramètres doivent être fournis dans un tableau de classes. Par la suite, la méthode ou le constructeur pourra être respectivement invoquer ou instancier par l'objet courant correspondant de type Method ou Constructor.

Class classe = Class.forName("java.util.Hashtable");
Object obj = classe.newInstance();
Class[] types = {
                               Class.forName("java.lang.Object"),
                               Class.forName("java.lang.Object")
                              };
Object[] params = {new Integer(0), "Une chaîne..."};
Method methode = classe.getMethod("put", types);
methode.invoke(obj, params);

Class classe = Class.forName("java.util.Hashtable");
Class[] types = {Integer.TYPE};
Constructor constructeur = 
                               classe.getConstructor("Hashtable", types);
Object[] params = {new Integer(20)};
Object obj = constructeur.newInstance(params);

Plusieurs autres méthodes préfixées par get retournent le paquetage (getPackage()), la superclasse (getSuperClass), les modificateurs (getModifiers()), les classes imbriquées (getClasses()), les interfaces implémentées (getInterfaces()), le chargeur de classe (getClassLoader()) ou encore la classe de déclaration (getDeclaringClass()).

Plusieurs méthodes préfixées par is et retournant une valeur booléenne, permettent de vérifier le type des classes objets spécifiques. Les méthodes isArray() et isPrimitive() testent respectivement si la classe objet représente un tableau et un des huit types primitifs et void (Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE).

if(clsObjet.isArray()){
  System.out.println("L'objet Class est un tableau !");
}
elseif(clsObjet.isPrimitive()){
  System.out.println("L'objet Class est un type primitif !");
}
elseif(clsObjet.isInterface()){
  System.out.println("L'objet Class est une interface !");
}
else{
  System.out.println("L'objet Class est une classe !");
}

En outre, d'autres méthodes de ce type permettent de déterminer si l'objet donné est une instance de cette classe (isInstance()), si le descripteur de classe représente une interface (IsInterface()) et si les objets d'une classe donnée peuvent être assignés aux objets de cette classe (isAssignableFrom()).

if(clsObjet.isInstance()){
  //Bloc d'instructions...
}

La méthode newInstance() est utilisée pour instancier la classe représentée par l'objet Class. Lors de la création de l'objet, le constructeur par défaut est appelé pour initialiser l'objet. L'objet retourné par la méthode newInstance() est de type Object.

Class clsVecteur = Class.forName("java.util.Vector");
// est équivalent à Vector vecteur = new Vector();
Vector vecteur = (Vector)(clsVecteur.newInstance());
Exemple [voir]
public class Introspection {
    public static void main(String[] args) {
      String ch = new String("Une chaîne de caractères...");
      if (args.length > 0){
        try {
          Class classe = Class.forName(args[0]);
          System.out.println("Le nom de la classe = " 
                                                  + classe.getName());
          System.out.println("Le paquetage de la classe = " 
                                                  + classe.getPackage().getName());
          System.out.println("Le chargeur de classe = " 
                                                  + classe.getClassLoader());
          System.out.println("Le superclasse de la classe = " 
                                                  + classe.getSuperclass());
          System.out.println("Les méthodes publiques de la classe = " 
                                                  + classe.getMethods().length);
          System.out.println("Toutes les méthodes de la classe = " 
                                                  + classe.getDeclaredMethods().length);
          System.out.println("Les constructeurs publiques de la classe = " 
                                                  + classe.getConstructors().length);
          System.out.println("Tous les constructeurs de la classe = " 
                                                  + classe.getDeclaredConstructors().length);
          System.out.println("Les champs publiques de la classe = " 
                                                  + classe.getFields().length);
          System.out.println("Tous les champs de la classe = " 
                                                  + classe.getDeclaredFields().length);

          System.out.println("La classe est " 
                               + obtenirModificateurs(classe.getModifiers()) + "."); 
          if(classe.isInstance(ch)){
            System.out.println("L'objet ch est une instance de la classe sous-jacente.");
          }

          Vector tabParents = obtenirHierarchie(classe);
          String esp = "";
          for(int i = tabParents.size() - 1; i >= 0; i--){
            System.out.println(esp + tabParents.elementAt(i));
            for(int j = 0; j < i; j++) esp += "  ";
          }

          Class primitive = Boolean.TYPE;
          System.out.println("Le nom de la classe = " 
                                                              + primitive.getName());
          System.out.println("Le paquetage de la classe = " 
                                                              + primitive.getPackage());
          System.out.println("Le chargeur de classe = " 
                                                              + primitive.getClassLoader());
          System.out.println("Le superclasse de la classe = " 
                                                              + primitive.getSuperclass());
          if(primitive.isPrimitive()){
            System.out.println("La classe sous-jacente " 
                                                              + "représente un type primitif.");
          }
        }
        catch (ClassNotFoundException e) {
          e.printStackTrace();
          System.out.println("La classe n'a pu être déterminée !");
        }
      }
    }
    /**
* Cette méthode statique fournit la liste des modificateurs d'une classe.
* @param valeur correspond au code numérique retourné par la méthode
* getModifiers() de la classe Class.
* @return Une chaîne de caractères contenant la liste
* des modificateurs de la classe courante.
*/
public static String obtenirModificateurs(int valeur){ String res = ""; if(valeur % 2 == 1){ //ACC_PUBLIC ^= 0x0001 ^= 1 res += "publique"; valeur -= 1; } if(valeur >= 128){ //ACC_ABSTRACT ^= 0x0400 ^= 128 if(!res.equals("")) res += ", "; res += "abstraite"; valeur -= 128; } if(valeur >= 64){ //ACC_INTERFACE ^= 0x0200 ^= 64 if(!res.equals("")) res += ", "; res += "une interface"; valeur -= 64; } if(valeur >= 16){ //ACC_FINAL ^= 0x0010 ^= 16 if(!res.equals("")) res += ", "; res += "finale"; valeur -= 16; } return res; } /**
* Cette méthode statique fournit la hiérarchie complète d'une classe.
* @param ssCls correspond à une sous-classe.
* @return Un objet Vector contenant l'ensemble des
* classes parentes de la sous-classe.
*/
public static Vector obtenirHierarchie(Class ssCls) { Vector hierarchie = new Vector(); Class supCls; hierarchie.add(ssCls.getName()); supCls = ssCls.getSuperclass(); while (supCls != null) { hierarchie.add(supCls.getName()); ssCls = supCls; supCls = ssCls.getSuperclass(); } return hierarchie; } } // L'appel du programme en ligne decommande >java Introspection java.lang.String //retourne Le nom de la classe = java.lang.String Le paquetage de la classe = java.lang Le chargeur de classe = null Le superclasse de la classe = class java.lang.Object Les méthodes publiques de la classe = 61 Toutes les méthodes de la classe = 58 Les constructeurs publiques de la classe = 11 Tous les constructeurs de la classe = 12 Les champs publiques de la classe = 1 Tous les champs de la classe = 7 La classe est publique, finale. L'objet ch est une instance de la classe sous-jacente. java.lang.Object java.lang.String Le nom de la classe = boolean Le paquetage de la classe = null Le chargeur de classe = null Le superclasse de la classe = null La classe sous-jacente représente un type primitif.

34.2 / Le modèle d'introspection

Le paquetage java.lang.reflect possèdent plusieurs classes et interfaces permettant de mettre en oeuvre le mécanisme d'introspection.

Les trois classes Field, Method et Constructor possèdent un modificateur final. La machine Virtuelle Java peut seulement créer des instances de ces classes. Ces objets sont utilisés pour manipuler les objets sous-jacents :

La classe Array est également finale mais non-instanciable. Elle fournit des méthodes statiques qui permettent de créer de nouveaux tableaux et d'obtenir ou de fixer les éléments des tableaux.

Exemple [voir]
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Introspection {
  public static void main(String[] args) {
    if (args.length > 0){
      try {
        Class classe = Class.forName(args[0]);
        Field[] champs = classe.getDeclaredFields();
        Method[] methodes = classe.getDeclaredMethods();
        Constructor[] constructeurs = classe.getDeclaredConstructors();
        System.out.println("Les champs de la classe " + classe.getName());
        System.out.println("Num :\tChamp\tType");
        for(int i = 0; i < champs.length; i++){
          System.out.println(i + " :\t" + champs[i].getName() 
                                                   + "\t" + champs[i].getType());
        }
        System.out.println("\nLes méthodes de la classe " + classe.getName());
        System.out.println("Num :\tType de retour\tMethode\t"
                                                  + "Types des Parametres\tTypes des Exceptions");
        for(int i = 0; i < methodes.length; i++){
          System.out.print(i + " :\t" + methodes[i].getReturnType() 
                                                     + "\t" + methodes[i].getName() + "\t");
          afficherInfos(methodes[i], "getParameterTypes");
          System.out.print("\t");
          afficherInfos(methodes[i], "getExceptionTypes");
          System.out.println("");
        }
        System.out.println("\nLes constructeurs de la classe " + classe.getName());
        System.out.println("Num :\tConstructeur\tTypes des Parametres"
                                                    + "\tTypes des Exceptions");
        for(int i = 0; i < constructeurs.length; i++){
          System.out.print(i + " :\t" + constructeurs[i].getName() + "\t");
          afficherInfos(constructeurs[i], "getParameterTypes");
          System.out.print("\t");
          afficherInfos(constructeurs[i], "getExceptionTypes");
          System.out.println("");
        }
      }
      catch (ClassNotFoundException e) {
        e.printStackTrace();
        System.out.println("La classe n'a pu être déterminée dans la méthode main()!");
      }
    }
  }

  /**
* La méthode afficherInfos() permet d'afficher des informations relatives
* à l'objet passé en argument. Les informations sont extraites par rapport
* au nom d'une méthode, laquelle doit être un membre de l'objet précité.
*
* @param obj correspond à l'objet à partir duquel des
* informations doivent être extraites.
* @param methode correspond à une méthode de l'objet et
* est destinée à extraire des informations.
*/
public static void afficherInfos(Object obj, String methode){ try { Object types = obj.getClass().getMethod(methode, null).invoke(obj, null); Class[] tabTypes = (Class[])types; for(int i = 0; i < tabTypes.length; i++){ System.out.print(i > 0 ? ", " : "\t"); System.out.print(tabTypes[i].getName()); } } catch (Exception e) { e.printStackTrace(); System.out.println("Une exception a été lancée dans la méthode afficherInfos() !"); } } }

34.3 / L'interface Member

Les classes Field, Method et Constructor implémentent l'interface Member symbolisant les membres d'une classe réflêchie.

Les méthodes de l'interface Member sont utilisées pour questionner un membre, afin de récupérer le nom, les modificateurs et la classe de déclaration du membre.

Les méthodes
Class getDeclaringClass()
retourne l'objet Class représentant la classe ou l'interface qui déclare le membre ou le constructeur.
int getModifiers()
retourne les modificateurs du membre ou du constructeur, sous la forme d'un code entier.
String getName()
retourne le nom du membre ou du constructeur sous-jacent.

Les trois méthodes sont également utilisables dans la classe java.lang.Class.

34.4 / Les objets Field

Un objet Field représente un champ réflêchi. Le champ sous-jacent peut être une variable de classe (champ statique) ou une variable d'instance (champ non-statique).

Les méthodes de la classe Field sont utilisées pour obtenir le type et la valeur du champ, et également fixer la valeur de ce dernier.

Class classe = Class.forName(args[0]);
Field[] champs = classe.getDeclaredFields();

La classe Field comporte principalement des méthodes destinées à récupérer (get) ou à assigner (set) la valeur d'un champ. Il existe une de ces méthodes pour chaque type primitif Java (getTypePrimitif() et setTypePrimitif()) et pour les objets (get(obj) et set(obj, val)).

Class classe = Class.forName("java.util.GregorianCalendar");
Object obj = classe.newInstance();
Field champ = classe.getField("FIELD_COUNT");
int val = champ.getInt(obj);
System.out.println(champ.getName() + " = " + val);

Class classe = Class.forName("java.util.Locale");
Class[] typesParams = {Class.forName("java.lang.String")};
Constructor constructeur = classe.getConstructor(typesParams);
Object[] params = {new String("FR")};
Object obj = constructeur.newInstance(params);
Field champ = classe.getField("FRENCH");
Object val = champ.get(obj);
System.out.println(champ.getName() + " = " + val.toString());

En outre, des méthodes fournissent également des informations sur l'objet Field, Il s'agît des méthodes getName(), getType() et getDeclaringClass() retournant respectivement le nom, le type référence et la classe de déclaration du champ sous-jacent.

Exemple [voir]
import java.util.Calendar;
import java.util.GregorianCalendar;

public class Calendrier {
  public static int annee;
  public Calendrier(){
    GregorianCalendar gc = new GregorianCalendar();
    annee = gc.get(Calendar.YEAR);
  }
}

import java.lang.reflect.Field;

public class Introspection {
  public static void main(String[] args){
    try{
      Class classe = Class.forName("Calendrier");
      Object cal = classe.newInstance();
      Field champ = classe.getField("annee");
      int valeur = champ.getInt(cal);
      System.out.println(champ.getName() + " = " + valeur);
      champ.setInt(cal, 2020);
      valeur = champ.getInt(cal);
      System.out.println(champ.getName() + " = " + valeur);
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }
}

34.5 / Les objets Method

Un objet Method représente une méthode réflêchie. La méthode sous-jacente peut être une méthode abstraite (modificateur abstract), une méthode d'instance (modificateur : private, protected et public) ou une méthode de classe (modificateur static).

Les méthodes de cette classe sont utilisées pour obtenir le type de chacun des paramètres, le type de retour et les types d'exceptions contrôlées de la méthode réflêchie.

Class classe = Class.forName(args[0]);
Method[] methodes = classe.getDeclaredMethods();

En outre, il est possible d'invoquer la méthode sous-jacente sur des objets cibles, par l'intermédiaire de la méthode invoke(). L'invocation de méthode abstraite et d'instance utilise une méthode de résolution dynamique fondée sur la classe d'exécution de l'objet cible et la classe de déclaration, le nom et le type des paramètres formels de la méthode. Ainsi, il est permis d'invoquer une méthode d'interface réflêchie sur un objet qui est une instance d'une classe qui implémente l'interface. L'invocation des méthodes statiques utilise la méthode statique sous-jacente de la classe de déclaration de la méthode.

import java.lang.reflect.Method;

public class Introspection {
  public static void main(String[] args) {
    try {
      Class classe = Class.forName("java.util.LinkedList");
      Object obj = classe.newInstance();
      Class[] types = {Integer.TYPE, Class.forName("java.lang.Object")};
      Object[] params = 
                                               {new Integer(0), "Une chaîne..."};
      Method methode = classe.getMethod("add", types);
      methode.invoke(obj, params);
      System.out.println(obj.toString());
    }
    catch (ClassNotFoundException e) {
      e.printStackTrace();
      System.out.println("La classe n'a pu être" 
                       + " déterminée dans la méthode main()!");
    }
  }
}

L'invocation d'une méthode nécessite de renseigner le nom et les valeurs de paramètres au sein de la méthode invoke(params). Les valeurs doivent correspondre aux types de paramètres énoncés lors de l'obtention de la méthode. Subséquemment, la méthode peut être invoquer par l'objet Method courant.

Class classe = Class.forName("java.util.Hashtable");
Object obj = classe.newInstance();
Class[] types = {
                                       Class.forName("java.lang.Object"), 
                                       Class.forName("java.lang.Object")
                               };
Object[] params = {new Integer(0), "Une chaîne..."};
Method methode = classe.getMethod("put", types);
methode.invoke(obj, params);

En outre, il est possible d'obtenir la classe de déclaration de la méthode par l'intermédiaire de la méthode getDeclaringClass(). Quant au nom ou à la représentation textuelle de la méthode sous-jacente, il faut employer respectivement la méthode getName() ou toString().

Class classe = Class.forName("java.util.Hashtable");
Method methode = classe.getMethod("isEmpty", null);
String nomClasse = methode.getName();
String nomClasseDeclaration = 
                              methode.getDeclaringClass().getName();
String représentationMethode = methode.toString();

La classe Method dispose également de plusieurs méthodes destinées à récupérer les types de retour (getReturnType()), de paramètres formels (getParameterTypes()) et d'exceptions susceptibles d'être lancées (getExceptionTypes()), de la méthode sous-jacente représentée par l'objet Method.

Exemple [voir]
import java.lang.reflect.Method;

public class Introspection {
  public static void main(String[] args) {
    try {
      Class classe = Class.forName("java.util.Vector");
      Method[] methodes = classe.getMethods();
      System.out.println("
Les méthodes publiques de la classe " + classe.getName() 
                                       + " et celles héritées des superclasses et interfaces.");
      System.out.println("Num :\tType de retour\tMethode\t"
                                                + "Types des Parametres\tTypes des Exceptions");
      for(int i = 0; i < methodes.length; i++){
        System.out.print(i + " :\t" + methodes[i].getReturnType() 
                                                   + "\t" + methodes[i].getName() + "\t");
        Class[] tabTypesParams = methodes[i].getParameterTypes();
        for(int j = 0; j < tabTypesParams.length; j++){
          System.out.print(j > 0 ? ", " : "\t");
          System.out.print(tabTypesParams[j].getName());
        }
        System.out.print("\t");
        Class[] tabTypesExceptions = methodes[i].getExceptionTypes();
        for(int j = 0; j < tabTypesExceptions.length; j++){
          System.out.print(j > 0 ? ", " : "\t");
          System.out.print(tabTypesExceptions[j].getName());
        }
        System.out.println("");
      }
    }
    catch (ClassNotFoundException e) {
      e.printStackTrace();
      System.out.println("La classe n'a pu être déterminée " 
                                       + "dans la méthode main()!");
    }
  }
}

34.6 / Les objets Constructor

Un objet Constructor représente un constructeur réflêchi.

Les méthodes de cette classe sont utilisées pour obtenir le type de chaque paramètre formel et exception contrôlée du constructeur sous-jacent. En outre, la méthode newInstance() de la classe Constructor permet de créer et initialiser une nouvelle instance de la classe déclarée par le constructeur à condition que la classe soit instanciable.

Class classe = Class.forName("java.lang.StringBuffer");
Constructor[] constructeurs = classe.getDeclaredConstructors();

L'instanciation d'une classe par l'intermédiaire d'un constructeur nécessite de renseigner les valeurs de paramètres au sein de la méthode newInstance(params). Les valeurs doivent correspondre aux types de paramètres énoncés lors de l'obtention du constructeur. Subséquemment, le constructeur peut être instancier par l'objet Constructor courant.

Class classe = Class.forName("java.util.Hashtable");
Class[] types = {Integer.TYPE};
Constructor constructeur = 
                                       classe.getConstructor("Hashtable", types);
Object[] params = {new Integer(20)};
Object obj = constructeur.newInstance(params);

par ailleurs, il est possible d'obtenir la classe de déclaration du constructeur par l'intermédiaire de la méthode getDeclaringClass(). Le nom ou à la représentation textuelle de l'objet Constructor sont accessibles respectivement par le truchement de la méthode getName() ou toString().

Class classe = Class.forName("java.util.Vector");
Class[] types = {Integer.TYPE, Integer.TYPE};
Constructor constructeur = classe.getConstructor(types);
String nomClasse = constructeur.getName();
String nomClasseDeclaration = 
                                       constructeur.getDeclaringClass().getName();
String représentationMethode = constructeur.toString();

La classe Constructor dispose également de plusieurs méthodes destinées à récupérer les types de paramètres formels (getParameterTypes()) et d'exceptions susceptibles d'être lancées (getExceptionTypes()), du constructeur sous-jacent représenté par l'objet Constructor.

Exemple [voir]
import java.lang.reflect.Constructor;

public class Introspection {
  public static void main(String[] args) {
    try {
      Class classe = Class.forName("java.util.Vector");
      Constructor[] constructeurs = classe.getConstructors();
      System.out.println("Les constructeurs publics de la classe " 
         + classe.getName() + " et celles héritées des superclasses et interfaces.");
      System.out.println("Num :\tConstructeur\t"
                                                + "Types des Parametres`\tTypes des Exceptions");
      for(int i = 0; i < constructeurs.length; i++){
        System.out.print(i + " :\t" + constructeurs[i].getName() + "\t");
        Class[] tabTypesParams = constructeurs[i].getParameterTypes();
        for(int j = 0; j < tabTypesParams.length; j++){
          System.out.print(j > 0 ? ", " : "\t");
          System.out.print(tabTypesParams[j].getName());
        }
        System.out.print("\t");
        Class[] tabTypesExceptions = constructeurs[i].getExceptionTypes();
        for(int j = 0; j < tabTypesExceptions.length; j++){
          System.out.print(j > 0 ? ", " : "\t");
          System.out.print(tabTypesExceptions[j].getName());
        }
        System.out.println("");
      }
    }
    catch (ClassNotFoundException e) {
      e.printStackTrace();
      System.out.println("La classe n'a pu être déterminée " 
                                                        + "dans la méthode main()!");
    }
  }
}

34.7 / La classe Array

La classe Array est une classe non-instanciable qui exporte les méthodes de classe pour créer des tableaux Java avec des primitives ou des types de composants de classes.

La classe Array possède deux méthodes destinées à créer des tableaux avec un type d'élément associé. Les méthodes créent un tableau en spécifiant pour l'une, une longueur et pour l'autre, des dimensions.

Object tab = Array.newInstance(Class.forName("java.lang.String"), 20);

int[] dimensions = {10, 10, 3};
Object tabDims = Array.newInstance(Char.TYPE, dimensions);

Les méthodes de la classe Array sont aussi utilisées pour obtenir et fixer les valeurs des éléments d'un tableau.Les méthodes d'obtention et d'affectation sont préfixées respectivement par get et set. A chaque type primitif correspond une méthode, ainsi pour les valeurs de type double, il existe une méthode getDouble() et une autre setDouble().

Un autre couple de méthodes permet d'extraire ou de fixer une valeur de type Object, il s'agît de get() et set().

Array.set(tab, 0, "Une chaîne...");

System.out.println(Array.get(tab, 0).toString());

Dans le cas de tableaux dynamiques à plusieurs dimensions, la première dimension est accessible via l'identificateur du tableau et les autres par l'intermédiaire de d'une imbrication de méthodes get().

int taille1 = Array.getLength(tabDims);
int taille2 = Array.getLength(Array.get(tabDims, 0));
int taille3 = Array.getLength(Array.get(Array.get(tabDims, 0), 0));

La méthode getLength() retourne une valeur entière indiquant la taille d'un tableau ou de l'une de ses dimensions.

Il est nécessaire d'importer la classe java.lang.reflect.Array afin de pouvoir utiliser ses membres dans un programme.

Exemple [voir]
import java.lang.reflect.Array;

public class Introspection {
    public static void main(String[] args) {
      try{
      Object tableau = Array.newInstance(Integer.TYPE, 10);
      int[] dimensions = {2, 10};
      Object tableau2 = Array.newInstance(Double.TYPE, dimensions);
      System.out.println(Array.getLength(tableau));
      System.out.println(Array.getLength(Array.get(tableau2, 0)));
      System.out.println("Premier tableau :");
      for(int i = 0; i < Array.getLength(tableau); i++){
        Array.setInt(tableau, i, 100 * i);
      }
      for(int i = 0; i < Array.getLength(tableau); i++){
        System.out.println(Array.getInt(tableau, i));
        Array.setDouble(Array.get(tableau2, 0), i, Array.getInt(tableau, i));
      }
      System.out.println("Second tableau :");
      for(int i = 0; i < Array.getLength(tableau2); i++){
        System.out.println(Array.get(tableau2, i).toString());
        for(int j = 0; j < Array.getLength(Array.get(tableau2, i)); j++){
          if (i == 0)
            Array.setDouble(Array.get(tableau2, 1), j, 
              (j > 0 ? (Math.PI / Array.getDouble(Array.get(tableau2, i), j)) : 0));
          System.out.println(Array.getDouble(Array.get(tableau2, i), j));
        }
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

34.8 / La classe Modifier

La classe Modifier est une classe non-instanciable qui exporte les méthodes de classe afin de décoder les modificateurs pour les membres et les classes.

Les trois classes Field, Constructor et Method du paquetage java.lang.reflect, ainsi que la classe java.lang.Class possèdent un méthode getModifiers() capable de retourner un code entier représentant une combinaison de modificateurs. Par exemple, l'application de la méthode sur une classe publique et statique, donnera en retour une valeur égale à 17, car le modificateur public possède la valeur 1 (en hexadécimal : 0x0001) et le modificateur static, la valeur 16 (id : 0x0010).

Class classe = Class.forName("java.lang.StringBuffer");
int mod = classe.getModifiers();
System.out.println("Valeur des modificateurs de la classe " 
                                          + classe.getName() + " :" + mod);
Constructor constructeur = classe.getDeclaredConstructor(null);
mod = constructeur.getModifiers();
System.out.println("Valeur des modificateurs du constructeur " 
                                          + constructeur.getName() + " :" + mod);
Method methode = classe.getDeclaredMethod("length", null);
mod = methode.getModifiers();
System.out.println("Valeur des modificateurs de la méthode " 
                                          + methode.getName() + " :" + mod);

La classe Modifier dispose essentiellement de méthodes statiques permettant de vérifier le type de modificateurs. Ces méthodes sont toutes préfixées par is suivi de l'identificateur du modificateur comme suit : isModificateur(). Elles prennent toutes un argument de type entier, représentant le modificateur à tester et retournent une valeur booléenne.

if(Modifier.isStatic(modificateur)){
    System.out.println("Le modificateur testé est static !");
}

Plusieurs constantes statiques représentant des modificateurs sont également exploitables à partir de la classe Modifier.

System.out.println(Modifier.PROTECTED);

Les modificateurs sont encodés dans un type entier, et utilisent les constantes d'encodage définies par la spécification de la Machine Virtuelle Java.

Les classes
DrapeauValeurDéfinition
ACC_PUBLIC0x0001La classe est publique et donc accessible à l'extérieur de son paquetage.
ACC_FINAL0x0010La classe est finale et donc ne peut être étendue.
ACC_SUPER0x0020La classe est considérée comme une superclasse.
ACC_INTERFACE0x0200La classe est en fait une interface.
ACC_ABSTRACT0x0400La classe est abstraite et donc ne peut être instanciée.
Les champs
DrapeauValeurDéfinition
ACC_PUBLIC0x0001Le champ est public et donc peut être accédé à l'extérieur de son paquetage.
ACC_PRIVATE0x0002Le champ est privé et donc ne peut être utilisé qu'au sein de sa classe.
ACC_PROTECTED0x0004Le champ est protégé, et donc peut être accédé à l'intérieur des sous-classes.
ACC_STATIC0x0008Le champ est statique et est donc accessible au sein de la classe et non d'un objet.
ACC_FINAL0x0010Le champ est final et donc ne peut être réaffecté.
ACC_VOLATILE0x0040Le champ est volatile et donc ne peut être caché.
ACC_TRANSIENT0x0080Le champ est transient et ne peut donc être lu ou écrit par un gestionnaire d'objet persistant.
Les méthodes
DrapeauValeurDéfinition
ACC_PUBLIC0x0001La méthode est publique et peut donc être accédée à l'extérieur de son paquetage.
ACC_PRIVATE0x0002Le méthode est privée et n'est donc accessible qu'au sein de sa classe.
ACC_PROTECTED0x0004La méthode est protégée et peut donc être accédée par des sous-classes.
ACC_STATIC0x0008La méthode est statique et ne peut être utilisée que par la classe et non par un objet.
ACC_FINAL0x0010La méthode est finale et ne peut donc être surchargée.
ACC_SYNCHRONIZED0x0020La méthode est synchronisée et ne peut donc être invoquée que si le verrou est levé.
ACC_NATIVE0x0100La méthode est native indiquant qu'elle est écrite dans un autre langage que Java.
ACC_ABSTRACT0x0400La méthode est abstraite signifiant qu'aucune implémentation n'est fournie.
ACC_STRICT0x0800La méthode est strictfp indiquant que le mode de virgule flottante est du type FP-strict.
Les classes imbriquées
DrapeauValeurDéfinition
ACC_PUBLIC0x0001La classe imbriquée est déclarée explicitement ou implicitement publique.
ACC_PRIVATE0x0002La classe imbriquée est déclarée explicitement privée.
ACC_PROTECTED0x0004La classe imbriquée est déclarée explicitement protégée.
ACC_STATIC0x0008La classe imbriquée est déclarée explicitement ou implicitement statique.
ACC_FINAL0x0010La classe imbriquée est déclarée explicitement finale.
ACC_INTERFACE0x0200La classe imbriquée est en fait une interface.
ACC_ABSTRACT0x0400La classe imbriquée est déclarée explicitement ou implicitement abstraite.
Exemple [voir]
public class Introspection {
  public static void main(String[] args) {
      String ch = new String("Une chaîne de caractères...");
        try {
          Class classe = Class.forName(args[0]);
          Vector vecteur = obtenirModificateurs(classe.getModifiers());
          System.out.println("Les modificateurs de la classe " + classe.getName() + " : ");
          for(int i = 0; i < vecteur.size(); i++){
            System.out.println(vecteur.elementAt(i));
          }
      }
      catch (ClassNotFoundException e) {
        e.printStackTrace();
        System.out.println("La classe n'a pu être déterminée !");
      }
  }
  /**
    * Cette méthode statique fournit la liste des modificateurs d'une classe.
   * @param valeur correspond au code numérique retourné par la méthode
   *                      getModifiers() de la classe Class.
   * @return Un vecteur contenant la liste 
   *                des modificateurs de la classe courante.
   */
  public static Vector obtenirModificateurs(int valeur){
    Vector res = new Vector();
    if(valeur % 2 == 1){ //ACC_PUBLIC ^= 0x0001 ^= 1
      res.add("publique");
      valeur -= 1;
    }
    if(valeur >= 128){ //ACC_ABSTRACT ^= 0x0400 ^= 128
      res.add("abstraite");
      valeur -= 128;
    }
    if(valeur >= 64){ //ACC_INTERFACE ^= 0x0200 ^= 64
      res.add("une interface");
      valeur -= 64;
    }
    if(valeur >= 16){ //ACC_FINAL ^= 0x0010 ^= 16
      res.add("finale");
      valeur -= 16;
    }
    return res;
  }
}

34.9 / La représentation des types primitifs Java

Il existe neuf objets Class qui sont utilisées pour représenter les huit types primitifs auxquels s'ajoute le mot-clé void au moment du temps d'exécution.

Il faut noter que ces objets sont des instances de type Class et non des classes. L'API d'introspection central (Core Reflection API) utilise ces objets afin d'identifier :

La JVM (Java Virtual Machine) crée ces neufs objets Class qui ont les mêmes noms que les types qu'ils représentent. Les objets Class peuvent seulement être référencés par le truchement des variables statiques finales suivantes :

ClassePrimitive
java.lang.Boolean.TYPEboolean
java.lang.Character.TYPEchar
java.lang.Byte.TYPEbyte
java.lang.Short.TYPEshort
java.lang.Integer.TYPEint
java.lang.Long.TYPElong
java.lang.Float.TYPEfloat
java.lang.Double.TYPEdouble
java.lang.Void.TYPEvoid

En particulier, ces objets Class ne sont pas accessibles par l'intermédiaire de la méthode Class.forname().

Exemple [voir]
public class Introspection {
  public static void main(String[] args) {
    try {
      int[][][] tab = new int[10][2][20];
      String sType = tab.getClass().getName();
      if (sType.indexOf('[') > -1) {
        int nbDimensions = 0; 
        while (sType.charAt(nbDimensions) == '[')
          nbDimensions++; 
        switch(sType.charAt(nbDimensions)) {
          case 'B' :
            System.out.print("byte");
            break;
          case 'C' :
            System.out.print("char");
            break;
          case 'D' :
            System.out.print("double");
            break;
          case 'F' :
            System.out.print("float");
            break;
          case 'I' :
            System.out.print("int");
            break;
          case 'J' :
            System.out.print("long");
            break;
          case 'L' :
            System.out.print(sType.substring(nbDimensions + 1, sType.indexOf(";")));
            break;
          case 'S' :
            System.out.print("short");
            break;
          case 'Z' :
            System.out.print("boolean");
            break;
        }
        for(int i = 1; i <= nbDimensions; i++){
          System.out.print("[]");
        }
        System.out.println(";");
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
}

35 / L'API XML

Le langage XML (eXtensible Markup Language) s'est immiscé dans quasiment tous les domaines du développement d'applications. Il sert, par exemple, pour les propriétés des logiciels (menus, langues, etc.) ou comme support pour le transport de données entre différents serveurs Web via un protocole de transmission comme SOAP (Simple Object Access Protocol) ou XML-RPC (XML-Remote Procedure Calling).

Les plateformes Java se devaient donc d'être en mesure d'exploiter le langage XML et son corollaire :

Java s'appuie sur les bibliothèques fournies par le module JAXP (Java API XML Processing) pour le traitement de données XML.

La version 1.5 du JDK intègre JAXP spécialisé dans le traitement de données XML. Outre, le support DOM, SAX et XSLT, la plateforme Java supporte désormais le langage XPath, la validation des documents XML, les espaces de noms, les inclusions XML et comprend d'autres API suivant les spécifications DOM 3, comme DOM Events et DOM Load and Save.

JAXP dispose de plusieurs paquetages concourrant à manipuler des informations XML. Les paquetages principaux se situent sous le paquetage javax.xml contenant notamment les analyseurs SAX (Simple API XML) et DOM (Document Object Model) et les paquetages org.xml.sax et org.w3c.dom.

Il existe deux possibilités pour manipuler des documents XML :

Le modèle d'objet de document a été conçu par le W3C. Il existe trois niveaux de spécification énonçant les règles que doivent suivre les différentes implémentations, telles que celle de Java ou d'autres langages comme PHP, C#, etc.

Simple API XML fur originellement un composant Java qui est devenu de facto une norme utilisée par de nombreux autres plateformes, y compris celles de Microsoft. Actuellement, SAX a atteint la version 2, subissant régulièrement des révisions et extensions destinées à améliorer son fonctionnement.

Un aspect important différencie radicalement ces deux moyens de traiter des documents XML.

En outre, la modification et la sauvegarde de tout ou d'une partie d'un document XML n'est pas possible directement avec SAX. Cette API permet plutôt de consulter des ressources XML lourdes avec des performances acceptables au niveau du temps de traitement et d'encombrement de la mémoire. Par exemple, la consultation d'un fichier XML pour un affichage de ses données dans des pages HTML se fera par le truchement de SAX. En clair, si un document XML ne nécessite pas de modification, il est préférable d'utiliser SAX. De même, si le document XML est lourd, SAX doit être la priorité même s'il faut le modifier à certains endroits. Une implémentation spécifique des gestionnaires d'événements SAX peut être réalisée à cet effet.

DOM ne souffre guère de cette limitation puisque toutes les données sont en mémoire. En conséquence, il suffit de rechercher un noeud à modifier par son nom ou par son identificateur (ID) s'il en possède un ou encore par son chemin, pour consulter sa valeur et éventuellement la modifier. La structure et le style d'un document XML ainsi que les noeuds qui le composent peuvent être accédés, modifiés et mis-à-jour facilement en utilisant les composants de l'architecture DOM.

35.1 / Le modèle d'objets de document

L'API DOM de Java suit le modèle d'objet spécifié par le W3C.

Un document XML peut être composé de 14 types de noeuds distincts. Deux collections permettent de stocker plusieurs noeuds résultant d'une recherche.

Les interfaces fondamentales et étendues proposées par le W3C sont toutes présentes dans l'implémentation du modéle objet de document de Java.

NoeudInterface W3CDescription
NodeNodereprésente un noeud XML.
DocumentDocumentreprésente un document XML.
ElementElementreprésente un élément XML.
AttrAttrreprésente un attribut XML.
CharacterDataCharacterDatareprésente une section de caractères.
TextTextreprésente le texte d'un noeud XML.
CDATASectionCDATASectionreprésente une section de caractères non-analysables (section CDATA)
CommentCommentreprésente un commentaire XML.
ProcessingInstructionProcessingInstructionreprésente une instruction de traitement.
DocumentTypeDocumentTypereprésente une définition de type de document.
NotationNotationreprésente une notation XML.
EntityEntityreprésente une entité.
EntityReferenceEntityReferencereprésente une référence d'entité.
DocumentFragmentDocumentFragmentreprésente une portion d'un document XML.
CollectionInterface W3CDescription
NodeListNodeListreprésente une liste de noeuds.
NamedNodeMapNamedNodeMapreprésente une collection d'attributs ordonnés par paire nom/valeur.
DiversInterface W3CDescription
DOMImplementationDOMImplementationreprésente l'implémentation utilisé pour exploiter un document XML.
DOMExceptionDOMExceptionreprésente une exception du DOM qui pourra être lancée lors de l'analyse ou l'exploitation du document XML.
 ExceptionCodeconstitue une liste de constantes représentant chacune un type d'exception.

La classe Node constitue la superclasse de tous les autres noeuds. Ainsi, les objets Document, Element et Attr héritent de toutes les méthodes et champs d'une instance de la classe Node.

De même, les objets Text et Comment héritent des caractéristiques d'un objet CharacterData. Enfin, la classe CDATASection étend la classe Text.

35.1.1 / Exploitation du DOM

L'exploitation d'un document XML à partir du modèle d'objet de document demeure relativement simple.

L'ouverture d'un document XML demeure le préalable obligatoire à l'utilisation du modèle d'objet DOM. Le paquetage javax.xml.parsers contient deux classes particulièrement importantes, puisqu'elles permettent de créer et de charger une source XML.

DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabrique.newDocumentBuilder();

Des caractéristiques et certaines propriétés (validation du document XML par rapport à sa DTD, prise en compte des espaces de noms et des inclusions XML, développement des références d'entités, fusion des noeuds CDATA adjacents, élimination des espaces blancs non-indispensables dans les éléments et abandon des commentaires) peuvent être précisées lors de l'instanciation de la classe DocumentBuilderFactory.

DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
fabrique.setValidating(true);
fabrique.setNamespaceAware(true);
fabrique.setXIncludeAware(true);
fabrique.setExpandEntityReferences(true);
fabrique.setCoalescing(false);
fabrique.setIgnoringElementContentWhitespace(true);
fabrique.setIgnoringComments(false);
DocumentBuilder analyseur = fabrique.newDocumentBuilder();

La fabrique DocumentBuilderFactory transmet toute la configuration aux analyseurs DOM qu'elle crée à l'aide de la méthode newDocumentBuilder().

Désormais, l'objet DocumentBuilder est prêt à produire un document XML à partir de différentes sources d'entrées à fournir à sa méthode d'instance parse().

Document document = analyseur.parse("fichier.xml");
//ou
BufferedReader br = new BufferedReader(new FileReader("fichier.xml"));
InputSource source = new InputSource(br);
Document document = analyseur.parse(source);
//ou
URL url = new URL("http://laltruiste.com/coursjava/exemples/employes.xml");
BufferedInputStream bis = new BufferedInputStream(url.openStream());
Document document = analyseur.parse(bis);
//ou
Document document = analyseur.parse(
                    "http://laltruiste.com/coursjava/exemples/employes.xml");

L'exploration du document XML s'effectue en se déplaçant dans l'arborescence, de noeud en noeud, à l'aide des nombreuses méthodes et attributs proposées par le DOM.

L'emplacement du document XML, s'il n'a pas été créé par la méthode DOMImplementation.createDocument, devrait être obtenu par la méthode getDocumentURI(). L'adresse URI peut aider à résoudre des adresses relatives au sein du document, comme les références vers une DTD externe, un schéma XML ou une feuille de style XSLT.

String uri = document.getDocumentURI();

Un document XML contient un prologue qui fournit certaines informations à son propos :

String version = document.getXmlVersion();
String encodage = document.getXmlEncoding();
if(document.getXmlStandalone())
  System.out.println("Le document est autonome !");
else
  System.out.println("Le document n'est pas autonome !");

L'encodage de caractères employé au moment de l'analyse du document peut différer de celui déclaré dans le prologue. La méthode getInputEncoding() fournit cette information.

String encodage_analyse = document.getInputEncoding()

La configuration du DOM pour le document courant présente divers paramètres, identiques aux propriétés de SAX 2. Ces propriétés indiquent comment certains composants d'un document XML doivent être traités lors du processus de normalisation. Par exemple, les commentaires doivent ils être ignorés, les sections CDATA doivent elles être transformées en noeuds textes, lesquels s'ils sont adjacents doivent ils être fusionnés, les références d'entités doivent elles être développées, etc.

DOMConfiguration config = document.getDomConfig();
DOMStringList liste = config.getParameterNames();
for(int i = 0; i < liste.getLength(); i++){
  String nom = liste.item(i);
  Object valeur = liste.getParameter(nom);
  System.out.println(nom + " = " + valeur);
}

Le premier noeud est obtenu par la méthode getDocumentElement() de l'objet Document.

Element racine = doument.getDocumentElement();

L'élément racine étant un descendant (héritage) d'un noeud, les méthodes et attributs de l'objet Node sont utilisables pour récupérer des informations sur le noeud et sa descendance.

String nom = racine.getNodeName();
String valeur = racine.getNodeValue();
short type = $racine->getNodeType();
Node pere = racine.getParentNode();
NodeList liste_enfants = racine.getChildNodes();
NodeNamedMap attributs = racine.getAttributes();
Document document = racine.getOwnerDocument();
String texte = racine.getTextContent();

D'autres méthodes d'un Node permettent d'accéder aux noeuds environnants.

Node noeud = liste_enfants.item(3);
Node premier_enfant = noeud.getFirstChild();
Node dernier_enfant = noeud.getLastChild();
Node grand_frere = noeud.getPreviousSibling();
Node petit_frere = noeud.getNextSibling();

La méthode getChildNodes() est particulièrement utile pour parcourir rapidement et facilement une arborescence XML. Il suffit d'employer une boucle pour accéder à chaque enfant de la liste de noeuds obtenus.

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.IOException;

public class Parcours {
  public static void main(String[] args) {
    try {
      DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
      DocumentBuilder analyseur = fabrique.newDocumentBuilder();
      Document document = analyseur.parse("employes.xml");
      Element racine = document.getDocumentElement();
      System.out.println("ELEMENT RACINE");
      afficherInfos(racine);
      NodeList liste = racine.getChildNodes();

      System.out.println("ENFANTS DE L'ELEMENT RACINE");
      for (int i = 0; i < liste.getLength(); i++) {
        Node noeud = liste.item(i);
        afficherInfos(noeud);
      }
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
  }
  public static void afficherInfos(Node noeud) {
    String nom = noeud.getNodeName();
    String valeur = noeud.getNodeValue();
    short type = noeud.getNodeType();
    if (type == Node.ELEMENT_NODE)
      valeur = noeud.getTextContent();
    System.out.println(nom + " (" + type + ") = '" + valeur + "'");
  }
}

La nouvelle boucle for du JDK 1.5, pourrait également servir à parcourir la liste de noeuds.

for(Node noeud : liste){
  afficherInfos(noeud);
}

Le parcours complet de l'arborescence demande une fonction récursive afin que chaque élément rencontré puisse être exploré à son tour, s'il possède des noeuds enfants (hasChildNodes()).

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.IOException;

public class Parcours {
  public static void main(String[] args) {
    try {
      DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
      DocumentBuilder analyseur = fabrique.newDocumentBuilder();
      Document document = analyseur.parse("employes.xml");
      afficherInfos(document, 0);
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
  }
  public static void afficherInfos(Node noeud, int niv) {
    short type = noeud.getNodeType();
    String nom = noeud.getNodeName();
    String valeur = noeud.getNodeValue();
    indenter(niv, type == Node.TEXT_NODE);
    System.out.print(nom + " (" + type + ") = '");
    if(valeur != null && !valeur.matches("^\\s+$"))
      System.out.print(valeur);
    System.out.println("'");

    if ((type == Node.DOCUMENT_NODE 
        || type == Node.ELEMENT_NODE)
        && noeud.hasChildNodes()) {
      NodeList liste = noeud.getChildNodes();
        for(int i = 0; i < liste.getLength(); i++)
        afficherInfos(liste.item(i), niv + 1);
    }
  }
  public static void indenter(int n, boolean texte){
    String tab = "\t";
    for(int i = 0; i < n; i++){
      System.out.print(tab);
    }
    if(texte)
      System.out.print(" - ");
    else
      System.out.print(" + ");
  }
}

35.1.1.1 / Les attributs

Seuls les éléments XML contiennent des attributs. Fort de cette constatation, il suffit de tester si le noeud rencontré est un élément et que ce dernier possède des attributs (hasAttributes()). Puis avec la méthode getAttributes() de l'objet Node, une collection NamedNodeMap est obtenue. Cet objet contient des attributs référencés par leur nom. Ainsi, les attributs peuvent être trouvés par leur nom.

NamedNodeMap attributs = noeud.getAttributes();
Node attribut = attributs.getNamedItem("service");

En outre, une itération peut également faire l'affaire pour accéder aux attributs de cette collection

public static void afficherInfos(Node noeud, int niv) {
  short type = noeud.getNodeType();
  String nom = noeud.getNodeName();
  String valeur = noeud.getNodeValue();
  indenter(niv, type == Node.ELEMENT_NODE);
  System.out.print(nom + " (" + type + ") = '");
  if (valeur != null && !valeur.matches("^\\s+$"))
    System.out.print(valeur);
  System.out.println("'");

    if ((type == Node.DOCUMENT_NODE 
        || type == Node.ELEMENT_NODE)
      && noeud.hasChildNodes()) {
    if (noeud.hasAttributes()) {
      NamedNodeMap attributs = noeud.getAttributes();
      for (int i = 0; i < attributs.getLength(); i++) {
        Node attribut = attributs.item(i);
        afficherInfos(attribut, niv + 2);
      }
    }
    NodeList liste = noeud.getChildNodes();
    for (int i = 0; i < liste.getLength(); i++)
      afficherInfos(liste.item(i), niv + 1);
  }
}

Par ailleurs, plusieurs méthodes de l'objet Element permettent de récupérer un attribut ou sa valeur, à l'aide de son nom et éventuellement de son espace de noms. Il s'agît des méthodes getAttribute() et getAttributeNS() ou getAttributeNode() et getAttributeNodeNS() qui retournent respectivement la valeur de l'attribut ou un objet Attr.

NodeList noeuds = document.getElementsByTagName("employe");
for(int i = 0; i < noeuds.getLength(); i++){
  Node noeud = noeuds.item(i);
  Attr service = noeud.getAttributeNode("service");
  afficherInfos(service, 0);
  String id = noeud.getAttribute("id");
  System.out.println("ID = " . id);
}

La méthode getElementsByTagName() des objets Document et Element retourne une liste de noeuds correspondant au nom passé en argument.

NodeList employes = document.getElementsByTagName("employes");
for(int i = 0; i < employes.getLength(); i++){
  Element employe = (Element)employes.item(i);
  Element nom = employe.getElementsByTagName("nom").item(0);
  Element prenom = employe.getElementsByTagName("prenom").item(0);
}

Si le document possède des attributs ID permettant d'identifier sans ambiguités des éléments, il est possible d'employer la méthode getElementById() afin de récupérer l'élément correspondant à un identificateur passé en argument. Toutefois, le document XML doit être validé par une DTD, un schéma XML ou un schéma Relax NG. En effet, les attributs portant le nom id ne sont pas reconnus comme des identificateurs tant qu'ils n'ont pas été définis avec le type ID dans une DTD ou autres.

DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
fabrique.setValidating(true);
DocumentBuilder analyseur = fabrique.newDocumentBuilder();
Document document = analyseur.parse("employes.xml");
Element element = document.getElementById("GA1013");
afficherInfos(element, 0);

En cas de suppression de la déclaration DOCTYPE de la source XML, la méthode getElementById() deviendra alors inopérante.

Lors du parcours des attributs d'un élément XML, la méthode isId() des objets Attr, détermine si l'attribut en cours est ou n'est pas un attribut identificateur défini. A l'instar de la méthode getElementById(), le document doit être validé.

Nodelist elements = racine.getElementsByTagName("employes");
for(int i = 0; i < elements.getLength(); i++){
  Element element = (Element)elements.item(i);
  Attr id = element.getAttributeNode("id");
  if(id.isId()){
    System.out.println("L'attribut est bien un identificateur !");
  }
}

35.1.1.2 / La DTD et les instructions de traitement

Le noeud DocumentType représentant la déclaration de type de document, peut livrer des informations sur le contenu de la DTD, soit les entités, les notations, les identificateurs PUBLIC ou/et SYSTEM et le nom de l'élément racine du document. L'objet DocumentType est délivré par la méthode getDocType() de l'objet Document. Evidemment si le document XML ne possède pas de déclaration de type de document, la valeur null sera retournée.

public class Parcours {
  public static void main(String[] args) {
    try {
      DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
      DocumentBuilder analyseur = fabrique.newDocumentBuilder();
      fabrique.setValidating(true);
      Document document = analyseur.parse("onu.xml");
      DocumentType dtd = document.getDoctype();
      afficherInfos(dtd, 0);
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
  }
  public static void afficherInfos(Node noeud, int niv) {
    short type = noeud.getNodeType();
    String nom = noeud.getNodeName();
    String valeur = noeud.getNodeValue();
    System.out.print(nom + " (" + type + ") = '");
    if (valeur != null && !valeur.matches("^\\s+$"))
      System.out.print(valeur);
    System.out.println("'");

    if(type == Node.ENTITY_NODE) {
      Entity entite = (Entity)noeud;
      System.out.println("\tID Public : " + entite.getPublicId());
      System.out.println("\tID Système : " + entite.getSystemId());
      System.out.println("\tNom de notation : " + entite.getNotationName());
      System.out.println("\tEncodage d'entrée : " + entite.getInputEncoding());
      System.out.println("\tEncodage XML : " + entite.getPublicId());
      System.out.println("\tVersion XML : " + entite.getSystemId());
      System.out.println("\tTexte : " + entite.getTextContent());
    }
    else if(type == Node.NOTATION_NODE) {
      Entity entite = (Entity)noeud;
      System.out.println("\tID Public : " + entite.getPublicId());
      System.out.println("\tID Système : " + entite.getSystemId());
      System.out.println("\tTexte : " + entite.getTextContent());
    }
    else if(type == Node.DOCUMENT_TYPE_NODE) {
      DocumentType dtd = (DocumentType)noeud;
      NamedNodeMap entites = dtd.getEntities();
      NamedNodeMap notations = dtd.getNotations();
      System.out.println("\tID Public : " + dtd.getPublicId());
      System.out.println("\tID Système : " + dtd.getSystemId());
      System.out.println("\tTexte : " + dtd.getTextContent());

      for(int i = 0; i < notations.getLength(); i++) {
        Node n = notations.item(i);
        afficherInfos(n, 0);
      }
      for(int i = 0; i < entites.getLength(); i++) {
        Node n = entites.item(i);
        afficherInfos(n, 0);
      }
    }
  }
}

Les instructions de traitement sont composées d'une cible et d'un contenu, lesquels sont disponibles à partir des méthodes de l'objet ProcessingInstruction.

DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabrique.newDocumentBuilder();
fabrique.setValidating(true);
Document document = analyseur.parse("logitheque.xml");
NodeList liste = document.getChildNodes();
for(int i = 0; i < liste.getLength(); i++){
  if(liste.item(i) instanceof ProcessingInstruction){
    ProcessingInstruction pi = (ProcessingInstruction)liste.item(i);
    System.out.print("Cible : " + pi.getTarget());
    System.out.print("Contenu : " + pi.getData());
  }
}

35.1.2 / Modification d'un document DOM

Un document XML peut nécessiter une mise à jour de sa structure et de ses données. Le DOM dispose de méthodes capables de remplacer et de supprimer des noeuds et de modifier des données textuelles.

La méthode removeChild() de l'objet Node supprime le noeud spécifié de la liste des enfants.

DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabrique.newDocumentBuilder();
analyseur.setValidating(true);
Document doc_xml = analyseur.parse(new File("source.xml"));
Element element = doc_xml.getElementById("XSY210356");
Element racine = doc_xml.getDocumentElement();
Node noeud_sup = racine.removeChild(element);

/*Contenu du document XML :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
  </logiciel>
</liste>*/

De cette manière n'importe quel noeud dans l'arborescence XML peut être supprimé. Pour un noeud textuel, il suffit de cibler l'objet contenant le texte, puis de soumettre l'enfant de ce dernier à la méthode removeChild().

NodeList commentaires = doc_xml.getElementsByTagName("commentaire");
for(int i = 0; i < commentaires.getLength(); i++){
  Node commentaire = commentaires.item(i);
  if(commentaire.hasChildNodes()){
    Node texte = commentaire.getChildNodes().item(0);
    commentaire.removeChild(texte);
  }
}

/*Tous les éléments commentaire
deviennent des éléments vides <commentaire/>
*/

Après suppression, un noeud Element peut devenir un élément vide.

for(int i = noeuds.getLength() - 1; i >= 0; i--){
  Node noeud = noeuds.item(i);
  Node noeud_sup = element.removeChild(noeud);
}
/*L'arborescence de l'élément logiciel avec id="XSY210356"
devient un élément vide <logiciel id="XSY210356"/>
*/

La méthode removeChild() est susceptible de lancer trois exceptions :

Les attributs peuvent être supprimés d'un élément en utilisant les méthodes de suppression d'attributs de l'objet Element.

Element logiciel = document.getElementById("CTP0124555");
if(logiciel != null){
  Element element = logiciel.getChildNodes().item(0);
  element.removeAttribute("systeme_exploitation");
  if(!element.hasAttribute("systeme_exploitation"))
    System.out.println("L'attribut systeme_exploitation a été supprimé !");

  Node attribut = element.getAttributes().item(0);
  if(element.removeAttributeNode(attribut) != null)
    System.out.println("L'attribut " + attribut.getNodeName() +  " a été supprimé !");
}
/*Contenu du document XML :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    <nom>Cooktop 2.200</nom>
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
  </logiciel>
  <logiciel id="XSY210356">
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
  </logiciel>
</liste>*/

Une autre méthode de suppression existe, mais elle doit être employée pour un attribut situé dans un espace de noms. Il s'agît de la méthode removeAttributeNS().

La méthode replaceChild() remplace un noeud par un autre.

NodeList elements = document.getElementsByTeagName("commentaire");
Node element1 = elements.item(0);
Node element2 = elements.item(elements.getLength() - 1);
Node texte1 = element1.getFirstChild().cloneNode();
Node texte2 = element2.getFirstChild().cloneNode();
Node nouv_noeud1 = element1.replaceChild(
                              texte2, 
                              element1.getFirstChild());
Node nouv_noeud2 = element2.replaceChild(
                              texte1, 
                              element2.getFirstChild());

/*Contenu du document :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    ...
    <commentaire>
      Permet de creer des documents XML.
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
  </logiciel>
  <logiciel id="XSY210356">
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
    <commentaire>
      Un editeur XML, XSLT, XPath et DTD puissant et totalement gratuit.
    </commentaire>
  </logiciel>
    ...
</liste>*/

Cette méthode peut lancer plusieurs exceptions :

Les chaînes de caractères présentes dans les noeuds textuels peuvent être modifiées complètement ou partiellement. La classe CharacterData propose des méthodes de modification du contenu textuel d'un noeud.

DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabrique.newDocumentBuilder();
analyseur.setValidating(true);
Document doc_xml = analyseur.parse(new File("source.xml"));
NodeList logiciels = doc_xml.getElementsByTagName("logiciel");
for(int i = 0; i < logiciels.getLength(); i++){
  Node logiciel = logiciels.item(i);
  NodeList noms = logiciel.getElementsByTagName("nom");
  Node nom = noms.item(0).getFirstChild();
  NodeList commentaires = logiciel.getElementsByTagName("commentaire");
  Node commentaire = commentaires.item(0).getFirstChild();
  //Insertion du nom devant le commentaire
  commentaire.insertData(0, " : ");
  commentaire.insertData(0, nom.getNodeValue());
  NodeList colprix = logiciel.getElementsByTagName("prix");
  Node prix = colprix.item(0).getFirstChild();
  int pos = commentaire.getNodeValue().indexOf(".");
  int taille = commentaire.getNodeValue().length();
  //Suppression du point terminal et des espaces blancs
  commentaire.deleteData(pos , taille - pos);
  //Ajout du prix entre parenthèses
  commentaire.appendData("(");
  commentaire.appendData(prix.getNodeValue());
  commentaire.appendData(").");
}

/*Affiche :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE liste [...]>
<liste>
  <logiciel id="CTP0124555">
    ...
    <commentaire>
      Cooktop 2.200
      : 
      Un editeur XML, XSLT, XPath et DTD puissant et totalement gratuit
      (00.00).
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XSY325684">
    ...
    <commentaire>
      XML Spy 4.1
      : 
      Un editeur XML desormais mature
      (199,00).
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XSY210356">
    ...
    <commentaire>
      XML Spy 4.1 B2B Server
     : 
      La version 4 en version Business to business
    (1 999,00).
    </commentaire>
    ...
  </logiciel>
  <logiciel id="XWR387795">
    ...
    <commentaire>
      XMLwriter v1.21
      : 
      Permet de creer des documents XML
      (75,00).
    </commentaire>
    ...
  </logiciel>
</liste>
*/

for(int i = 0; i < logiciels.getLength(); i++){
  Node logiciel = logiciel.item(i);
  NodeList noms = logiciel.getElementsByTagName("nom");
  Node nom = noms.item(0).getFirstChild();
  NodeList commentaires = logiciel.getElementsByTagName("commentaire");
  Node commentaire = commentaires.item(0).getFirstChild();
  int pos = commentaire.getNodeValue().indexOf(":");
  //Suppression du nom du logiciel
  commentaire.deleteData(0, pos + 1);
  pos = commentaire.getNodeValue().indexOf("(");
  taille = commentaire.getNodeValue().getLength();
  //Remplacement du prix entre parenthèses par un point terminal
  commentaire.replaceData(pos, taille - pos, ".");
}

//Retour à la source d'origine

Les méthodes appendData(), deleteData(), insertData(), replaceData() et substringData() s'appliquent à tous les noeuds héritant de la classe CharacterData, en l'occurrence Text, Comment et CDataSection. La méthode setData() assigne une chaîne de caractères au noeud textuel. Si ce dernier possèdait déjà un contenu, celui-ci serait supprimé et remplacé par le nouveau texte.

La valeur des attributs est fixée par la méthode setValue() de la classe Attr ou setNodeValue() de la classe Node.

public class Attribut {
  public static void main(String[] args) {
    try {
      URL url = new URL("http://laltruiste.com/coursjava/exemples/logitheque.xml");
      InputSource source = new InputSource(url.openStream());
      XPathFactory fabrique = XPathFactory.newInstance();
      XPath environnement = fabrique.newXPath();
      XPathExpression expression = environnement.compile("//logiciel/prix");
      NodeList colPrix = (NodeList) 
                       expression.evaluate(source, XPathConstants.NODESET);
      for (int i = 0; i < colPrix.getLength(); i++) {
        Element noeud = (Element) colPrix.item(i);
        Attr monnaie = noeud.getAttributeNode("monnaie");
        if (monnaie.getNodeValue().equals("FRF")) {
          monnaie.setValue("€");
          String valeur = noeud.getFirstChild().getNodeValue()
                                     .replaceAll(" ", "").replaceAll(",", ".");
          double nb = new Double(valeur).doubleValue() / 6.55957;
          noeud.getFirstChild().setNodeValue(String.valueOf(nb));
        }
      }
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    catch (XPathExpressionException e) {
      e.printStackTrace();
    }
  }
}

35.1.3 / La création d'objets DOM

La création ou la modification d"un document XML existant s'accomplit aisément avec les outils proposés par le DOM.

La création d"objets du DOM s'obtient par l'invocation des méthodes de création de l'objet Document.

Attr attribut = document.createAttribute("unAttribut");
Attr attr_ns = document.createAttributeNS(
                         "http://www.laltruiste.com/", "lal:unAttribut");
CDATASection cdata = 
             document.createCDATASection("Un texte non analysable...");
Comment commentaire = document.createComment("Un commentaire...");
Element element = document.createElement("unElement", "Une valeur...");
Element elt_ns = document.createElementNS(
                         "http://www.laltruiste.com/", "lal:unElement", "Une valeur...");
EntityReference entite = document.createEntityReference("&amp;");
ProcessingInstruction pi = document.createProcessingInstruction(
                         "xml-stylesheet", "href="style.xsl" type="text/xsl"");
Text texte = document.createTextNode("Un texte...");

Désormais, il faut pouvoir insérer ces objets au sein d'un document XML.

Les noeuds éléments ou textuels se greffent dans un document par l'intermédiaire de la méthode appendChild() de l"objet Node.

DocumentBuilderFactory fabriqueDOM = DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabriqueDOM.newDocumentBuilder();
Document document = analyseur.newDocument();
document.setXmlVersion("1.0");
document.setXmlEncoding("ISO-8859-1");
Element racine = document.createElement("racine");
document.appendChild(racine);

/*création de :
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine/>
*/

L'ajout d'un élément ou d'un texte à un élément parent est identique. Le noeud cible de l'ajout doit invoquer la méthode appendChild() pour qu'un nouveau noeud soit ajouter en son sein et à la fin de ses enfants éventuels.

Element enfant = document.createElement("enfant");
racine.appenChild(enfant);
CDATASection cdata = document.createCDATASection("<balise/> -> Balise vide");
Node noeud_ajoute = enfant.appendChild(cdata);

/*création de :
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine>
<enfant>
<![CDATA[<balise/> -> Balise vide]]>
</enfant>
</racine>
*/

La méthode appendChild() retourne le noeud nouvellement ajouté. En outre, cette méthode est susceptible de lancer des exceptions.

Les attributs s'ajoutent aux éléments d"une manière différente. En effet, il faut passer par les méthodes d'ajout d'attribut de l'objet Element.

Element element = document.createElement("elt");
boolean reussi = element.setAttribute("attribut", "valeur");
Attr attribut = document.createAttribute("attribut", "valeur");
reussi = element.setAttributeNode(attribut);
attr_ns = element.setAttributeNS(
                        "http://www.laltruiste.com/", 
                        "lal:attr_ns", 
                        "Valeur de l'attribut");

Attr attribut_ns = document.createAttribute("lal:attribut_ns");
attribut_ns.setValue("Une valeur d'attribut");
Attr nouv_attr = element.setAttributeNodeNS(attribut_ns);
if(attribut_ns.isSameNode(attribut_ns))
  System.out.println("Le noeud a bien été ajouté puisqu'ils sont identiques !");

/*création de :
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine>
  <enfant>
    <![CDATA[<balise/> -> Balise vide]]>
    <elt 
            xmlns:lal="../" 
            attribut="valeur" 
            lal:attr_ns="Valeur de l'attribut" 
            lal:attribut_ns="Une valeur d'attribut"/>
  </enfant>
</racine>
*/

L'ajout ou la modification d'une valeur textuelle à un attribut s'effectue par l'intermédiaire de la méthode setValue() ou setNodeValue() héritée de l'objet Node.

Le clonage des noeuds se réalise avec la méthode cloneNode() de l'objet DOMNode.

Node clone = enfant.clonNode(true);
racine.appendChild(clone);

/*création de :
<?xml version="1.0" encoding="ISO-8859-1"?>
<racine>
  <enfant>
    <![CDATA[<balise/> -> Balise vide]]>
    <elt 
            xmlns:lal="../" 
            attribut="valeur" 
            lal:attr_ns="Valeur de l"attribut" 
            lal:attribut_ns="Une valeur d"attribut"/>
  </enfant>
  <enfant>
    <![CDATA[<balise/> -> Balise vide]]>
    <elt 
            xmlns:lal="../" 
            attribut="valeur" 
            lal:attr_ns="Valeur de l"attribut" 
            lal:attribut_ns="Une valeur d"attribut"/>
  </enfant>
</racine>
*/

Si ce genre d'ajout avait été tenté sans clonage :

La méthode importNode() de l'objet DOMDocument fournit un moyen d'importation d'un noeud avec éventuellement toute sa descendance au sein d'un autre document que le propriétaire du noeud importé.

Document nouv_doc = analyseur.newDocument();
nouv_doc.setXmlVersion("1.0");
nouv_doc.setXmlEncoding("ISO-8859-1");
Node import = nouv_doc.importNode(enfant, true);
nouv_doc.appendChild(import);

/*création de :
<?xml version="1.0" encoding="ISO-8859-1"?>
<enfant>
  <![CDATA[<balise/> -> Balise vide]]>
  <elt 
          xmlns:lal="../" 
          attribut="valeur" 
          lal:attr_ns="Valeur de l"attribut" 
          lal:attribut_ns="Une valeur d"attribut"/>
</enfant>
*/

La méthode adoptNode() déplace un noeud et son arborescence d'un document vers un autre. Le noeud cible de l'adoption est supprimé de son document d'appartenance et est placé dans le document hôte. Contrairement à la méthode importNode(), le noeud n'existe plus dans le document d'origine après l'adoption de ce dernier.

Node adopte = document.adoptNode(enfant);

Les références d'entité peuvent être ajoutées directement dans un élément avec la méthode appendChild().

Document document = analyseur.newDocument();
document.setXmlVersion("1.0");
document.setXmlEncoding("ISO-8859-1");
Element element = document.createElement("zoneTexte");
EntityReference ref = document.createEntityReference("eacute");
Text texte1 = document.createtextNode("La r");
Text texte2 = document.createtextNode("f");
Text texte3 = document.createtextNode("rence d'entit");
elt.appendChild(texte1);
element.appendChild(ref);
element.appendChild(texte2);
element.appendChild(ref.cloneNode());
element.appendChild(texte3);
element.appendChild(ref.cloneNode());
document.appendChild(element);

/*création de :
<?xml version="1.0" encoding="ISO-8859-1"?>
<zoneTexte>
  La référence d"entité
</zoneTexte>
*/

Les chaînes de caractères peuvent être ajoutées ou insérées dans un objet textuel à l'aide des méthodes appendData() et insertData(), voire même replaceData() de l'objet CharacterData.

Document document = analyseur.newDocument();
document.setXmlVersion("1.0");
document.setXmlEncoding("ISO-8859-1");
Element element = document.createElement("citation");
CDATASection texte = document.createCDATASection("On n'est jamais si hereu");
texte.appendData("ni si malheureux qu'on s'imagine.");
texte.appendData("La Rochefoucauld, Maximes.");
texte.replaceData(19, 5, "heureux");
texte.insertData(26, " ");
texte.insertData(60, "<br/>(");
texte.insertData(0, "<p>");
texte.appendData(")</p>");
element.appendChild(texte);
document.appendChild(element);

/*création de :
<?xml version="1.0" encoding="ISO-8859-1"?>
<citation>
  <![CDATA[
     <p>On n'est jamais si heureux ni 
            si malheureux qu"on s'imagine.
            </br>(La Rochefoucauld, Maximes.)</p>]]>
</citation>
*/

35.1.4 / Les implémentations DOM

L'objet DOMIplementation fournit un ensemble de méthodes permettant de créer un document et une délaration de type de document.

Les objets obtenus par les méthodes createDocumentType() et createDocument() sont indépendants de n'importe quelles instances particulières du modèle d'objet de document.

DOMImplementation impl = document.getImplementation();
DocumentType dtd = impl.createDocumentType(
                      "html", 
                      "-//W3C//DTD XHTML 1.0 Strict//EN", 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
Document doc = impl.createDocument(
                       "http://www.w3.org/1999/xhtml", 
                       "html", 
                       dtd);

Un document créé par la méthode newDocument() de la classe DocumentBuilder, ne possède pas d'élément racine entraînant donc une malformation initiale. La méthode createDocument() indique dès la conception l'élément racine indispensable pour obtenir un document bien-formé, mais en plus peut être valide grâce aux identificateurs PUBLIC et SYSTEM. L'emploi de cette alternative à DocumentBuilder paraît une solution plus appropriée pour la création d'un nouveau document XML.

Deux autres méthodes permettent d'accéder à un objet implémentant l'API spécialisée d'une caractéristique DOM et de sa version ou de vérifier si elles sont implémentées par l'implémentation courante. Ces caractéristiques portent un nom et un numéro de version qui ne peut être que 1.0 pour DOM Level 1 Specification, 2.0 pour DOM Level 2 Core Specification et 3.0 pour DOM Level 3 Core Specification

Object resultat = doc.getFeature("Core", "2.0);
if(doc.hasFeature("Events", "2.0"))
  System.out.println("La caractéristique est supportée !");
Caractéristique Version Spécification
XML 1.0 Document Object Model (Core) Level 1
Core 1.0 Document Object Model (Core) Level 1
HTML 1.0 Document Object Model (HTML) Level 1
XML 2.0 Document Object Model Level 2 Core
Core 2.0 Document Object Model Level 2 Core
HTML 2.0 Document Object Model HTML
Views 2.0 Document Object Model Views
Events 2.0 Document Object Model Events
StyleSheets 2.0 Document Object Model Style Sheets
CSS 2.0 Document Object Model CSS
Traversal 2.0 Document Object Model Traversal
Range 2.0 Document Object Model Range
XML 3.0 Document Object Model Level 3 Core
Core 3.0 Document Object Model Level 3 Core
LS 3.0 Document Object Model Load and Save
LS-Async 3.0 Document Object Model Load and Save
Validation 3.0 Document Object Model Validation
xpath 3.0 Document Object Model XPath
Events 3.0 Document Object Model Level 3 Events
AS-READ 3.0 Abstract Schemas Object Model for Read
AS-EDIT 3.0 Abstract Schemas Object Model for Editing
AS-DOC 3.0 Abstract Schemas Object Model for Document Editing
ViewsAndFormatting   Document Object Model Views and Formatting (Generic)
VisualViewsAndFormatting   Document Object Model Views and Formatting (Visual properties)
org.w3c.dom.mathml   Mathematical Markup Language Version 2.0
org.w3c.svg   SVG 1.0
org.w3c.dom.svg   SVG DOM
TimeControl   SMIL Animation
import org.w3c.dom.DOMImplementation;
public class Caracteristiques {
  private static String[][] caracteristiques = 
                          {{"XML", "1.0"},
                           {"Core", "1.0"},
                           {"HTML", "1.0"},
                           {"XML", "2.0"},
                           {"Core", "2.0"},
                           {"HTML", "2.0"},
                           {"Views", "2.0"},
                           {"Events", "2.0"},
                           {"StyleSheets", "2.0"}
                           {"CSS", "2.0"},
                           {"Traversal", "2.0"},
                           {"Range", "2.0"},
                           {"XML", "3.0"},
                           {"Core", "3.0"},
                           {"LS", "3.0"},
                           {"LS-Async", "3.0"},
                           {"Validation", "3.0"},
                           {"xpath", "3.0"},
                           {"Events", "3.0"},
                           {"AS-READ", "3.0"},
                           {"AS-EDIT", "3.0"},
                           {"AS-DOC", "3.0"}};
  public static void main(String args[]){
    DOMImplementation implDOM = 
                      DOMImplementationImpl.getDOMImplementation();
     for (int i = 0; i < caracteristiques.length; i++){
       System.out.print(caracteristiques[i][0] + " " 
                      + caracteristiques[i][1] +" : ");
       if(implDOM.hasFeature(
                             caracteristiques[i][0], 
                             caracteristiques[i][1]))
         System.out.println("supportée");
       else
         System.err.println("non-supportée");
     }
  }
}

La classe DOMImplementationRegistry constitue une fabrique d'objets DOMImplementation. Dans le but d'obtenir une implémentation DOM personnalisées, il suffit d'invoquer la méthode getDOMImplementation() et de lui passer une liste des caractéristiques devant être supportées par l'objet DOMImplementation retourné. La liste possède des noms de caractéristiques avec leur numéro de version, séparés par des espaces.

DOMImplementationRegistry enregistreur =
                    DOMImplementationRegistry.newInstance();
//Implémentation DOM supportant XML 3.0
DOMImplementation implDOM3 =
                    enregistreur.getDOMImplementation("XML 3.0");
//Implémentation DOM supportant XML 1.0 Traversal et Events 2.0
DOMImplementation implDOM =
                    enregistreur.getDOMImplementation(
                                    "XML 1.0 Traversal Events 2.0");

La vérification du support de caractéristiques particulières par une implémentation, s'effectue par le truchement de la méthode hasFeature(), à laquelle il faut spécifier le nom de la caractéristique et sa version.

DOMImplementationRegistry enregistreur =
                    DOMImplementationRegistry.newInstance();
DOMImplementation implDOM3 =
                    enregistreur.getDOMImplementation("XML 3.0");
if(implDOM3.hasFeature("LS", "3.0"))
  System.out.println(
         "L'implémentation supporte l'API DOM Level 3 Load and Save.");

Etant donné qu'il n'est pas possible de créer une DTD, et partant, d'en affecter une à un objet Document déjà chargé, les méthodes createDocumentType() et createDocument() pallient à ce problème. L'utilisation directe de l'implémentation DOM sous-jacente, telle que Xerces, peut également résoudre ce problème. En effet, la classe org.apache.xerces.dom.CoreDocumentImpl possède une méthode createDocumentType().

En premier lieu, une instance de DOMImplementation doit être obtenue. Puis, à partir de cet objet, la méthode createDocumentType() construit une déclaration de type de document avec le nom de l'élément racine et éventuellement les identificateurs public et système. Ce dernier peut être un chemin vers une définition DTD locale. Enfin, un objet Document est conçu avec la méthode createDocument() à laquelle on spécifie l'objet DocumentType et éventuellement une adresse URI d'espace de noms et un nom qualifié.

Finalement, il ne reste plus qu'à importer l'élément racine du document dénué de DTD, et l'ajouter dans le nouveau document XML.

public class Programme {
  public static void main(String[] args){
    String fichier = "societe";
    DocumentBuilderFactory fabrique = 
                                DocumentBuilderFactory.newInstance();
    DocumentBuilder analyseur = fabrique.newDocumentBuilder();
    Document doc_xml = analyseur.parse(new File(fichier + ".xml"));
    System.out.println("Le document XML " + fichier + " a été chargé !";
    
    DomImplementation impl = document.getImplementation();
    Documentype dtd = impl.createDocumentType(
                                 fichier, "", fichier + ".dtd");
    Document doc = impl.createDocument(fichier, "",dtd);
    doc.setXmlVersion("1.0");
    doc.setXmlEncoding("ISO-8859-1");
    doc.setXmlStandalone("no");
    doc.setValidating(true);
    Node racine = doc.importNode(doc.getDocumentElement(), true);
    doc.appendChild(racine);
  }
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Fichier : societe.xml -->
<societe>
  <services>
    <service id="DG001">
      <designation>Direction générale</designation>
    </service>
    <service id="ST001">
      <designation>Service technique</designation>
    </service>
    <service id="SC001">
      <designation>Service commercial</designation>
    </service>
    <service id="SC101">
      <designation>Service clientèle</designation>
    </service>
    <service id="RH001">
      <designation>Ressources humaines</designation>
    </service>
    <service id="SQ001">
      <designation>Service qualité</designation>
    </service>
    <service id="SP001">
      <designation>Service production</designation>
    </service>
    <service id="RD001">
      <designation>Recherche et développement</designation>
    </service>
  </services>
  <divisions>
    <division id="A001" services="DG001 RH001"/>
    <division id="B001" services="SC001 SC101"/>
    <division id="C001" services="SP001 SQ001 RD001"/>
  </divisions>
  <employes>
    <employe id="RJ1002" service="DG001">
      <nom>Robierre</nom>
      <prenom>Jean</prenom>
    </employe>
    <employe id="LA1012" service="DG001">
      <nom>Lardut</nom>
      <prenom>Anne</prenom>
    </employe>
    <employe id="GA1013" service="ST001">
      <nom>Guilde</nom>
      <prenom>Angelique</prenom>
    </employe>
    <employe id="HP1022" service="SC001">
      <nom>Henry</nom>
      <prenom>Paul</prenom>
    </employe>
    <employe id="MM1045" service="RH001">
      <nom>Mortier</nom>
      <prenom>Marc</prenom>
    </employe>
    <employe id="LS1102" service="SQ001">
      <nom>Lebreton</nom>
      <prenom>Sophie</prenom>
    </employe>
    <employe id="JM1095" service="RD001">
      <nom>Jolie</nom>
      <prenom>Martine</prenom>
    </employe>
    <employe id="MT1036" service="SC101">
      <nom>Marcelin</nom>
      <prenom>Tania</prenom>
    </employe>
    <employe id="LL1029" service="SC101">
      <nom>Leger</nom>
      <prenom>Laurence</prenom>
    </employe>
    <employe id="DM1052" service="SC001">
      <nom>Duroi</nom>
      <prenom>Maxime</prenom>
    </employe>
  </employes>
</societe>

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Fichier : societe.dtd -->
<!ELEMENT designation (#PCDATA)>
<!ELEMENT division EMPTY>
<!ATTLIST division
    id ID #REQUIRED
    services IDREFS #REQUIRED
>
<!ELEMENT divisions (division+)>
<!ELEMENT employe (nom, prenom)>
<!ATTLIST employe
    id ID #REQUIRED
    service IDREF #REQUIRED
>
<!ELEMENT employes (employe+)>
<!ELEMENT nom (#PCDATA)>
<!ELEMENT prenom (#PCDATA)>
<!ELEMENT service (designation)>
<!ATTLIST service id ID #REQUIRED>
<!ELEMENT services (service+)>
<!ELEMENT societe (services, divisions, employes)>

35.1.5 / La sauvegarde DOM

La sauvegarde d'un document XML permet de conserver les éventuelles modifications de valeurs ou de structure pratiquées sur ce document.

La sauvegarde d'un document XML s'effectue généralement par l'intermédiaire de certaines classes du paquetage java.xml.transform.

La classe TransformerFactory consitue une fabrique d'objets Transformer à partir desquels, des propriétés de sortie peuvent être spécifiées.

TransformerFactory tfabrique = TransformerFactory.newInstance();
Transformer transformeur = tfabrique.newTransformer();

Ces paramètres sont la méthode de rendu (methode = "xml | html | text | autre"), l'encodage de caractères (encoding = "ISO-8859-1 | UTF-16 | UTF-8 | autre"), l'indentation du texte (indent = "yes | no"), l'écriture du prologue XML (omit-xml-declaration = "yes | no"), la spécification d'un identificateur PUBLIC et/ou SYSTEM (doctype-public = "Identificateur" et doctype-system = "Identificateur"), etc. Les propriétés de sortie représentent les attributs de 'élément XSLT xsl:output, lequel indique le format de sortie du document résultant dans une feuille de style de transformation. La méthode setOutputProperties() permet d'assigner les propriétés aux objets Transformer.

Properties proprietes = new Properties();
proprietes.put("method", "xml");
proprietes.put("version", "1.0"); 
proprietes.put("encoding", "ISO-8859-1"); 
proprietes.put("standalone", "yes");
proprietes.put("indent", "yes");
proprietes.put("omit-xml-declaration", "no");
transformeur.setOutputProperties(proprietes);

Ensuite, un objet Source doit être conçu à partir d'une ressource XML DOM (Document Object Model) ou SAX (Simple API XML).

DocumentBuilderFactory fabrique = 
                               DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabrique.newDocumentBuilder();
Document document = analyseur.parse(new File("logitheque.xml"));
DOMSource entree = new DOMSource(document);

XMLReader analyseurSax = XMLReaderFactory.createXMLReader();
InputSource sourceEntree = 
                new InputSource(new FileInputStream("logitheque.xml"));
SAXSource entree = new SAXSource(analyseurSax, sourceEntree);

Un objet Result doit être créé préalablement afin de recevoir le résultat envoyé par la méthode transform(). L'objet Result peut être un résultat DOM (DOMResult) ou SAX (SAXResult) ou encore un flux (StreamResult).

File fichier = new File("resultat.xml");
FileOutputStream flux = new FileOutputStream(fichier);
Result sortie = new StreamResult(flux);

Enfin, les objets Source et Result doivent être passés à la méthode transform() de l'objet Transformer. Après le processus de transformation, le résultat est transmis à l'objet Result, lequel pourrait être directement exploité ultérieurement par l'application sous la forme d'une arborescence DOM ou d'un objet SAX. Dans le cas d'un flux, le résultat sera être écrit dans un fichier local (File) ou distant (URL).

public static void ecrireXML(Document document) {
  try{
    TransformerFactory tfabrique = TransformerFactory.newInstance();
    Transformer transformeur = tfabrique.newTransformer();

    Properties proprietes = new Properties();
    proprietes.put("method", "xml");
    proprietes.put("encoding", "ISO-8859-1"); 
    proprietes.put("indent", "yes");
    transformeur.setOutputProperties(proprietes);

    Source entree = new DOMSource(document);
    File oFic = new File(
                   document.getDocumentElement().getNodeValue() + ".xml");
    FileOutputStream fos = new FileOutputStream(oFic);

    if(fos != null) {
      Result sortie = new StreamResult(fos);
      transformeur.transform(entree, sortie);
    }

    fos.flush();
    fos.close();
  }
  catch (FileNotFoundException e) {
    e.printStackTrace();
  }
  catch (FactoryConfigurationError e) {
    //erreur de configuration de fabrique
    e.printStackTrace();
  }
  catch (TransformerException e) {
    //erreur lors de la transformation
    e.printStackTrace();
  }
  catch (IOException e) {
    e.printStackTrace();
  }
}

La spécification DOM Level 3 Load and Save Specification fournit de nouveaux outils de sauvegarde et de chargement de documents XML. Elle intègre des objets d'entrée (LSInput), de sortie (LSOutput) et de sérialisation (LSSerializer).

Les objets implémentant l'interface LSInput acceptent diverses entrées :

L'adresse URI est résolue par l'analyseur seulement s'il n'existe aucune autre source d'entrée, c'est-à-dire, qu'il ne doit pas y avoir de flux d'octets ou de caractères et de chaîne de caractères.

L'encodage de caractères des sources d'entrée doit être fourni, si nécessaire, au moyen de la méthode setEncoding().

Les objets implémentant l'interface LSOutput supportent plusieurs types de sortie.

Le paquetage org.apache.xerces.dom propose deux classes implémentant les interfaces LSInput et LSOutput. Il s'agît des classes DOMInputImpl et DOMOutputImpl qui permettront de charger et de sauvegarder une source XML sans utiliser le paquetage java.xml.transform dont le but originel n'est pas de sauvegarder des documents XML, mais de les transformer.

File fichier = new File("source.xml");
FileInputStream fluxEntree = new FileInputStream(fichier);
DOMInputImpl entree = new DOMInputImpl();
entree.setEncoding("ISO-8859-1");
entree.setSystemId("source.xml");
entree.setByteStream(fluxEntree);

File fichier = new File("resultat.xml");
FileOutputStream fluxSortie = new FileOutputStream(fichier);
DOMOutputImpl sortie = new DOMOutputImpl();
sortie.setEncoding("ISO-8859-1");
sortie.setSystemId("resultat.xml");
sortie.setByteStream(fluxSortie);

Il est possible d'obtenir une implémentation des interfaces LSInput, LSOutput et LSSerializer, en obtenant d'abord un objet DOMImplementationRegistry, à partir duquel il faut invoquer la méthode getDOMImplementation(), en lui passant les caractéristiques à supporter pour prendre en compte l'API de sauvegarde et de chargement. Ensuite, il ne reste plus qu'à employer les méthodes énoncées dans les interfaces.

DOMImplementationRegistry enregistreur = 
                DOMImplementationRegistry.newInstance();
DOMImplementationLS implLS = (DOMImplementationLS)
                enregistreur.getDOMImplementation("LS 3.0");
LSSerializer serialiseur = implLS.createLSSerializer();

DOMImplementationLS implDOM = (DOMImplementationLS)
                enregistreur.getDOMImplementation("Core 3.0");
LSParser analyseur = implDOM.createLSParser(
                               DOMImplementationLS.MODE_ASYNCHRONOUS, 
                               "http://www.w3.org/TR/REC-xml");
Document doc = analyseur.parseURI(
                       "http://laltruiste.com/ressource.xml");

La caractéristique LS 3.0 ou LS-Async 3.0 permettent d'obtenir une implémentation de l'API DOM Load and Save, tandis que Core 3.0 ou XML 3.0 donnera une implémentation complète de l'API DOM de niveau 3, comprenant évidemment l'implémentation du paquetage org.w3c.dom.ls. De cette manière, tous les dispositifs de chargement et de sauvegarde seront disponibles directement.

public boolean sauvegarder(Document document, String repertoire) {
    try {
        DOMImplementationLS implLS = null;
        if(document.getImplementation().hasFeature("LS", "3.0")) {
            implLS = (DOMImplementationLS)
                                      document.getImplementation();
        }
        else { 
            DOMImplementationRegistry enregistreur = 
                                          DOMImplementationRegistry.newInstance();
            implLS = (DOMImplementationLS)
                                enregistreur.getDOMImplementation("LS 3.0");
        }
        if(implLS == null)
            System.out.println(
                "Votre implémentation ne supporte "
              + "pas l'API DOM Load and Save !");

        File fichier = new File(
                document.getDocumentURI().replaceFirst("http:/", repertoire));
        File dossier = fichier.getParentFile();
        if(!dossier.mkdirs())
            System.out.println("Le dossier n'a pu être créé : " 
                                   + dossier.toString());
        FileOutputStream fluxSortie = new FileOutputStream(fichier);
        LSSerializer serialiseur = implLS.createLSSerializer();
        LSOutput sortie = implLS.createLSOutput();
        sortie.setEncoding("ISO-8859-1");
        sortie.setSystemId(fichier.toString());
        sortie.setByteStream(fluxSortie);
        serialiseur.write(document, sortie);
        fluxSortie.flush();
        fluxSortie.close();
        return true;
    }
    catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    catch (ClassCastException e) {
        e.printStackTrace();
    }
    catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    catch (InstantiationException e) {
        e.printStackTrace();
    }
    catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

La classe CoreDocumentImpl de l'implémentation Xerces recèle d'autres dispositifs de chargement et de sauvegarde des document XML. Les méthodes load(), loadXML() et saveXML(), actuellement expérimentales, permettent de charger un document XML à partir d'une ressource pointée par une adresse URI ou d'une chaîne de caractères, et de sauvegarder le noeud passé en argument dans une chaîne de caractères.

CoreDocumentImpl doc = new CoreDocumentImpl();
doc.getFeature("entities", "false");
doc.getFeature("normalize-characters", "false");
doc.getFeature("check-character-normalization", "false");
if(doc.load("logitheque.xml"))
  System.out.println("Le fichier a été chargé !");
else if(doc.loadXML(
           "<?xml version=\"1.0\"?><racine>texte</racine>"))
  System.out.println("La chaîne de caractères a été chargée !");
else {
  System.out.println("Un document XML a été créé !");
  Element racine = doc.createElement("racine");
  doc.appendChild(racine);
  Text texte = doc.createTextNode("Une valeur textuelle...");
  racine.appendChild(texte);
}
String chaine = doc.saveXML(doc.getDocumentElement());
System.out.println(chaine);

La méthode saveXML() fournit le même résultat que la méthode writeToString() de l'interface LSSerializer, laquelle dispose de deux autres méthodes de sérialisation writeToURI() et write(). L'interface LSSerializer, définie dans le paquetage org.w3c.dom.ls, fournit une API spécialisée dans la sérialisation des objets DOM en données XML envoyées dans une chaîne de caractères ou dans un flux de sortie.

DOMImplementationRegistry enregistreur = 
                DOMImplementationRegistry.newInstance();
DOMImplementationLS impl = (DOMImplementationLS)
                enregistreur.getDOMImplementation("LS 3.0");
LSSerializer serialiseur = impl.createLSSerializer();
boolean reussi = serialiseur.write(noeud, oLSOutput);
String resultat = serialiseur.writeToString(noeud);
reussi = serialiseur.writeToURI(noeud, adresseURI);

La normalisation d'un document XML peut s'opérer au moyen de la méthode normalizeDocument() des objets Document. Cette opération peut être utile pour stocker un document normalisé dans une représentation qui sera identique lors d'opérations successives de sauvegarde et de rechargement. Elle est également utile lorsque des opérations spécifiques, dépendant directement de la structure de l'arborescence spécifique à un document, doivent être pratiquées.

La méthode normalizeDocument() exprime le document sous une forme "normale". En fait, elle met à jour les références d'entité en fonction du dictionnaire d'entités de la DTD et normalise des noeuds Text, c'est-à-dire place tous les noeuds Text dans toute la profondeur de la sous arborescence en dessous du noeud courant, dans une forme "normale" incluant les attributs, où seulement le balisage (éléments, commentaires, instructions de traitement, sections CDATA et références d'entité) sépare les noeuds Text, c'est-à-dire qu'il ne doit pas y avoir de noeuds de type Text adjacents ou vides.

document.normalizeDocument();

Si aucune normalisation n'est pratiqué, le résultat dépendra des caractéristiques fixées sur l'objet DOMConfiguration du document XML courant. Les différentes dispositions mises en place par ces caractéristiques, régissant les opérations exécutées réellement sur le document XML. Concrètement, cette méthode a pu également rendre l'espace de noms du document bien-formé selon l'algorithme décrit en son sein, vérifier la normalisation des caractères, enlever les noeuds CDATASection, etc..

35.2 / Simple API XML

L'API SAX permet d'explorer une ressource XML selon une approche événementielle.

Des gestionnaires spécialisés sont chargés de capturer les événements lancés par l'analyseur SAX.

SAX définit quatre gestionnaires d'événements :

Interface JavaGestionnaire SAXDescription
ContentHandlerDocumentHandlers'occupe des événements concernant les noeuds d'un document XML.
DTDHandlerDTDHandlerprend en compte les événements liés à la définition de type de document.
EntityResolverEntityResolverest sollicitée lorsque l'analyseur SAX atteint des entités externes.
ErrorHandlerErrorHandlerest utilisé pour le traitement des erreurs.

Ces quatres gestionnaires d'événements sont disponibles dans le paquetage org.xml.sax sous la forme d'interfaces.

Ces interfaces fournissent toutes un comportement spécifique que chacune de leurs implémentations doit suivre.

Par exemple, l'interface ContentHandler définit plus d'une dizaine de méthodes qui doivent être invoquées suite à des événements précis.

La méthode startDocument() ou endDocument() est appelée automatiquement par l'analyseur SAX lorsque respectivement, il débute ou il termine, l'analyse d'un document XML.

Dans ce cas, aucune information n'est envoyée sur l'origine de l'événement. Par contre, lorsqu'un élément XML est atteint, la méthode startElement() est appelée et reçoit des informations exploitables sur ce noeud, en l'occurrence, son adresse URI d'espace de noms, son nom local, son nom qualifié et la liste de ses attributs.

public void startElement(
                     String URIEspaceNoms, 
                     String nomLocal, 
                     String nomQalifie, 
                     Attributes attributs){
  System.out.println("Adresse URI : " + URIEspaceNoms);
  System.out.println("Nom local : " + nomLocal);
  System.out.println("Nom qualifié : " + nomQalifie);
  System.out.println("Attributs : " + attributs.getLength());
  for(int i = 0; i < attributs.getLength(); i++){
    System.out.print("\t" + attributs.getQName(i));
    System.out.println(" = " + attributs.getValue(i));
  }
}

Par conséquent, l'API SAX associe chaque type d'événements à une méthode précise, laquelle comporte des paramètres qui expriment l'état spécifique de l'événement d'origine.

Une application SAX doit donc implémenter chacune des méthodes des gestionnaires SAX, pour lesquelles il est nécessaire de gérer des types d'événements déterminés. Les méthodes inutiles devront tout de même être déclarées, mais possèderont un corps vide. Dans le cas contraire, la classe devra être déclarée abstraite.

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;

public class GestionnaireContenu implements ContentHandler {
  public GestionnaireDocument() {
  }
  public void characters(char[] ch, int start, int length) {
    System.out.println("CONTENU TEXTUEL :\n" + new String(ch));
  }
  public void endDocument() {
    System.out.println("FIN DOCUMENT");
  }
  public void endElement(String uri, String localName, String qName) {
    System.out.println("FIN ELEMENT (" + qName + ")");
  }
  public void endPrefixMapping(String prefix) {
    System.out.println("FIN PREFIXE ESPACE DE NOMS (" + prefix + ")");
  }
  public void ignorableWhitespace(char[] ch, int start, int length) {
    System.out.println("ESPACE BLANC : ");
    System.out.println("\tChaine : '" + new String(ch) + "'");
  }
  public void processingInstruction(String target, String data) {
    System.out.println("INSTRUCTION DE TRAITEMENT : ");
    System.out.println("\tCible : " + target);
    System.out.println("\tContenu : " + data);
  }
  public void setDocumentLocator(Locator locator) {
    System.out.println("LOCALISTAION : ");
    System.out.println("\tNom de classe : " + locator.getClass().getName());
    System.out.println("\tN° de colonne : " + locator.getColumnNumber());
    System.out.println("\tN° de ligne : " + locator.getLineNumber());
    System.out.println("\tID Public : " + locator.getPublicId());
    System.out.println("\tID Système : " + locator.getSystemId());
  }
  public void skippedEntity(String name) {
    System.out.println("ENTITE SAUTEE : ");
    System.out.println("\tNom : " + name);
  }
  public void startDocument() {
    System.out.println("DEBUT DOCUMENT");
  }
  public void startElement(String uri, String localName, String qName,
      Attributes attributes) {
    System.out.println("DEBUT ELEMENT (" + qName + ")");
    System.out.println("\tAdresse URI : " + uri);
    System.out.println("\tNom local : " + localName);
    System.out.println("\tNom qualifié : " + qName);
    System.out.println("\tAttributs : " + attributes.getLength());
    for (int i = 0; i < attributes.getLength(); i++) {
      System.out.print("\t\t" + attributes.getQName(i));
      System.out.println(" = " + attributes.getValue(i));
    }
  }
  public void startPrefixMapping(String prefix, String uri) {
    System.out.println("DEBUT PREFIXE ESPACE DE NOMS : ");
    System.out.println("\tPréfixe : " + prefix);
    System.out.println("\tURI : " + uri);
  }
}

35.2.1 / Les analyseurs SAX

Les analyseurs SAX reposent sur l'interface XMLReader, laquelle a remplacé l'interface Parser dépréciée. De la même façon que pour les gestionnaires d'événements, l'interface XMLReader définit plusieurs méthodes auxquelles leurs implémentations doivent se conformer. Ces méthodes sont destinées à affecter ou à obtenir des gestionnaires d'événements, des caractéristiques et des propriétés concernant l'analyseur SAX courant. Deux autres méthodes particuliètrement importantes permettent d'analyser un document XML à partir de différentes sources comme une adresse URL ou une source d'entrée.

Bien évidemment, des analyseurs XML sont proposés par défaut au sein de la plateforme Java. Le paquetage org.xml.sax.helpers renferme les implémentations des interfaces du paquetage org.xml.sax. La classe XMLReaderFactory permet de créer un objet XMLReader qui sera capable d'analyser un document XML.

XMLReader analyseur = XMLReaderFactory.createXMLReader();

XMLReader analyseur = XMLReaderFactory.createXMLReader(
                               "org.apache.xerces.parsers.SAXParser");

XMLReader analyseur = XMLReaderFactory.createXMLReader(
                               "org.apache.crimson.parser.XMLReaderImpl");

La première méthode crée un analyseur s'appuyant sur la classe org.xml.sax.parser de la plateforme Java, tandis que les suivantes demandent la référence d'une classe spécialisée comme celle du module Xerces, Crimson ou autre.

Un autre moyen est proposé pour récupérer un analyseur XML. Le paquetage javax.xml.parsers présente deux classes très intéressantes : SAXParser et SAXParserFactory. Cette dernière constitue une fabrique d'objets SAXParser.

SAXParserFactory fabrique = SAXParserFactory.newInstance();
SAXParser analyseur = fabrique.newSAXParser();

La procédure de création d'analyseurs SAX passe par l'obtention d'une instance de la classe SAXParserFactory par l'intermédaire de la méthode de classe newInstance(). Puis, il suffit d'invoquer la méthode d'instance new SAXParser sur la fabrique pour récupérer un analyseur SAX.

Un objet SAXParserFactory prépare les caractéristiques et certaines propriétés des instances de la classe SAXParser. La validation par DTD ou par schéma XML est activée si la valeur true est passée à la méthode setValidating(). Un objet Schema du paquetage javax.xml.validation peut être affecté à l'objet par l'intermédaire de la méthode setSchema(). Le traitement des espaces de noms ou des inclusions XML est permis si les méthodes setNamespaceAware() et setXIncludeAware() reçoivent la valeur true.

fabrique.setValidating(true);
fabrique.setNamespaceAware(true);
fabrique.setXIncludeAware(true);

Enfin, des caractéristiques spéciales peuvent être activées ou désactivées selon les exigences techniques de l'application. Par exemple, les entités générales externes doivent elles être l'objet d'un événement spécifique si l'analyseur les rencontre ? Les listes d'attributs implémentent t'elles l'interface org.xml.sax.Attributes ou org.xml.sax.ext.Attributes2 ?

fabrique.setFeature(
                    "http://xml.org/sax/features/external-general-entities", true);
fabrique.setFeature(
                    "http://xml.org/sax/features/use-attributes2", false);

Un objet SAXParser encapsule un objet XMLReader. Le fonctionnement de cet analyseur est donc similaire à celui délivré par la fabrique XMLReaderFactory.

En ce qui concerne une instance de la classe XMLReader, l'affectation de caractéristiques et des propriétés s'effectuent directement à partir de l'analyseur et non de sa fabrique XMLReaderFactory. La validation d'un document XML par sa DTD, s'effectue via l'activation de la caractéristique http://xml.org/sax/features/validation. La validation par un schéma XML se réalise par l'intrmédaire des objets du paquetage javax.xml.validation.

import java.awt.Component;
import java.io.File;
import java.util.Iterator;
import java.util.TreeSet;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.helpers.DefaultHandler;

/**
 * 

La classe BarreMenus représente la barre * de menus de l'application.

* @see javax.swing.JMenuBar */ public class BarreMenus extends JMenuBar { /** * Le champ adapts représente une collection * d'adaptateurs pour les menus et les outils de l'application. */ private AdaptateursMenus adapts; /** *

Le constructeur crée une instance de la classe * BarreMenus.

*/ public BarreMenus(AdaptateursMenus adapts) { super(); this.adapts = adapts; this.creerBarreMenus(); } /** *

La méthode creerBareMenu() initialise * et crée la barre de menus.

*/ private void creerBarreMenus() { DefaultHandler gestionnaire = new MenusHandler(this, adapts); SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser saxParser = factory.newSAXParser(); saxParser.parse(new File("menu.xml"), gestionnaire); } catch (Throwable t) { t.printStackTrace(); } } } import java.awt.event.KeyEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** *

La classe MenusHandler gère des documents XML * en vue de la configuration des menus de l'application.

* @see org.xml.sax.helpers.DefaultHandler */ public class MenusHandler extends DefaultHandler { /** * Le champ barre représente la barre de menus * de l'application. */ private BarreMenus barre; /** * Le champ adapts représente une collection de * gestionnaires d'événements affectés aux menus de l'application. */ private AdaptateursMenus adapts; /** * Le champ menu représente un menu de l'application. */ private JMenu menu; /** * Le champ représente un sous-menu de l'application. */ private JMenuItem item; /** * Le champ type indique le type de l'élément * rencontré durant l'analyse (MENU, ITEM, TEXT ou SCUT). */ private int type; /** * La constante MENU indique un élément XML * de type MENU (menu). */ private final int MENU = 0; /** * La constante MENU indique un élément XML * de type ITEM (sous-menu). */ private final int ITEM = 1; /** * La constante MENU indique un élément XML * de type TEXT. */ private final int TEXT = 2; /** * La constante MENU indique un élément XML * de type SCUT (raccourci clavier - Short-CUT). */ private final int SCUT = 3; /** *

Le constructeur crée une instance de la classe MenusHandler.

* @param barre représente la barre de menus de l'application. * @param adapts représente une collection de gestionnaires d'événements */ public MenusHandler(BarreMenus barre, AdaptateursMenus adapts) { super(); this.adapts = adapts; this.barre = barre; } //=========================================================== // Méhodes ContentHandler SAX //=========================================================== /** *

La méthode startDocument reçoit la notification du début du document XML.

* @throws SAXException est lancée lors d'une erreur durant l'analyse du document XML. * @see org.xml.sax.ContentHandler#startDocument() */ public void startDocument() throws SAXException { } /** *

La méthode endDocument reçoit la notification de la fin du document XML.

* @throws SAXException est lancée lors d'une erreur durant l'analyse du document XML. * @see org.xml.sax.ContentHandler#endDocument() */ public void endDocument() throws SAXException { } /** *

La méthode startElement reçoit la notification * indiquant le début d'un élément XML.

* @param namespaceURI représente l'espace de noms de l'élément. * @param lName représente le nom local de l'élément. * @param qName représente le nom qualifié de l'élément. * @param attrs représente le jeu d'attributs de l'élément. * @throws SAXException est lancée lors d'une erreur * durant l'analyse du document XML. * @see org.xml.sax.ContentHandler * #startElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes) */ public void startElement( String namespaceURI, String lName, String qName, Attributes attrs) throws SAXException { String name = lName; if (name == null || name.equals(Constantes.VIDE)) name = qName; if (qName.equalsIgnoreCase("name")){ type = MENU; } else if (qName.equalsIgnoreCase("item")){ type = ITEM; } else if (qName.equalsIgnoreCase("text")){ type = TEXT; } else if (qName.equalsIgnoreCase("shortcut"))){ type = SCUT; } else return; if (attrs != null) { String nom = null; for (int i = 0; i < attrs.getLength(); i++) { String attr = attrs.getLocalName(i); if (attr.equalsIgnoreCase("")) attr = attrs.getQName(i); if(attr.equalsIgnoreCase("id")){ if(this.adapts.containsKey(attrs.getValue(i)) && attrs.getValue(i).length() > 0){ String n = attrs.getValue(i); final AbstractAction elts = this.adapts.getAction(attrs.getValue(i)); if(elts == null) return; this.item.setAction(elts); this.item.setText(nom); this.item.setHorizontalTextPosition(SwingConstants.RIGHT); this.item.setBorder(BorderFactory.createEmptyBorder(3, -10, 3, 0)); } } else if(attr.equalsIgnoreCase("name")){ switch(type){ case MENU: JMenu menu = new JMenu(attrs.getValue(i)); this.barre.add(menu); this.menu = menu; break; case ITEM: if(attrs.getValue(i).equalsIgnoreCase("separator")) this.menu.addSeparator(); else{ nom = attrs.getValue(i); JMenuItem item = new JMenuItem(); this.item = item; this.menu.add(this.item); } break; } } } } } /** *

La méthode endElement() reçoit la notification indiquant * la fin d'un élément XML.

* @param namespaceURI représente l'espace de noms de l'élément. * @param lName représente le nom local de l'élément. * @param qName représente le nom qualifié de l'élément. * @throws SAXException est lancée lors d'une erreur durant * l'analyse du document XML. * @see org.xml.sax.ContentHandler# * endElement(java.lang.String, java.lang.String, java.lang.String) */ public void endElement( String namespaceURI, String lName, String qName, Attributes attrs) throws SAXException { } /** *

La méthode characters reçoit la notification * indiquant la présence d'une chaîne de caractères.

* @param buf représente un tableau des caractères trouvés. * @param offset représente le début de la chaîne de caractères. * @param len représente la taille de la chaîne de caractères. * @throws SAXException est lancée lors d'une erreur * durant l'analyse du document XML. * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char buf[], int offset, int len) throws SAXException { if(len > 0){ switch(type){ case TEXT: this.item.setToolTipText(new String(buf, offset, len)); break; case SCUT: char car = buf[offset]; if(len > 1 && (new String(buf, offset, len)).matches("[0-9]+")) car = (char)Integer.parseInt(new String(buf, offset, len)); if(this.item.getText().indexOf( String.valueOf(KeyEvent.getKeyText(car))) > -1) this.item.setMnemonic((int)car); this.item.getAction().putValue( Action.ACCELERATOR_KEY, (car != 127 ? KeyStroke.getKeyStroke(Constantes.CTRL + KeyEvent.getKeyText(car)) : KeyStroke.getKeyStroke(car, 0))); break; } } } } import java.awt.event.KeyEvent; import java.util.Hashtable; import javax.swing.AbstractAction; import javax.swing.ImageIcon; import javax.swing.KeyStroke; import ui.Application; /** *

La classe AdaptateursMenus recense l'ensemble * des menus de l'application. * Les barres de menus et d'outils trouvent dans cette classe * les adaptateurs, icônes et les raccourcis adéquats.

* @see java.util.Hashtable */ public class AdaptateursMenus extends Hashtable { /** * Le champ fen représente la fenêtre principale de l'application. */ private InterfaceGraphique fen; /** *

Le constructeur crée une instance de la classe AdaptateursMenus.

*/ public AdaptateursMenus(InterfaceGraphique fen) { super(); this.fen = fen; this.creerCollection(); } /** *

La méthode creerCollection() crée une collection * d'objets destinés aux menus et aux outils de l'application courante.

*/ private void creerCollection(){ String nom; this.put(nom = Messages.getString("ui.menu.open"), new GUI_menuOuvrir( this.fen, nom, KeyEvent.VK_O, getIcone(nom), true)); this.put(nom = Messages.getString("ui.menu.new"), new GUI_menuConfigurer( this.fen, nom, KeyEvent.VK_N, getIcone(nom), true)); this.put(nom = Messages.getString("ui.menu.save"), new GUI_menuEnregistrer( this.fen, nom, KeyEvent.VK_S, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.saveas"), new GUI_menuEnregistrer( this.fen, nom, KeyEvent.VK_E, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.saveall"), new GUI_menuEnregistrer( this.fen, nom, KeyEvent.VK_T, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.close"), new GUI_menuFermer( this.fen, nom, KeyEvent.VK_F4, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.print"), new GUI_menuImprimer( this.fen, nom, KeyEvent.VK_P, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.exit"), new GUI_menuQuitter( this.fen, nom, KeyEvent.VK_Q, getIcone(nom), true)); this.put(nom = Messages.getString("ui.menu.undo"), new GUI_Annuler( this.fen, nom, KeyEvent.VK_Z, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.redo"), new GUI_Refaire( this.fen, nom, KeyEvent.VK_Y, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.cut"), //$NON-NLS-1$ new GUI_menuEdition( this.fen, nom, KeyEvent.VK_X, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.copy"), //$NON-NLS-1$ new GUI_menuEdition( this.fen, nom, KeyEvent.VK_C, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.paste"), //$NON-NLS-1$ new GUI_menuEdition( this.fen, nom, KeyEvent.VK_V, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.delete"), //$NON-NLS-1$ new GUI_menuEdition( this.fen, nom, KeyEvent.VK_DELETE, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.selectall"), //$NON-NLS-1$ new GUI_menuEdition( this.fen, nom, KeyEvent.VK_A, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.find"), //$NON-NLS-1$ new GUI_menuRechercher( this.fen, nom, KeyEvent.VK_F, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.replace"), //$NON-NLS-1$ new GUI_menuRechercher( this.fen, nom, KeyEvent.VK_H, getIcone(nom), false)); this.put(nom = Messages.getString("ui.menu.help"), //$NON-NLS-1$ new GUI_menuAPropos( this.fen, nom, KeyEvent.VK_F1, getIcone(nom), true)); this.put(nom = Messages.getString("ui.menu.about"), //$NON-NLS-1$ new GUI_menuAPropos( this.fen, nom, KeyEvent.VK_F12, getIcone(nom), true)); } /** *

La méthode getAction() retourne l'action * associée au nom passé en argument.

* @param nom représente le nom de l'action à rechercher. * @return La méthode retourne un objet AbstractAction. */ public AbstractAction getAction(String nom){ return (AbstractAction)super.get(nom); } } <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE menus SYSTEM "menus.dtd"> <menus> <menu name="Fichier"> <item name="Ouvrir" id="open"> <text>Ouvrir un projet existant</text> <shortcut>O</shortcut> </item> <item name="Nouveau" id="new"> <text>Créer un nouveau projet</text> <shortcut>N</shortcut> </item> <item name="separator"/> <item name="Fermer" id="close"> <text>Fermer le projet</text> <shortcut>115</shortcut> </item> <item name="separator"/> <item name="Enregistrer" id="save"> <text>Enregistrer le document actif</text> <shortcut>S</shortcut> </item> <item name="Enregistrer Sous" id="saveas"> <text>Enregistrer le document actif sous...</text> <shortcut>E</shortcut> </item> <item name="Enregistrer Tout" id="saveall"> <text>Enregistrer tous les documents ouverts</text> <shortcut>T</shortcut> </item> <item name="separator"/> <item name="Imprimer" id="print"> <text>Imprimer le document actif</text> <shortcut>P</shortcut> </item> <item name="separator"/> <item name="Quitter" id="exit"> <text>Quitter le logiciel</text> <shortcut>Q</shortcut> </item> </menu> <menu name="Edition"> <item name="Annuler" id="undo"> <text>Annuler la dernière opération</text> <shortcut>Z</shortcut> </item> <item name="Refaire" id="redo"> <text>Refaire la dernière opération</text> <shortcut>Y</shortcut> </item> <item name="separator"/> <item name="Couper" id="cut"> <text> Copier la sélection dans le presse-papiers et la supprimer </text> <shortcut>X</shortcut> </item> <item name="Copier" id="copy"> <text>Copier la sélection dans le presse-papiers</text> <shortcut>C</shortcut> </item> <item name="Coller" id="paste"> <text>Coller le contenu du presse-papiers</text> <shortcut>V</shortcut> </item> <item name="Supprimer" id="delete"> <text>Supprimer le texte sélectionné</text> <shortcut>127</shortcut> </item> <item name="separator"/> <item name="Rechercher" id="find"> <text>Rechercher une expression</text> <shortcut>F</shortcut> </item> <item name="separator"/> <item name="Sélectionner Tout" id="selectall"> <text>Sélectionner tout le document</text> <shortcut>A</shortcut> </item> </menu> <menu name="Aide"> <item name="Sommaire" id="help"> <text>Sommaire de l'aide</text> <shortcut>112</shortcut> </item> <item name="separator"/> <item name="A Propos" id="about"> <text>Informations à propos du logiciel</text> <shortcut>123</shortcut> </item> </menu> </menus> <?xml version="1.0" encoding="ISO-8859-1"?> <!ENTITY % entite SYSTEM "HTMLlat1x.ent"> %entite; <!ELEMENT item (text?, shortcut?)> <!ATTLIST item name CDATA #REQUIRED id CDATA #IMPLIED > <!ELEMENT menu (item*)> <!ATTLIST menu name CDATA #REQUIRED > <!ELEMENT menus (menu+)> <!ELEMENT shortcut (#PCDATA)> <!ELEMENT text (#PCDATA)>

35.2.2 / Les gestionnaires d'événements SAX

Les gestionnaires d'événements SAX, EntityResolver, DTDHandler, ContentHandler et ErrorHandler, peuvent être associés à un analyseur XMLReader à l'aide des méthodes d'affectation conçue à cet effet.

XMLReader analyseur = XMLReaderFactory.createXMLReader();

ContentHandler gestContenu = new GestionnaireContenu();
analyseur.setContentHandler(gestContenu);

DTDHandler gestDTD = new GestionnaireDTD();
analyseur.setDTDHandler(gestDTD);

EntityResolver gestEntites = new GestionnaireEntites();
analyseur.setEntityResolver(gestEntites);

ErrorHandler gestErreurs = new GestionnaireErreurs();
analyseur.setErrorHandler(gestErreurs);

Comme le suggère l'exemple précédent, les gestionnaires d'événements doivent être réalisés par les soins du programmeur. Tous les gestionnaires et les méthodes nécessaires doivent être implémentés afin que l'application SAX soit en mesure de traiter les événements attendus.

import org.xml.sax.DTDHandler;

public class GestionnaireDTD implements DTDHandler {
  public void notationDecl(
                       String name, 
                       String publicId, 
                       String systemId) {
    System.out.println("DECLARATION DE NOTATION : ");
    System.out.println("Nom : " + name);
    System.out.println("ID Public : " + publicId);
    System.out.println("ID Système : " + systemId);
  }
  public void unparsedEntityDecl(
                       String name, 
                       String publicId, 
                       String systemId, 
                       String notationName) {
    System.out.println("DECLARATION D'ENTITE NON-ANALYSEE : ");
    System.out.println("Nom : " + name);
    System.out.println("ID Public : " + publicId);
    System.out.println("ID Système : " + systemId);
    System.out.println("Nom de notation : " + notationName);
  }
}

import org.xml.sax.ErrorHandler;

public class GestionnaireErreurs implements ErrorHandler {
  public void error(SAXParseException exception) {
    System.out.println("ERREUR D'ANALYSE SAX : ");
    exception.printStackTrace();
  }
  public void fatalError(SAXParseException exception) {
    System.out.println("ERREUR FATALE D'ANALYSE SAX : ");
    exception.printStackTrace();
  }
  public void warning(SAXParseException exception) {
    System.out.println("AVERTISSEMENT D'ANALYSE SAX : ");
    exception.printStackTrace();
  }
}

import org.xml.sax.EntityResolver;

public class GestionnaireEntites implements EntityResolver {
  public InputSource resolveEntity (String publicId, String systemId) {
    System.out.println("RESOLUTION D'ENTITE : ");
    System.out.println("ID Public : " + publicId);
    System.out.println("ID Système : " + systemId);
    if (systemId != null) {
      return new InputSource(systemId);
    }
    else {
      return null;
    }
  }
}

Les analyseurs SAXParser ne prennent les gestionnaires que lors de l'invocation d'une méthode d'analyse. L'assignation des gestionnaires se fait donc par l'intermédaire d'une sous-classe dérivée de la classe DefaultHandler du paquetage org.xml.sax.helpers. La classe DefaultHandler implémente les quatres interfaces EntityResolver, DTDHandler, ContentHandler et ErrorHandler.

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.IOException;

public class GestionnaireDefaut extends DefaultHandler {
    public static void main(String[] args) {
      try {
       SAXParserFactory fabrique = SAXParserFactory.newInstance();
       SAXParser analyseur = fabrique.newSAXParser();
       analyseur.parse("document.xml", new GestionnaireDefaut());
    }
    catch (ParserConfigurationException e) {
       e.printStackTrace();
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
       e.printStackTrace();
    }
  }
  public void characters(char[] ch, int start, int length){
    System.out.println("CONTENU TEXTUEL :\n" + new String(ch));
  } 
  public void endDocument(){
    System.out.println("FIN DOCUMENT");
  } 
  public void endElement(String uri, String localName, String qName){
    System.out.println("FIN ELEMENT (" + qName + ")");
  } 
  public void endPrefixMapping(String prefix){
    System.out.println("FIN PREFIXE ESPACE DE NOMS (" + prefix + ")");
  } 
  public void error(SAXParseException e){
    System.out.println("ERREUR D'ANALYSE SAX : ");
    e.printStackTrace();
  } 
  public void fatalError(SAXParseException e){
    System.out.println("ERREUR FATALE D'ANALYSE SAX : ");
    e.printStackTrace();
  } 
  public void ignorableWhitespace(char[] ch, int start, int length){
    System.out.println("ESPACE BLANC : ");
    System.out.println("\tChaine : '" + new String(ch) + "'");
  } 
  public void notationDecl(String name, String publicId, String systemId){
    System.out.println("DECLARATION DE NOTATION : ");
    System.out.println("\tNom : " + name);
    System.out.println("\tID Public : " + publicId);
    System.out.println("\tID Système : " + systemId);
  } 
  public void processingInstruction(String target, String data){
    System.out.println("INSTRUCTION DE TRAITEMENT : ");
    System.out.println("\tCible : " + target);
    System.out.println("\tContenu : " + data);
  } 
  public InputSource resolveEntity(String publicId, String systemId){
    System.out.println("RESOLUTION D'ENTITE : ");
    System.out.println("\tID Public : " + publicId);
    System.out.println("\tID Système : " + systemId);
    if (systemId != null) {
      return new InputSource(systemId);
    }
    else {
      return null;
    }
  }
  public void setDocumentLocator(Locator locator){
    System.out.println("LOCALISTAION : ");
    System.out.println("\tNom de classe : " + locator.getClass().getName());
    System.out.println("\tN° de colonne : " + locator.getColumnNumber());
    System.out.println("\tN° de ligne : " + locator.getLineNumber());
    System.out.println("\tID Public : " + locator.getPublicId());
    System.out.println("\tID Système : " + locator.getSystemId());
  } 
  public void skippedEntity(String name){
    System.out.println("ENTITE SAUTEE : ");
    System.out.println("\tNom : " + name);
  } 
  public void startDocument(){
    System.out.println("DEBUT DOCUMENT");
  } 
  public void startElement(
                           String uri, 
                           String localName, 
                           String qName, 
                           Attributes attributes){
    System.out.println("DEBUT ELEMENT (" + qName + ")");
    System.out.println("\tAdresse URI : " + uri);
    System.out.println("\tNom local : " + localName);
    System.out.println("\tNom qualifié : " + qName);
    System.out.println("\tAttributs : " + attributes.getLength());
    for(int i = 0; i < attributes.getLength(); i++){
      System.out.print("\t\t" + attributes.getQName(i));
      System.out.println(" = " + attributes.getValue(i));
    }
  } 
  public void startPrefixMapping(String prefix, String uri){
    System.out.println("DEBUT PREFIXE ESPACE DE NOMS : ");
    System.out.println("\tPréfixe : " + prefix);
    System.out.println("\tURI : " + uri);
  } 
  public void unparsedEntityDecl(
                                 String name, 
                                 String publicId, 
                                 String systemId, 
                                 String notationName){
    System.out.println("DECLARATION D'ENTITE NON-ANALYSEE : ");
    System.out.println("\tNom : " + name);
    System.out.println("\tID Public : " + publicId);
    System.out.println("\tID Système : " + systemId);
    System.out.println("\tNom de notation : " + notationName);
  } 
  public void warning(SAXParseException e){
    System.out.println("AVERTISSEMENT D'ANALYSE SAX : ");
    e.printStackTrace();
  } 
}

35.3 / L'API XPath

Le langage XPath, défini par le W3C dans la spécification XML Path Language Version 1.0, fournit les moyens de sélectionner des noeuds précis de l'arborescence DOM d'un document XML.

Le modèle de données XPath est composés de huit noeuds XML.

Les expressions XPath ressemblent aux chemins utilisés pour accéder à des dossiers ou fichiers dans le système de fichiers Unix.

<?xml version="1.0"?>
<racine>
  <element id="elt1">
    <enfant>valeur 1</enfant>
  </element>
  <element id="elt2">
    <enfant>valeur 2</enfant>
  </element>
  <element id="elt3">
    <enfant>valeur 3</enfant>
  </element>
</racine>

/* Expressions XPath
/racine -> Sélection de l'élément racine
/racine/element -> Sélection des éléments element
/racine/element/enfant -> Sélection des éléments enfant
/racine/element/@id -> Sélection des attributs id
*/

Des caractères spéciaux permettent de construire des expressions plus compactes et relatives par rapport à un noued contextuel.

/* Expressions XPath
Sélection de l'élément racine
/racine
Sélection des éléments element
//element
Sélection des éléments enfant
/racine//enfant
Sélection des éléments enfant du noeud fils 
du noeud contextuel (ex.: racine)
*/enfant
Sélection du noeud parent element du noeud 
contextuel (ex.: <enfant>valeur 3</enfant>)
../element
. -> Sélection du noeud courant (ex.: valeur 2)
*/

Des prédicats peuvent être inclus dans les expressions XPath afin de cibler plus précisément des noeuds XML.

/* Expressions XPath
Sélection du premier élément element
/racine/element[1]
Sélection de l'élément portant l'attribut id="elt2"
/racine/element[@id='elt2']
Sélection de l'élément comprenant un élément <enfant>valeur 3</enfant>
/racine/element[enfant='valeur 3']
*/

Des axes nodaux et des fonctions complètes la panoplie du langage XPath.

/* Expressions XPath
Sélection du noeud grand-frère du noeud courant
following-sibling::*
Sélection du noeud enfant du noeud courant (ex.: element)
descendant::enfant
Sélection du noeud enfant du troisième noeud 
element du noeud parent du noeud courant
ancestor::*/element[3]/enfant
Sélection du contenu textuel du noeud enfant du noeud 
element portant l'attribut id="elt2"
//element[@id='elt2']/enfant/text()
Sélection du dernier noeud element
//element[last()]
Sélection du noeud element à la position numéro 2
//element[position()=2]
Comptabilise le nombre de noeuds éléments
count[//element]

En outre, XPath compte un ensemble d'opérateurs arithmétiques et booléens permettant de combiner des prédicats.

/* Expressions XPath
Sélection de l'avant-dernier noeud element
//element[position()=last() - 1]
Sélection du noeud element contenant l'attribut id dont la valeur 
se termine par 2 et qui est situé à la seconde position
//element[substring(@id, 2, 3)='2' and position()=2]
*/

35.3.1 / Evaluation des expressions XPath

L'API XPath disponible dans le paquetage javax.xml.xpath, propose un environnement d'évaluation des expressions XPath.

Une instance de la classe XPath permet de compiler et évaluer des expressions XPath. Un objet XPath s'obtient en invoquant la méthode d'instance d'un objet XPathFactory, lequel est instancié par sa méthode de classe newInstance().

XPathFactory fabrique = XPathFactory.newInstance();
XPath environnement = fabrique.newXPath();
XPathExpression expression = environnement.compile("//element");

La méthode newInstance() accepte un argument indiquant le modèle d'objet à utiliser pour l'objet XPath. Par défaut, le modèle d'objet XPath est celui énoncé dans la constante XPathFactory.DEFAULT_OBJECT_MODEL_URI.

XPathFactory fabrique = XPathFactory.newInstance(
                              XPathFactory.DEFAULT_OBJECT_MODEL_URI);
/*
XPathFactory.DEFAULT_OBJECT_MODEL_URI = 
             "http://java.sun.com/jaxp/xpath/dom"
XPathConstants.DOM_OBJECT_MODEL = 
             "http://java.sun.com/jaxp/xpath/dom"
*/

Il est possible de vérifier si le modèle d'objet est supporté par l'implémentation XPath sous-jacente. La méthode isObjectModelSupported() s'occupe de cela.

if(fabrique.isObjectModelSupported(modele)){
  fabrique.newInstance(modele);
}

L'objet XPathExpression représente une expression XPath compilée. A partir de cet objet, une évaluation de l'expression XPath sur une ressource XML est réalisable au moyen des méthodes evaluate().

URL url = new URL("http://laltruiste.com/coursjava/exemples/logitheque.xml");
InputSource source = new InputSource(url.openStream());

XPathExpression expression = environnement.compile(
                            "//logiciel[@id='15202718']/nom/text()");
String resultat = expression.evaluate(source)

expression = environnement.compile("//nom");
NodeList resultat = 
           (NodeList)expression.evaluate(source, XPathConstants.NODESET);

DocumentBuilderFactory fabriqueDOM = DocumentBuilderFactory.newInstance();
DocumentBuilder analyseur = fabriqueDOM.newDocumentBuilder();
Document document = analyseur.parse(new File("logitheque.xml"));

expression = environnement.compile(
                            "//element[last()]/enfant/text()");
String resultat = expression.evaluate(document);

expression = environnement.compile("element[@id='elt3']");
NodeList liste = document.getElementsByTagName("element");
Node noeud = (Node)expression.evaluate(liste, XPathConstants.NODE);

Les objets acceptés comme argument par les deux dernières méthodes evaluate() sont soit des noeuds XML (Document, DocumentFragment, Element ou Attr), soit des liste de noeuds (NamedNodeMap et NodeList). L'expression XPath s'applique seulement à ce contexte, c'est-à-dire, à sa structure. La valeur de l'argument peut être aussi une référence à une variable ou à une fonction. Dans ce cas, les objets XPathVariableResolver et XPathFunctionResolver sont exploités pour résoudre ces expressions. Si la variable ou la fonction n'ont pu être résolus, une exception XPathExpressionException sera lancée. Enfin, un nom qualifié peut être fourni. Ce nom est résolu en s'appuyant sur le contexte d'espace de noms XPath spécifié par la méthode setNamespaceContext().

Le second argument, pour deux des méthodes evaluate(), exprime le type de l'objet retourné. Le langage XPath propose cinq types de retour possibles (Ensemble de noeuds, noeud, chaîne de caractères, nombre et valeur booléenne), lesquels sont mis à disposition sous la forme de constantes, dans la classe XPathConstants.

La classe XPath dispose également de méthodes d'évaluation similaires à celles d'un objet XPathExpression. En fait, ces méthodes evaluate() accomplissent dans un premier temps la compilation d'une expression XPath, puis l'opération d'évaluation. Elles constituent donc une alternative compacte en n'utilisant qu'un appel de méthode, plutôt que deux comme exposé ci-dessus.

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class ExpressionXPath {
  public static void main(String[] args) {
    try {
      DocumentBuilderFactory fabriqueDOM = 
                                    DocumentBuilderFactory.newInstance();
      DocumentBuilder analyseur = fabriqueDOM.newDocumentBuilder();
      Document document = analyseur.parse(new File("logitheque.xml"));
      XPathFactory fabriqueXPath = XPathFactory.newInstance();
      XPath xpath = fabriqueXPath.newXPath();
      String expression = "//logiciel[@code='15202718']";
      Node noeud = (Node) xpath.evaluate(
                                    expression, document, XPathConstants.NODE);
      afficherInfos(noeud);
      expression = "ancestor::*/logiciel[3]/commentaire";
      noeud = (Node) xpath.evaluate(
                                    expression, noeud, XPathConstants.NODE);
      afficherInfos(noeud);
    }
    catch(IOException e) {
      e.printStackTrace();
    }
    catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
    catch (XPathExpressionException e) {
      e.printStackTrace();
    }
  }
  public static void afficherInfos(Node noeud) {
    String nom = noeud.getNodeName();
    String valeur = noeud.getNodeValue();
    short type = noeud.getNodeType();
    if (type == Node.ELEMENT_NODE)
      valeur = noeud.getTextContent();
    System.out.println(nom + " (" + type + ") = '" + valeur + "'");
  }
}

Le second argument de la méthode evaluate() détermine un noeud contextuel à partir duquel s'appliquera l'expression XPath spécifiée.

35.3.2 / Résolution des fonctions et variables

L'API XPath dispose de plusieurs interfaces destinées à résoudre des fonctions et des variables utilisateurs contenues dans une expression XPath.

L'interface XPathVariableResolver contient une seule méthode, en l'occurrence, resolveVariable(). Cette dernière pren un argument QName qui identifie la variable et retourne un objet correspondant au modèle d'objet sous-jacent.

XPathVariableResolver resolveurVariable = 
                              xpath.getXPathVariableResolver();
QName uneVariable = new QName("uneVariable");
Object resultat = 
               resolveurVariable.resolveVariable(uneVariable);

L'interface XPathFunctionResolver contient une méthode resolveFunction(), laquelle compte deux arguments. Le premier est le nom de la fonction et le second le nombre de paramètres que cette fonction attend.

XPathFunctionResolver resolveurFonction = 
                              xpath.getXPathFunctionResolver();
QName uneFonction = new QName("uneFonction");
XPathFunction fonctionXPath = 
             resolveurFonction.resolveFunction(uneFonction, 3);

La méthode resolveFunction() retourne un objet XPathFunction. Ce dernier possède également une méthode, evaluate(). Une liste d'arguments, contenant un nombre d'éléments correspondant au nombre de paramètres indiqué das la fonction resolveFuntion(), doit être passée à la méthode evaluate(), laquelle retourne un résultat sous la forme d'un objet.

ArrayList liste = new ArrayList();
liste.add("argument 1");
liste.add("argument 2");
liste.add("argument 3");
Object resultat = fonctionXPath.evaluate(liste);

La méthode reset() réinitialise l'objet XPath à sa configuration initiale, soit celle au moment de sa création. Toutefois, bien que les objets affectés (XPathFunctionResolver, XPathVariableResolver et NamespaceContext) risquent de na pas être les mêmes, leur fonctionnement sera équivalent.

Les objets XPath possèdent des méthodes renvoyant ou assignant des objets XPathFunctionResolver et XPathVariableResolver. Les fabriques XPathFactory disposent également des mêmes méthodes d'affectation. Les objets affectés seront, lors de la création d'un objet XPath, inclus dans ce dernier.

public class ResolutionFonction 
                     implements XPathFunctionResolver {
  public void resolveFunction(QName functionName, int arity){
    //Implémentation...
  }
}
public class ResolutionVariable 
                     implements XPathVariableResolver {
  public Object resolveVariable(QName variableName){
    //Implémentation...
  }
}
XPathFactory fabrique = XPathFactory.newInstance();
XPathFunctionResolver unResolveurFonction = 
                              new ResolutionFonction()
fabrique.setXPathFunctionResolver(unResolveurFonction);
fabrique.setXPathVariableResolver(unResolveurVariable);

XPath xpath = fabrique.newXPath();
xpath.setXPathFunctionResolver(unResolveurFonction);
XPathVariableResolver unResolveurVariable = 
                              new ResolutionVariable()
xpath.setXPathVariableResolver(unResolveurVariable);
XPathFunctionResolver resolveurFonction = 
                              xpath.getXPathFunctionResolver();
XPathVariableResolver resolveurVariable = 
                              xpath.getXPathVariableResolver();

Les interfaces XPathFunctionResolver, XPathFunction et XPathVariableResolver sont destinées à être implémentées par l'application et ensuite doivent être assignés à l'objet XPathFactory ou XPath.

35.3.3 / Les contextes d'espace de noms

Un contexte d'espace de noms peut être établi sur l'objet XPath par l'intermédiaire de la méthode setNamespaceContext() prenant comme argument un objet NamespaceContext.

Cet objet doit implémenter l'interface NamespaceContext et être initialisé avec l'adresse URI d'espace de noms et le préfixe adéquats.

Dans ce contexte, il est nécessaire d'activer la prose en compte des espaces de noms en utilisant la méthode setNamespaceAware() de la fabrique XPathFactory.

import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;

public class EspaceNomsContextuel implements NamespaceContext {
    private Hashtable prefixeVersURI;
    private Hashtable URIVersPrefixe;

    public EspaceNomsContextuel() {
        this("http://www.laltruiste.com/", "lal");
    }
    public EspaceNomsContextuel(String uri, String prefixe) {
        this.prefixeVersURI = new Hashtable();
        this.URIVersPrefixe = new Hashtable();
        this.prefixeVersURI.put(prefixe, uri);
        this.URIVersPrefixe.put(uri, prefixe);
    }
    public String getNamespaceURI(String prefix) {
        Object uri = this.prefixeVersURI.get(prefix);
        return uri != null ? uri.toString() : XMLConstants.NULL_NS_URI;
    }
    public String getPrefix(String namespaceURI) {
        Object prefixe = this.URIVersPrefixe.get(namespaceURI);
        return prefixe != null ? prefixe.toString() : XMLConstants.NULL_NS_URI;
    }
    public Iterator getPrefixes(String namespaceURI) {
        Object prefixe = this.URIVersPrefixe.get(namespaceURI);
        ArrayList liste = new ArrayList();
        if(prefixe != null)
            liste.add(prefixe);
        return liste.iterator();
    }
}

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class ExpressionXPath {
  public static void main(String[] args) {
    try {
      DocumentBuilderFactory fabriqueDOM = DocumentBuilderFactory.newInstance();
      fabriqueDOM.setNamespaceAware(true);
      fabriqueDOM.setValidating(false);
      DocumentBuilder analyseur = fabriqueDOM.newDocumentBuilder();
      Document document = analyseur.parse(new File("logitheque.xml"));
      XPathFactory fabriqueXPath = XPathFactory.newInstance();
      XPath xpath = fabriqueXPath.newXPath();
      NamespaceContext contexte = new EspaceNomsContextuel();
      xpath.setNamespaceAware(contexte);
      String expression = "//logiciel[@code='15202718']";
      Node noeud = (Node) xpath.evaluate(
                                    expression, document, XPathConstants.NODE);
      afficherInfos(noeud);
      expression = "ancestor::*/logiciel[3]/commentaire";
      noeud = (Node) xpath.evaluate(
                                    expression, noeud, XPathConstants.NODE);
      afficherInfos(noeud);
    }
    catch(IOException e) {
      e.printStackTrace();
    }
    catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
    catch (XPathExpressionException e) {
      e.printStackTrace();
    }
  }
  public static void afficherInfos(Node noeud) {
    String nom = noeud.getNodeName();
    String valeur = noeud.getNodeValue();
    short type = noeud.getNodeType();
    if (type == Node.ELEMENT_NODE)
      valeur = noeud.getTextContent();
    System.out.println(nom + " (" + type + ") = '" + valeur + "'");
  }
}

35.4 / La transformation XSL

Le langage XSLT (XML Stylesheet Language for Transformation) détermine des règles de style à appliquer à un document XML, en vue d'améliorer sa lisibilité auprès d'utilisateurs.

Le document XML subit une transformation selon les modèles imposés dans une feuille de style XSLT. Le résultat de cette transformation peut prendre différentes formes et donc devenir :

La mise en forme d'un document XML en fonction d'une feuille de style est définie par un ensemble d'instructions XSLT formant des modèles qui imposent une nouvelle représentation des données. Les feuilles de style XSLT peuvent être paramétrées, c'est-à-dire, qu'elles dépendent de données extérieures, à l'instar d'une fonction, pour effectuer correctement la transformation.

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<!DOCTYPE poesie [
 <!ELEMENT poesie (titre,texte,auteur)>
 <!ELEMENT titre (#PCDATA)>
 <!ELEMENT texte (#PCDATA)>
 <!ELEMENT auteur (#PCDATA)>
]>
<poesie>
 <titre>Locution des pierrots</titre>
 <texte>
 Je ne suis qu'un viveur lunaire
 Qui fait des ronds dans le bassin
 Et cela, sans autre dessein
 Que de devenir légendaire.

 Retroussant d'un air de défin
 Mes manches de Mandarin pâle,
 J'arrondis ma bouche et - j'exhale
 Des conseils doux de Crucifix

 Ah! oui, devenir légendaire,
 Au seuil des siècles charlatans !
 Mais où sont les Lunes d'antan ?
 Et que Dieu n'est-il à refaire ?
 </texte>
 <auteur>Jules Laforgue</auteur>
</poesie>

<!-- Feuille de style : style.xsl -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns="http://www.w3.org/TR/xhtml1/strict">
  <xsl:output method="html" encoding="ISO-8859-1"/>
  <xsl:template match="/">
   <html>
     <xsl:apply-templates/>
   </html>
  </xsl:template>
  <xsl:template match="poesie">
    <head>
      <title>
        <xsl:value-of select="titre"/>
      </title>
      <meta http-equiv="Content-Type" content="text/xhtml; charset=ISO-8859-1"/>
    </head>
    <body>
      <h2 align="center">
        <xsl:value-of select="titre"/>
      </h2>
      <div align="center">
        <pre>
          <xsl:value-of select="texte"/>
        </pre>
      </div>
      <h4 align="center">
        <xsl:value-of select="auteur"/>
      </h4>
    </body>
  </xsl:template>
</xsl:stylesheet>

<!-- Document HTML résultant -->
<html xmlns="http://www.w3.org/TR/xhtml1/strict">
  <head>
    <title>Locution des pierrots</title>
    <meta http-equiv="Content-Type" content="text/xhtml; charset=ISO-8859-1"/>
  </head>
  <body>
    <h2 align="center">Locution des pierrots</h2>
    <div align="center">
      <pre>
        Je ne suis qu'un viveur lunaire
        Qui fait des ronds dans le bassin
        Et cela, sans autre dessein
        Que de devenir légendaire.
    
        Retroussant d'un air de défin
        Mes manches de Mandarin pâle,
        J'arrondis ma bouche et - j'exhale
        Des conseils doux de Crucifix
    
        Ah! oui, devenir légendaire,
        Au seuil des siècles charlatans !
        Mais où sont les Lunes d'antan ?
        Et que Dieu n'est-il à refaire ?
      </pre>
    </div>
    <h4 align="center">Jules Laforgue</h4>
  </body>
</html>

35.4.1 / Le transformateur XSLT

Le paquetage javax.xml.transform définit plusieurs classes, interfaces et exceptions, destinées à traiter des instructions XSLT et à opérer un processus de transformation d'un document XML vers un résultat XML, HTML, texte ou autres.

L'API Java de transformation fournit la classe Transformer dont les instances ont la fonction principale de transformer une source XML selon des règles de style.

Les instances de la classe Transformer s'obtiennent par le biais de la classe TransformerFactory.

TransformerFactory fabrique = TransformerFactory.newInstance();
Transformer transformeur = fabrique.newTransformer();

Il est possible de passer par un objet intermédiaire Templates, lequel est récupéré à partir de la fabrique TransformerFactory. Un objet implémentant l'interface Templates prépare une représentation spécifique des instructions de transformation XSLT pour leur exécution ultérieure.

XMLReader analyseurSax = XMLReaderFactory.createXMLReader();
InputSource sourceEntree = 
                new InputSource(new FileInputStream("logitheque.xsl"));
SAXSource sourceXSL = new SAXSource(analyseurSax, sourceEntree);

TransformerFactory fabrique = TransformerFactory.newInstance();

Templates modeles = fabrique.newTemplates(sourceXSL);
Transformer transformeur = modeles.newTransformer();
//équivaut à
Transformer transformeur = fabrique.newTransformer(sourceXSL);

La transformation doit s'appuyer sur une source XSLT, soit une feuille de style. C'est pourquoi, les méthodes newTransformer() et newTemplates() attendent un objet Source. Tout objet implémentant l'interface Source peut être utilisé, incluant les sources DOM (javax.xml.transform.dom.DOMSource) et SAX (javax.xml.transform.sax.SAXSource) et les flux (javax.xml.transform.stream.StreamSource).

Si un document XML contient une instruction de traitement xml-stylesheet, la méthode getAssociatedStylesheet() retourne la source XSLT désignée dans ce document, afin de l'exploiter lors de la transformation.

DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
fabrique.setNamespaceAware(true);
fabrique.setValidation(true);
DocumentBuilder analyseur = fabrique.newDocumentBuilder();
Document doc = analyseur.parse(new File("source.xml"));
DOMSource sourceXML = new DOMSource(doc);

TransformerFactory fabrique = TransformerFactory.newInstance();
Source sourceXSL = fabrique.getAssociatedStylesheet(
                                   sourceXML, 
                                   null,
                                   "StyleXSL",
                                   "ISO-8859-1");
Transformer transformeur = fabrique.newTransformer(sourceXSL);

<!-- Fichier : source.xml -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet href="style.xsl" 
                    type="text/xsl" 
                    title="StyleXSL" 
                    charset="ISO-8859-1"
                    version = "1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                    xmlns="http://www.w3.org/TR/xhtml1/strict"?>
<librairie>
  <!-- ... -->
</librairie>

Il peut être nécessaire d'indiquer à la fabrique DocumentBuilderFactory de prendre en compte les espaces de noms. Dans le cas cntraire, la transformation pourrait ne pas s'exécuter correctement.

La transformation se réalise en appelant la méthode transform() d'un objet Transformer. Il faut passer à cette méthode deux arguments :

L'objet Result peut être un résultat DOM (DOMResult) ou SAX (SAXResult) ou encore un flux (StreamResult). Dans le cas, d'un objet DOMResult ou SAXResult, le résultat peut être exploité directement par l'application. En ce qui concerne le flux StreamResult, le résultat est envoyé dans un fichier, vers une ressource adressée par une URI, au travers d'un socket réseau, vers la sortie standard ou ailleurs.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Properties;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public class StyleXSLT {
  public static void main(String[] args) {
    try {
      XMLReader analyseurSax = XMLReaderFactory.createXMLReader();
      InputSource sourceEntreeXSL = 
                             new InputSource(
                                 new FileInputStream("logitheque.xsl"));
      SAXSource sourceXSL = 
                               new SAXSource(analyseurSax, sourceEntreeXSL);

      InputSource sourceEntreeXML = 
                             new InputSource(
                                 new FileInputStream("logitheque.xml"));
      SAXSource sourceXML = 
                new SAXSource(analyseurSax, sourceEntreeXML);

      TransformerFactory fabrique = 
                               TransformerFactory.newInstance();
      Transformer transformateur = 
                               fabrique.newTransformer(sourceXSL);

      transformateur.setOutputProperty(
                               OutputKeys.METHOD, "html");
      transformateur.setOutputProperty(
                               OutputKeys.ENCODING, "ISO-8859-1");
      transformateur.setOutputProperty(
                               OutputKeys.INDENT, "yes");

      transformateur.setParameter("num", "6");

      File oFic = new File("resultat.html");
      FileOutputStream fos = new FileOutputStream(oFic);

      if (fos != null) {
        Result sortie = new StreamResult(fos);
        transformateur.transform(sourceXML, sortie);
      }
      fos.flush();
      fos.close();
    }
    catch (TransformerConfigurationException e) {
      e.printStackTrace();
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
    catch (FileNotFoundException e) {
      e.printStackTrace();
    }
    catch (TransformerException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Feuille de style : logitheque.xsl -->
<xsl:stylesheet 
       version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns="http://www.w3.org/1999/xhtml">
  <xsl:output 
            method="html" 
            encoding="ISO-8859-1"
            media-type="text/html; charset=ISO-8859-1"/>
  <xsl:param name="num">6</xsl:param>
  <xsl:template match="/">
    <xsl:apply-templates 
                    select="/logitheque/categorie[position()=$num]"/>
  </xsl:template>
  <xsl:template match="/logitheque/categorie">
    <html>
      <head>
        <title>
          La logithèque : 
          <xsl:value-of select="/logitheque/categorie[$num]/@nom"/>
        </title>
        <meta name="Robots" content="noindex, nofollow"/>
      </head>
      <body>
        <h1><xsl:value-of select="@nom"/></h1>
        <table border="1" width="100%" class="produit">
          <tr>
            <th colspan="5" class="entete">Logiciel</th>
          </tr>
          <tr>
            <th class="entete" width="35%">Editeur</th>
            <th class="entete" width="10%">Langue</th>
            <th class="entete" width="24%">OS</th>
            <th class="entete" width="25%">Prix</th>
            <th class="entete" style="width: 6%">Panier</th>
          </tr>
          <xsl:apply-templates>
            <xsl:sort select="nom"/>
          </xsl:apply-templates>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="cellule0" match="/logitheque/categorie/logiciel">
    <tr>
      <td colspan="5" class="c1 somniv1" height="24">
        <xsl:choose>
          <xsl:when test="@code != ''">
            <a href="http://aff.soc.fr?var=x12&produit={@code}" target="_blank">
              <xsl:apply-templates select="nom"/>
            </a>
          </xsl:when>
          <xsl:otherwise>
            <a href="{editeur/@lien}" target="_blank">
              <xsl:apply-templates select="nom"/>
            </a>
          </xsl:otherwise>
        </xsl:choose> - <xsl:apply-templates select="./commentaire"/>
      </td>
    </tr>
    <tr>
      <td style="white-space:nowrap">
        <a href="{editeur/@lien}" target="_blank">
          <xsl:apply-templates select="./editeur"/>
        </a>
      </td>
      <td>
        <xsl:apply-templates select="./langue"/>
      </td>
      <td>
        <xsl:apply-templates select="./plateforme"/>
      </td>
      <td>
        <xsl:apply-templates select="./prix"/>
        <xsl:text> </xsl:text>
        <xsl:apply-templates select="prix/@monnaie"/>
      </td>
      <td>
        <xsl:if test="@code != '' ">
          <script 
             src="http://aff.soc.fr?var=x12&produit={@code}&target=_blank"/>
        </xsl:if>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet 
                   type="text/xsl" 
                   href="logitheque.xsl" 
                   title="StyleXSLT"
                   encoding="ISO-8859-1"?>
<!DOCTYPE logitheque SYSTEM "logitheque.dtd">
<logitheque>
  <categorie nom="Edition Web">
    <logiciel code="13404148">
      <nom>Web Expert 2000</nom>
      <commentaire>Editeur HTML professionnel.</commentaire>
      <editeur lien="http://www.visic.com/webexpert/">Visicom</editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">429,00</prix>
    </logiciel>
  </categorie>
  <categorie nom="Dreamweaver">
    <logiciel code="13413363">
      <nom>Dreamweaver 4</nom>
      <commentaire>
        Créez vos pages HTML et gérez votre site Web.
      </commentaire>
      <editeur lien="http://www.macromedia.com/software/">
        Macromedia
      </editeur>
      <langue>US</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">2 508,44</prix>
    </logiciel>
  </categorie>
  <categorie nom="Frontpage">
    <logiciel code="13404422">
      <nom>FrontPage 2000 Media Pack</nom>
      <commentaire>
        Media Pack ne peut être vendu séparément.
      </commentaire>
      <editeur lien="http://www.microsoft.com/">
        Microsoft
      </editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">184,62</prix>
    </logiciel>
  </categorie>
  <categorie nom="Director Shockwave">
    <logiciel code="13406163">
      <nom>Director Shockwave Studio 8.0</nom>
      <commentaire>
        La référence en conception multimedia.
      </commentaire>
      <editeur lien="http://www.macromedia.com/software/">
        Macromedia
      </editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">2 558,52</prix>
    </logiciel>
  </categorie>
  <categorie nom="Feuille de Style">
    <logiciel code="">
      <nom>TopStyle Pro 2.1</nom>
      <commentaire>
        La version 2.5 disponible en Beta test.
      </commentaire>
      <editeur lien="http://www.bradsoft.com/topstyle/">
        Bradbury Software
      </editeur>
      <langue>EN</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="$US">49,95</prix>
    </logiciel>
  </categorie>
  <categorie nom="XML et XSL">
    <logiciel code="">
      <nom>Cooktop  2.200</nom>
      <commentaire>
        Un éditeur XML, XSLT, XPath et DTD puissant et totalement gratuit.
      </commentaire>
      <editeur lien="http://xmleverywhere.com/cooktop/">
         XML Everywhere
       </editeur>
      <langue>EN</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="$US">00.00</prix>
    </logiciel>
    <logiciel code="">
      <nom>XML Spy 3.5</nom>
      <commentaire>La version 4 bientôt disponible.</commentaire>
      <editeur lien="http://www.xmlspy.com/default.html">
        Altova Inc.
      </editeur>
      <langue>EN</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="$US">199,00</prix>
    </logiciel>
  </categorie>
  <categorie nom="Base de données">
    <logiciel code="13414437">
      <nom>Borland Kylix Developpement Desktop</nom>
      <commentaire>
        Développement serveur et base de données pour réaliser 
        rapidement des applications web évolutives.
      </commentaire>
      <editeur lien="">Borland</editeur>
      <langue>FR</langue>
      <plateforme>Win/Linux</plateforme>
      <prix monnaie="FRF">1 502,00</prix>
    </logiciel>
  </categorie>
  <categorie nom="Java">
    <logiciel code="11406923">
      <nom>JBuilder 4.0 Entreprise</nom>
      <commentaire>
        Développement d'applications Java.
      </commentaire>
      <editeur lien="http://www.borland.com/">
        Borland
      </editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">22 105,00</prix>
    </logiciel>
    <logiciel code="11414012">
      <nom>Eclipse 3.0</nom>
      <commentaire>
        Développement d'applications Java.
      </commentaire>
      <editeur lien="http://www.eclipse.org/">
        Fondation Eclipse
      </editeur>
      <langue>US</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">0</prix>
    </logiciel>
  </categorie>
  <categorie nom="Visual Basic">
    <logiciel code="11400283">
      <nom>Visual Basic 6.0 Professionnel</nom>
      <commentaire>
        Le célèbre outil de développement.
      </commentaire>
      <editeur lien="http://www.microsoft.com/">
        Microsoft
      </editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">3 855,17</prix>
    </logiciel>
  </categorie>
  <categorie nom="Delphi">
    <logiciel code="13400140">
      <nom>Delphi 5 Professionnel</nom>
      <commentaire>
        Le développement ultrarapide pour windows.
      </commentaire>
      <editeur lien="http://www.borland.com/">
        Borland
      </editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">5 995,00</prix>
    </logiciel>
  </categorie>
  </categorie>
  <categorie nom="Navigateur">
    <logiciel code="">
      <nom>Netscape 6.1</nom>
      <commentaire>
        La dernière version totalement refondue de Netscape.
      </commentaire>
      <editeur lien="http://home.netscape.com/download/index.html">
        Netscape
      </editeur>
      <langue>FR</langue>
      <plateforme>Win/Mac/Linux</plateforme>
      <prix monnaie="FRF">00,00</prix>
    </logiciel>
  </categorie>
  <categorie nom="Client FTP">
    <logiciel code="13414140">
      <nom>WS_FTP Pro (1 utilisateur)</nom>
      <commentaire>
        La nouvelle version, exclusivement en anglais.
      </commentaire>
      <editeur lien="http://www.ipswitch.com/products/index.html">
        Ipswitch
      </editeur>
      <langue>US</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">417,40</prix>
    </logiciel>
  </categorie>
  <categorie nom="Recherche">
    <logiciel code="">
      <nom>SubmitWolf v4.02.003 MAJ</nom>
      <commentaire>
        SubmitWolf est un outil professionnel de promotion de sites Web.
      </commentaire>
      <editeur lien="http://www.trellian.com//fr/products.htm">
        Trellian Soft.
      </editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="$US">100,00</prix>
    </logiciel>
  </categorie>
  </categorie>
  <categorie nom="Graphisme Web">
    <logiciel code="13413372">
      <nom>Fireworks 4</nom>
      <commentaire>Optimisez vos images pour le web.</commentaire>
      <editeur lien="http://www.macromedia.com/software/">
        Macromedia
      </editeur>
      <langue>US</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">2 508,69</prix>
    </logiciel>
    <logiciel code="13406152">
      <nom>Flash 5.0</nom>
      <commentaire>
        Créez des sites web avec animations vectorielles.
      </commentaire>
      <editeur lien="http://www.macromedia.com/software/">
        Macromedia
      </editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">3 087,11</prix>
    </logiciel>
    <logiciel code="15213947">
      <nom>Paint Shop Pro 7 -Licence 10 à 49 postes</nom>
      <commentaire>
        La nouvelle version du celèbre logiciel graphique en anglais.
      </commentaire>
      <editeur lien="http://www.wska.com/">Wska</editeur>
      <langue>FR</langue>
      <plateforme>Win</plateforme>
      <prix monnaie="FRF">575,00</prix>
    </logiciel>
  </categorie>
</logitheque>

35.4.2 / Les paramètres et propriétés

Les objets Transformer sont responsables du recueil des paramètres nécessaires à la feuille de style de transformation et également de préciser des propriétés de sortie.

Fournir des paramètres à l'objet Transformer revient à préciser des valeurs aux éléments XSLT xsl:param correspondants dans une feuille de style de transformation. Ces valeurs seront exploitées durant le processus de transformation.

Les paramètres
transformeur.setParameter("parametre", "Une valeur");

<!-- Feuille de style -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns="http://www.w3.org/TR/xhtml1/strict">
  <xsl:output method="html" encoding="ISO-8859-1"/>
  <xsl:param name="parametre">Valeur par défaut</xsl:param>
  <!-- ... -->
</xsl:stylesheet>

Le nom de chaque paramètre soumis à la méthode setParameter() doit être parfaitement identique à celui auquel il se réfère dans la feuille de style XSLT.

Les propriétés de sortie correspondent aux attributs de l'élément XSLT xsl:output. Ces propriétés indiquent au processeur XSL comment mettre en forme le résultat de la transformation.

//Les propriétés de sortie
Properties proprietes = new Properties();
proprietes.put("method", "xml");
proprietes.put("version", "1.0");
proprietes.put("encoding", "ISO-8859-1"); 
proprietes.put("standalone", "no");
proprietes.put("indent", "yes");
proprietes.put("omit-xml-declaration", "no");
proprietes.put("doctype-public", "-//W3C//DTD XHTML 1.1//EN");
proprietes.put("doctype-system", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd");
proprietes.put("media-type", "text/xhtml");

transformeur.setOutputProperties(proprietes);

Les noms de propriété de sortie sont tous référencés dans la classe OutputKeys sous la forme de constantes. L'utilisation de ces constantes permettra d'éviter des fautes d'orthographes malencontreuses dans l'affectation de valeurs aux propriétés.

transformateur.setOutputProperty(OutputKeys.METHOD, "html");
transformateur.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
transformateur.setOutputProperty(OutputKeys.INDENT, "yes");

Les propriétés peuvent être affectées individuellement à l'objet Transformer, en utilisant la méthode setOutputProperty().

transformeur.setParameter(OutputKeys.INDENT, "yes");

Les paramètres et les propriétés de sortie sont disponibles pour une consultation en invoquant respectivement les méthodes getParameter() et getOutputProperty().

Object valParametre = transformeur.getParameter("parametre");

String valPropriete = transformeur.getOutputProperty(OutputKeys.INDENT);

Les propriétés peuvent être toutes obtenues dans une collection Properties au moyen de la méthode getOutputProperties().

Properties proprietes = transformeur.getOutputProperties();
Set ensemble = proprietes.entrySet();
Iterator ite = ensemble.iterator();
while(ite.hasNext()){
  Map.Entry entree = (Map.Entry)ite.next();
  System.out.println(entree.getKey() + " = " + entree.getValue());
}

La méthode clearParameters() se charge de supprimer tous les paramètres assignés à l'objet Transformer.

transformeur.clearParameters();

La réinitialisation de l'objet Transformer à son état initial, s'accomplit en appelant la méthode reset(), laquelle supprime notament tous les paramètres et les propriétés définis auparavant. Toutefois, les objets URIResolver et ErrorListener peuvent subir un remplacement par d'autres objets au fonctionnement équivalent.

transformeur.reset();
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class Programme implements Runnable {
    private String encodage;
    private String cheminXML;
    private String cheminXSL;
    private String cheminHTML;
    private String numero;

    public Programme(
                     String cheminXML, 
                     String cheminXSL, 
                     String cheminHTML, 
                     String numero, 
                     String encodage) {
        this.cheminXML = cheminXML;
        this.cheminXSL = cheminXSL;
        this.cheminHTML = cheminHTML;
        this.numero = numero;
        this.encodage = encodage;
    }
    public Programme(
                     String cheminXML, 
                     String cheminXSL, 
                     String cheminHTML, 
                     String numero) {
        this(cheminXML, cheminXSL, cheminHTML, 
                        numero, System.getProperty("file.encoding"));
    }
    public void transformer(DocumentXML xml, DocumentXML xsl) {
        try {
            DOMSource sourceXSL = new DOMSource(xsl.getDocument());
            TransformerFactory fabrique = TransformerFactory.newInstance();
            Transformer transformateur = fabrique.newTransformer(sourceXSL);

            transformateur.setOutputProperty(OutputKeys.METHOD, "html");
            transformateur
                    .setOutputProperty(OutputKeys.ENCODING, this.encodage);
            transformateur.setOutputProperty(OutputKeys.INDENT, "yes");

            transformateur.setParameter("num", numero);

            File fichier = new File(cheminHTML);
            FileOutputStream fos = new FileOutputStream(fichier);

            if (fos != null) {
                Result sortie = new StreamResult(fos);
                DOMSource sourceXML = new DOMSource(xml.getDocument());
                transformateur.transform(sourceXML, sortie);
                System.out.println("Transformation réussie : " + fichier.toString());
            }
            fos.flush();
            fos.close();
        }
        catch (TransformerConfigurationException e) {
            e.printStackTrace();
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (TransformerException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void traitement(
                         DocumentXML xml, 
                         DocumentXML xsl) {
        synchronized(DocumentXML.class) {
            xml.chargerDocument(this.cheminXML);
            xsl.chargerDocument(this.cheminXSL);
            transformer(xml, xsl);
        }
    }
    public void run() {
        DocumentXML xml = new DocumentXML();
        DocumentXML xsl = new DocumentXML();
        traitement(xml, xsl);
    }
    public static void main(String[] args) {
        for (int i = 1; i <= 20; i++) {
            Programme prog = new Programme(
                                           "logitheque.xml", 
                                           "logitheque.xsl", 
                                           "resultat" + i + ".html", 
                                           String.valueOf(i));
            Thread t = new Thread(prog);
            t.start();
        }
    }
}

//Fichier : DocumentXML.java
public class DocumentXML {
    private Document document;

    public DocumentXML() {
        super();
    }
    public synchronized void chargerDocument(String source) {
        try {
        DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();
        fabrique.setNamespaceAware(true);
        DocumentBuilder constructeur = fabrique.newDocumentBuilder();
        document = constructeur.parse(new File(source));
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
    public synchronized Document getDocument() {
        return document;
    }
    public synchronized Element getRacine() {
        return this.document.getDocumentElement();
    }
    public synchronized DocumentType getDTD() {
        return this.document.getDoctype();
    }
    public synchronized String getEncodage() {
        return this.document.getXmlEncoding();
    }
    public synchronized String getVersionXML() {
        return this.document.getXmlVersion();
    }
    public synchronized void fournirURI(String uri) {
        this.document.setDocumentURI(uri);
    }
}

35.4.3 / Le gestionnaire d'URI

Un document XML étant susceptible de contenir des ressources externes pointées par des adresses URI, un objet URIResolver peut permettre de résoudre de telles adresses URI, c'est-à-dire, de retourner à l'application l'objet Source pointée par l'adresse URI présente dans les instructions XSLT document(), xsl:import et xsl:include.

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;

public class GestionnaireURI implements URIResolver {
  private URL baseDefaut;
  public GestionnaireURI() {
    this("http://www.laltruiste.com/");
  }
  public GestionnaireURI(String URIBase) {
    try {
      this.baseDefaut = new URL(URIBase);
    }
    catch (MalformedURLException e) {
      System.out.println("L'adresse URL (" 
                        + URIBase
                        + ") soumise n'est pas correcte !");
    }
  }
  public Source resolve(String href, String base) 
                                         throws TransformerException {
    try {
      URL adresseURL = null;
      if (!href.matches("^[a-z]+://.+$")) {
        if (base == null || base.matches("^[\\s]*$")) {
          adresseURL = new URL(this.baseDefaut, href);
        }
        else {
          URL baseURL = new URL(base);
          adresseURL = new URL(baseURL, href);
        }
      }
      else {
        adresseURL = new URL(href);
      }
      return new StreamSource(adresseURL.openStream());
    }
    catch (Exception e) {
      return null;
    }
  }
}

transformeur.setURIResolver(new GestionnaireURI());

<!-- Feuille de style -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns="http://www.w3.org/TR/xhtml1/strict">
  <xsl:template match="/">
  <html>
    <xsl:include href="meta_description.inc"/>
      <xsl:apply-templates/>
  </html>
  </xsl:template>
  <!-- ... -->
</xsl:stylesheet>

L'objet URIResolver peut être obtenu par une invocation de la méthode getURIResolver().

URIResolver gestURI = transformeur.getURIResolver();

Les objets TransformerFactory peuvent aussi définir un gestionnaire d'URI URIResolver qui servira pour résoudre les adresses URI spécifiées dans les instructions de transformation.

transformeur.setURIResolver(new GestionnaireURI());

35.4.4 / Le gestionnaire d'erreurs

Un gestionnaire d'erreurs implémentant l'interface ErrorListener peut être affecté au transformateur XSLT. Dans ce cas, tous les événements liés à des erreurs durant le processus de transformation seront pris en charge par ce gestionnaire.

import javax.xml.transform.ErrorListener;
import javax.xml.transform.TransformerException;

public class GestionnaireErreurs implements ErrorListener {
  public void error(TransformerException exception) {
    System.err.println(
             "ERREUR LORS DU PROCESSUS DE TRANSFORMATION : ");
    exception.printStackTrace();
  }
  public void fatalError(TransformerException exception) {
    System.err.println(
             "ERREUR FATALE LORS DU PROCESSUS DE TRANSFORMATION : ");
    exception.printStackTrace();
  }
  public void warning(TransformerException exception) {
    System.err.println(
             "AVERTISSEMENT LORS DU PROCESSUS DE TRANSFORMATION : ");
    exception.printStackTrace();
  }
}

TransformerFactory fabrique = TransformerFactory.newInstance();
Transformer transformateur = fabrique.newTransformer(sourceXSL);

transformateur.setErrorListener(new GestionnaireErreurs());

L'interface ErrorListener se trouve dans le paquetage javax.xml.transform, à ne pas confondre avec l'interface ErrorHandler du paquetage org.xml.sax.

Le gestionnaire d'erreurs peut être récupéré en sollicitant la méthode getErrorListener().

ErrorHandler gestErreurs = transformeur.getErrorListener();

Les objets TransformerFactory peuvent aussi définir un gestionnaire d'erreurs ErrorListener qui servira pour rapporter les erreurs de traitement des instructions de transformation. Ce gestionnaire ne prendra pas en compte les erreurs émises lors du processus de transformation avec l'objet Transformer.

fabrique.setErrorListener(new GestionnaireErreurs());
public class StyleXSLT {

    public static void main(String[] args) {
        try {
            XMLReader analyseurSax = XMLReaderFactory.createXMLReader();
            File sourceEntreeXSL = new File("logitheque.xsl");
            StreamSource sourceXSL = new StreamSource(sourceEntreeXSL);
            File sourceEntreeXML = new File("logitheque.xml");
            StreamSource sourceXML = new StreamSource(sourceEntreeXML);

            TransformerFactory fabrique = TransformerFactory.newInstance();
            Transformer transformateur = fabrique.newTransformer(sourceXSL);

            transformateur.setErrorListener(new GestionnaireErreurs());

            Properties proprietes = new Properties();
            proprietes.put("method", "html");
            proprietes.put("encoding", "ISO-8859-1");
            proprietes.put("indent", "yes");
            transformateur.setOutputProperties(proprietes);

            transformateur.setParameter("num", "10");

            File oFic = new File("resultat.html");
            FileOutputStream fos = new FileOutputStream(oFic);

            if (fos != null) {
                Result sortie = new StreamResult(fos);
                transformateur.transform(sourceXML, sortie);
            }

            fos.flush();
            fos.close();
        }
        catch (TransformerConfigurationException e) {
            e.printStackTrace();
        }
        catch (SAXException e) {
            e.printStackTrace();
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (TransformerException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

35.5 / La validation de documents XML

La validation permet de vérifier si la structure et le contenu d'un document XML respecte les contraintes imposées par une définition de type de document (DTD) ou un schéma XML.

<!-- Fichier : employes.xml -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE employes SYSTEM "employes.dtd">
<employes>
  <employe id="RJ1002" service="DG001">
    <nom>Robierre</nom>
    <prenom>Jean</prenom>
  </employe>
  <employe id="LA1012" service="DG001">
    <nom>Lardut</nom>
    <prenom>Anne</prenom>
  </employe>
  <employe id="GA1013" service="ST001">
    <nom>Guilde</nom>
    <prenom>Angelique</prenom>
  </employe>
  <employe id="HP1022" service="SC001">
    <nom>Henry</nom>
    <prenom>Paul</prenom>
  </employe>
  <employe id="MM1045" service="RH001">
    <nom>Mortier</nom>
    <prenom>Marc</prenom>
  </employe>
  <employe id="LS1102" service="SQ001">
    <nom>Lebreton</nom>
    <prenom>Sophie</prenom>
  </employe>
  <employe id="JM1095" service="RD001">
    <nom>Jolie</nom>
    <prenom>Martine</prenom>
  </employe>
  <employe id="MT1036" service="SC101">
    <nom>Marcelin</nom>
    <prenom>Tania</prenom>
  </employe>
  <employe id="LL1029" service="SC101">
    <nom>Leger</nom>
    <prenom>Laurence</prenom>
  </employe>
  <employe id="DM1052" service="SC001">
    <nom>Duroi</nom>
    <prenom>Maxime</prenom>
  </employe>
</employes>

<!-- Fichier : employes.xsd -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="element_enfant" type="xsd:string"/>
  <xsd:element name="element_racine">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="element_enfant" type="xsd:string" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

<!-- Fichier : employes.rng -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<element name="employes" 
         xmlns="http://relaxng.org/ns/structure/1.0"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <oneOrMore>
    <element name="employe">
        <attribute name="id">
          <data type="ID"/>
        </attribute>
        <attribute name="service">
          <data type="NMTOKEN"/>
        </attribute>
      <element name="nom">
        <text/>
      </element>
      <element name="prenom">
        <text/>
      </element>
    </element>
  </oneOrMore>
</element>

<!-- Fichier : employes.dtd -->
<?xml version="1.0" encoding="ISO-8859-1"?>
<!ELEMENT employe (nom, prenom)>
<!ATTLIST employe
        id ID #REQUIRED
        service NMTOKEN #REQUIRED
>
<!ELEMENT employes (employe+)>
<!ELEMENT nom (#PCDATA)>
<!ELEMENT prenom (#PCDATA)>

35.5.1 / Le paramétrage de validation

Suite à la création de l'objet DocumentBuilderFactory, il est possible de déclarer avec quel moyen (DTD ou schéma) sera validé le document XML.

Une solution consiste à passer par la méthode setAttribute() de la fabrique. Celle-ci accepte dans ce cas deux arguments.

Le premier est une chaîne de caractères exprimant une propriété indiquant le type de la valeur passée à la méthode setAttribute(). Il existe deux possibilités :

fabrique.setAttribute(
                 "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                 "http://www.w3.org/2001/XMLSchema");
fabrique.setAttribute(
                 "http://java.sun.com/xml/jaxp/properties/schemaSource"
                 new File("schema.xsd"));

Le second argument de la méthode setAttribute() indique :

Pour des raisons de commodité, il peut être utile de placer les identificateurs de propriétés au sein de constantes.

public static final String JAXP_SCHEMA_LANGUAGE =
        "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
public static final String JAXP_SCHEMA_SOURCE =
        "http://java.sun.com/xml/jaxp/properties/schemaSource";

Le langage de schéma est disponible sous la forme d'une constante dans la classe javax.xml.XMLConstants.

fabrique.setAttribute(
                 JAXP_SCHEMA_LANGUAGE,
                 XMLConstants.W3C_XML_SCHEMA_NS_URI);

Si l'implémentation sous-jacente gère d'autres langages de schéma, à l'image de Relax NG. Il est possible de spécifier l'adresse URI de ce langage.

fabrique.setAttribute(
                 JAXP_SCHEMA_LANGUAGE,
                 XMLConstants.RELAXNG_NS_URI);

Si le document XML nécessite plusieurs schémas XML pour sa validation, il faut créer un tableau et y placer les références vers les schémas.

String schemaSociete = "societe.xsd";
String schemaService = "service.xsd";
String schemaEmploye = "employe.xsd";

String[] schemas = {
                   schemaSociete,
                   schemaService, 
                   schemaEmploye,
                   };

DocumentBuilderFactory fabrique =
                           DocumentBuilderFactory.newInstance()
fabrique.setAttribute(JAXP_SCHEMA_SOURCE, schemas);

La valeur à soumettre à la méthode setAttribute(JAXP_SCHEMA_SOURCE, valeur) peut être de différents types :

La soumission d'une source validante impose l'analyseur de valider le document XML avec elle. Si le document XML possède une référence vers un schéma XML, alors ce dernier sera purement et simplement ignoré. Par contre, si aucune source validante n'est fournie au moyen de la méthode setAttribute(), le schéma présent dans le document XML sera retenu pour la validation.

fabrique.setAttribute(
                   JAXP_SCHEMA_LANGUAGE, 
                   XMLConstants.W3C_XML_SCHEMA_NS_URI);
//fabrique.setAttribute(JAXP_SCHEMA_SOURCE, new File(sourceXSD));

La prise en compte des espaces de noms et le processus de validation doivent être activés,

fabrique.setNamespaceAware(true);
fabrique.setValidating(true);

L'invocation de la méthode setValidating(true) entraîne la validation du document XML par rapport à l'éventuelle définition de type de document (DTD) déclarée par <!DOCTYPE...>, si aucune information supplémentaire de validation n'est précisée dans l'application.

import java.io.IOException;
import javax.xml.parsers.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class ValidationXML {
     public static final String JAXP_SCHEMA_LANGUAGE =
          "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
     public static final String JAXP_SCHEMA_SOURCE =
          "http://java.sun.com/xml/jaxp/properties/schemaSource";
  public static final void main(String[] args) {
    ValidationXML oValid = new ValidationXML(
                                       "fichier.xml", 
                                       "fichier.xsd");
  }
  public ValidationXML(String fichierXML, Object sourceXSD) {
    try {
      DocumentBuilderFactory fabrique = 
                                  DocumentBuilderFactory.newInstance();

      fabrique.setNamespaceAware(true);
      fabrique.setValidating(true);
      fabrique.setAttribute(
                         JAXP_SCHEMA_LANGUAGE, 
                         XMLConstants.W3C_XML_SCHEMA_NS_URI);
      fabrique.setAttribute(JAXP_SCHEMA_SOURCE, new File(sourceXSD));

      DocumentBuilder constructeur = fabrique.newDocumentBuilder();
      constructeur.setErrorHandler(new GestionnaireErreurs());

      Document document = constructeur.parse(fichierXML);
      Element racine  = document.getDocumentElement();
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }
}

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;

public class GestionnaireErreurs implements ErrorHandler {
  public void error(SAXParseException e) {
    System.err.println("ERREUR SAX : " + e.getMessage());
  }
  public void fatalError(SAXParseException e) {
    System.err.println("ERREUR FATALE SAX : " + e.getMessage());
  }
  public void warning(SAXParseException e) {
    System.err.println("AVERTISSEMENT SAX : " + e.getMessage());
  }
}

L'implémentation Xerces offre un autre moyen d'indiquer à l'analyseur DOM ou SAX de valider un document XML.

La caractéristique validation doit être fixée à true afin de contraindre l'analyseur XML à accomplir l'opération de validation.

analyseur.setFeature(
                  "http://xml.org/sax/features/validation",
                  true); 

Sans autres informations supplémentaires, l'analyseur XML recherchera l'éventuelle DTD et validera le document XML. Si le document ne contient pas de DTD, la validation échouera.

La validation par un schéma XML doit être spécifiée en paramétrant la caractéristique validation/schema à true.

parser.setFeature(
                  "http://apache.org/xml/features/validation/schema", 
                  true);

Une autre caractéristique active la vérification des contraintes gramaticales.

parser.setFeature(
                  "http://apache.org/xml/features/validation/schema-full-checking",
                  true);

Enfin, il ne reste plus qu'à fournir la source validante sous la forme d'une adresse URL. Si le document XML comporte des espaces de noms nécessaires à sa validation, il faut utiliser la la propriété schema/external-schemaLocation, dans le cas contraire schema/external-noNamespaceSchemaLocation conviendra tout à fait. Ces propriétés sont fixées à l'aide de la méthode setProperty().

parser.setProperty(
      "http://apache.org/xml/properties/schema/external-schemaLocation",
      schema);
parser.setProperty(
      "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
      SchemaUrl);

35.5.2 / La validation par DTD

Les analyseurs XML XMLReader et SAXParser acceptent l'activation d'un processus de validation lors du chargment d'un ressource XML par rapport à une DTD, si la caractéristique http://xml.org/sax/features/validation est fixée à true par l'intermédairee de la méthode setFeature().

//Utilisation de XMLReader
import java.io.IOException;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public class Validation2 {
  public static void main(String[] args) {
    try {
      XMLReader analyseur = XMLReaderFactory.createXMLReader();
      analyseur.setFeature("http://xml.org/sax/features/validation", true);
      analyseur.setErrorHandler(new GestionnaireErreurs());
      analyseur.parse("ex.xml");
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}

//Utilisation de SAXParser
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public class Validation2 {
  public static void main(String[] args) {
    try {
      SAXParserFactory fabrique = SAXParserFactory.newInstance();
      fabrique.setFeature("http://xml.org/sax/features/validation", true);
      SAXParser analyseur = fabrique.newSAXParser();
      DefaultHandler gestionnaire = new DefaultHandler() {
        public void error(SAXParseException exception) {
          System.out.println("ERREUR");
          exception.printStackTrace();
        }
        public void fatalError(SAXParseException exception) {
          System.out.println("ERREUR FATALE");
          exception.printStackTrace();
        }
        public void warning(SAXParseException exception) {
          System.out.println("AVERTISSEMENT");
          exception.printStackTrace();
        }
      };
      analyseur.parse("employes.xml", gestionnaire);
    }
    catch (SAXException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
  }
}

Si le document XML cible ne contient aucune DTD ou déclaration de DTD, deux exceptions sont lancées, indiquant que le document n'est pas valide puisqu'aucunes règles structurelles n'a pu être trouvées et que le nom de l'élément racine ne correspond pas à la valeur null symbolisant la carence de déclaration de type de document.

org.xml.sax.SAXParseException: 
    Document is invalid: no grammar found.
org.xml.sax.SAXParseException: 
    Document root element "element_racine", 
    must match DOCTYPE root "null".

Le gestionnaire d'erreurs assigné aux analyseurs capture les erreurs produites lors de la validation. Les exception précitées n'étant pas fatales pour le déroulement du programme, peuvent êre simplement ignorées en ne fournissant pas d'implémentation à la méthode error().

35.5.3 / La validation par schéma XML

La validation par un schéma XML est assurée par le paquetage javax.xml.validation. La classe Schema représente un schéma XML écrit dans le langage W3C XML Schema, Relax NG ou autre.

Une instance de la classe Schema s'obtient par la fabrique SchemaFactory, laquelle compile une ressource XML exprimant le schéma W3C ou Relax NG par le biais d'une constante passée lors de l'instanciation de la fabrique.

SchemaFactory fabriqueW3C = SchemaFactory.newInstance(
                               XMLConstants.W3C_XML_SCHEMA_NS_URI);
SchemaFactory fabriqueRNG = SchemaFactory.newInstance(
                               XMLConstants.RELAXNG_NS_URI);

Source sourceW3C = new StreamSource(new File("c:\\employes.xsd"));
Source sourceRNG = new StreamSource(new File("c:\\employes.rng"));

Schema schemaW3C = fabrique.newSchema(sourceW3C);
Schema schemaRNG = fabrique.newSchema(sourceRNG);

Un objet Schema peut être consitué à partir de diverses sources d'entrée, comme un flux (StreamSource), une source DOM (DOMSource) ou SAX (SAXSource), un fichier et une adresse URL. Il est même possible de passer un tableau de sources (Source[]) dans le cas où plusieurs schémas XML seraient nécessaires pour valider un document.

Document docXSD = parser.parse(new File("C:\\schema.xsd"));
Source sourceXSD = new DOMSource(docXSD);
Schema schemaW3C = fabrique.newSchema(sourceXSD);

Désormais, la classe Validator doit être instanciée par la méthode newValidator() de l'objet Schema. Puis à partir du validateur ainsi récupéré, l'invocation de sa méthode validate() provoque la validation du document XML par rapport à un schéma XML.

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.w3c.dom.Document;
import java.io.File;
import java.io.IOException;

public class Validation {
  public static void main(String[] args) {
    try {
      DocumentBuilderFactory fabriqueAnalyseur = 
                             DocumentBuilderFactory.newInstance();
      DocumentBuilder analyseur = fabriqueAnalyseur.newDocumentBuilder();
      Document document = analyseur.parse(new File("C:\\employes.xml"));

      SchemaFactory fabrique = SchemaFactory.newInstance(
                             XMLConstants.W3C_XML_SCHEMA_NS_URI);
      fabrique.setErrorHandler(new GestionnaireErreurs());

      InputSource sourceentree = new InputSource("C:\\employes.xsd");
      SAXSource sourceXSD = new SAXSource(sourceEntree);

      Schema schema = fabrique.newSchema(sourceXSD);
      Validator validateur = schema.newValidator();

      validateur.validate(new DOMSource(document));
    } 
    catch (SAXException e) {
      e.printStackTrace();
    }
    catch (ParserConfigurationException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}

/Gestionaire d'erreurs
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

class GestionnaireErreurs implements ErrorHandler {
    public void fatalError( SAXParseException e ) throws SAXException {
        System.out.println("ERREUR FATALE");
        e.printStackTrace();
    }
    public void error( SAXParseException e ) throws SAXException {
        System.out.println("ERREUR");
        e.printStackTrace();
    }
    public void warning( SAXParseException e ) throws SAXException {
        System.out.println("AVERTISSEMENT");
        e.printStackTrace();
    }
}

Le gestionnaire d'erreurs permet de rapporter les erreurs lancées durant le processus de validation.

Si le schéma n'est pas rédigé dans le langage de schéma correspondant à l'URI d'espace de noms, plusieurs erreurs peuvent être lancées simultanément.

org.xml.sax.SAXParseException: 
    s4s-elt-schema-ns: The namespace of element 'element' must be 
    from the schema namespace, 'http://www.w3.org/2001/XMLSchema'.

org.xml.sax.SAXParseException: 
    s4s-att-not-allowed: Attribute 'datatypeLibrary' cannot 
    appear in element 'element'.ERREUR

Si le schéma est écrit dans un langage qui n'est pas supporté par l'analyseur JAXP, une exception IllegalArgumentException se produit sur l'instruction de création d'un objet SchemaFactory.

Exception in thread "main" 
    java.lang.IllegalArgumentException: 
        http://purl.oclc.org/dsdl/schematron

La version JDK 1.5 est susceptible de supporter plusieurs langages de schéma, tels que W3C XML Schema, Relax NG ou Schematron. Toutefois, la rise en compte de ces langages de schéma dépend des implémentations d'analyseur. La méthode d'instance isSchemaLanguageSupported() de la classe SchemaFactory peut aider à déterminer si l'implémentation sous-jacente supporte des langages de schéma supplémentatires.

SchemaFactory fabrique = 
                       SchemaFactory.newInstance(
                                     XMLConstants.W3C_XML_SCHEMA_NS_URI);
if(fabrique.isSchemaLanguageSupported(
                   XMLConstants.RELAXNG_NS_URI))
  System.out.println("Relax NG est supporté...");
if(fabrique.isSchemaLanguageSupported(
                   "http://purl.oclc.org/dsdl/schematron"))
  System.out.println("Schematron est supporté...");

Si le choix de valider un document par un schéma XML, il ne faut pas fixer la valeur de la caractéristique de validation (http://xml.org/sax/features/validation) à false.

analyseur.setFeature("http://xml.org/sax/features/validation", false);

Dans le cas contraire, il y aurait une redondance de validation par DTD puis par schéma, et dans le pire des cas, des erreurs pourraient se produire si le document XML ne comporte pas de définition de type de document.

35.6 / La localisation d'entité

Les objets implémentant l'interface Locator sont capables de fournir des informations sur la localisation du dernier événement produit au sein d'un document XML.

Les informations sont des numéros de ligne et de colonne, ainsi que les identificateurs SYSTEM et PUBLIC du document courant.

L'encodage de caractères et le numéro de version XML de l'entité situé à l'emplacement courant, peuvent être obtenus si l'objet implémente l'interface Locator2. Cela se vérifie en invoquant la méthode getFeature() d'une fabrique SAXParserFactory, qui retourne true si l'es objets de localisation implémente l'interface Locator2.

SAXParserFactory fabrique = SAXParserFactory.newInstance();
if(fabrique.getFeature("use-locator2"))
  System.out.println("L'implémentation supporte Locator2");

SAX possède une classe abstraite dénommée DefaultHandler dans laquelle existe une méthode dont la fonction est de recevoir un objet Locator. Il s'agît de la méthode setDocumentLocator() qui reçoit lors de l'analyse SAX, un argument de type Locator qui peut être exploité si cette méthode a été implémentée.

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.helpers.DefaultHandler;
import java.io.File;

public class GestionEmplacement extends DefaultHandler {
  public static void main(String[] args) throws Exception {
    SAXParserFactory fabrique = SAXParserFactory.newInstance();
    SAXParser analyseur = fabrique.newSAXParser();
    analyseur.parse(new File("logitheque.xml"), new GestionEmplacement());
  }

  private Locator emplacement;

  public void setDocumentLocator(Locator locator) {
    this.emplacement = locator;
  }
  public void startElement(
                           String uri, 
                           String localName, 
                           String qName, 
                           Attributes attributes) {
    if (this.emplacement == null)
      System.err.println("L'objet Locator n'est pas disponible ! ");
    else {
      System.out.println("ELEMENT : " + qName);
      System.out.println("Numéro de ligne : " 
                              + this.emplacement.getLineNumber());
      System.out.println("Numéro de colonne : " 
                              + this.emplacement.getColumnNumber());
      System.out.println("ID Système : " 
                              + this.emplacement.getSystemId());
      System.out.println("ID Public : " 
                              + this.emplacement.getPublicId());
    }
  }
}

Il est possible d'implémenter l'interface ContentHandler qui déclare la méthode setDocumentLocator(). La classe abstraite DefaultHandler implémente cette interface.

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.ContentHandler;

public class GestionEmplacement implements ContentHandler {
  private Locator emplacement;

  public void setDocumentLocator(Locator locator) {
    this.emplacement = locator;
  }
  public void startElement(
                           String uri, 
                           String localName, 
                           String qName, 
                           Attributes attributes) {
    if (this.emplacement == null)
      System.err.println("L'objet Locator n'est pas disponible ! ");
    else {
      System.out.println("ELEMENT : " + qName);
      System.out.println("Numéro de ligne : " 
                              + this.emplacement.getLineNumber());
      System.out.println("Numéro de colonne : " 
                              + this.emplacement.getColumnNumber());
    }
  }
}

DOM comporte une interface DOMLocator située dans le paquetage javax.xml.transform.dom. Cette interface contient une seule méthode (getOriginatingNode()) retournant le noeud à l'origine de l'événement courant.

L'interface DOMLocator étend une autre interface SourceLocator, laquelle dispose de méthodes délivrant les mêmes informations que le localisateur SAX, soit des numéros de ligne et de colonne, ainsi que les identificateurs SYSTEM et PUBLIC du document courant.

L'objet implémentant l'interface SourceLocator s'obtient à partir des exceptions TransformerException et TransformerConfigurationException du paquetage javax.xml.transform.

public class TransformerException extends Exception {
  SourceLocator locator;
  //...
  public String getMessageAndLocation() {
    StringBuffer sbuffer = new StringBuffer();
    String       message = super.getMessage();
  
    if (null != message) {
        sbuffer.append(message);
    }
    if (null != locator) {
        String systemID = locator.getSystemId();
        int    line     = locator.getLineNumber();
        int    column   = locator.getColumnNumber();
        if (null != systemID) {
            sbuffer.append("; SystemID: ");
            sbuffer.append(systemID);
        }
        if (0 != line) {
            sbuffer.append("; Line#: ");
            sbuffer.append(line);
        }
        if (0 != column) {
            sbuffer.append("; Column#: ");
            sbuffer.append(column);
        }
    }
  
    return sbuffer.toString();
  }
  //...
}

Xerces 2 propose une implémentation de l'interface DOMLocator, en l'occurrence org.apache.xerces.dom.DOMLocatorImpl. La classe org.apache.xerces.dom.DOMNormalizer déclare un champ protégé fLocator utilisé par plusieurs méthodes de cette classe pour vérifier si les valeurs d'attributs (isAttrValueWF()), les sections CDATA (isCDataWF()), les commentaires (isCommentWF()) et des caractères XML (isXMLCharWF()), sont bien formés. Les objets DOMLocatorImpl sont souvent utilisés pour rapporter une erreur.

36 / Les applications Swing

Enormément de programmes Java destinés à des utilisateurs comportent des éléments graphiques de telle sorte que l'application soit plus conviviale et ergonomique au travers de son interface Homme-Machine (IHM).

La plateforme Java dispose de différents outils permettant de construire des interfaces utilisateurs graphiques (GUI : Graphical User Interface) sophistiquées.

Plusieurs paquetages graphiques sont fournis par Java, tels AWT (Abstract Window Toolkit) et SWING, mais

Les applications Java nécessitent l'importation du paquetage Swing par l'intermédiaire de l'instruction suivante :

import javax.swing.*;

Les applications Swing ont également souvent besoin des paquetages AWT, notamment pour la création d'interface utilisateur et la gestion événementielles des programmes.

import java.awt.*;
import java.awt.event.*;

La plateforme Java permet de spécifier un aspect particulier à appliquer à une application Swing. La méthode setLookAndFeel() de la classe UIManager permet d'affecter une apparence, en fournissant un nom de classe look and feel.

// Nom de la classe Look and Feel
UIManager.setLookAndFeel(nomClasseLAF);

// Instance de la classe Look and Feel
UIManager.setLookAndFeel(instanceClasseLAF);

Il existe plusieurs look and feel pour les applications Swing.

// Look and feel par défaut
UIManager.setLookAndFeel(
    UIManager.getSystemLookAndFeel());

// Look and Feel de la plateforme sous-jacente
UIManager.setLookAndFeel(
    UIManager.getCrossPlatformLookAndFeelClassName());

// Look and feel Windows
UIManager.setLookAndFeel(
    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

// Look and feel CDE/Motif
UIManager.setLookAndFeel(
    "com.sun.java.swing.plaf.motif.MotifLookAndFeel");

// Look and feel GTK+
UIManager.setLookAndFeel(
    "com.sun.java.swing.plaf.gtk.GTKLookAndFeel");

// Look and feel métal
UIManager.setLookAndFeel(
    "javax.swing.plaf.metal.MetalLookAndFeel");

// Look and feel Macintosh
UIManager.setLookAndFeel(
    "it.unitn.ing.swing.plaf.macos.MacOSLookAndFeel");

// look and feel Kunststoff
UIManager.setLookAndFeel(
    "com.incors.plaf.kunststoff.KunststoffLookAndFeel");

Il est possible de préciser le look and file de l'application en passant par une instruction -Dswing.defaultlaf en ligne de commande ou en rensignant un fichier swing.properties à localiser dans le répertoire lib de Java.

Ligne de commande
java -Dswing.defaultlaf=NomClasseLAF ApplicationJava

Fichier : swing.properties
# Swing properties

swing.defaultlaf=NomClasseLAF

Le look and feel d'une inteface utilisateur peut être modifiée même si cette dernière est affichée à l'écran. Pour cela, il suffit de fournir le nouveau nom de classe LAF, puis d'utiliser la méthode updateComponentTreeUI() pour mettre à jour le composant de plus haut niveau de l'interface conformément à la nouvelle apparence. Enfin,le réaffichage correct des composants enfants dans leur container s'effectue en invoquant une méthode spécifique telle que pack() de la classe JFrame.

UIManager.setLookAndFeel(NomClasseLAF);
SwingUtilities.updateComponentTreeUI(composantFrame);
composantFrame.pack();

En outre, l'aspect d'une application peut être entièrement personnalisée. En d'autres mots, il est possible de créer sa propre classe Look And Feel et de l'utiliser pour habiller ses propres applications.

Exemple [voir]
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;

public class Tree {
  static JTree tree ;

  public static void main(String[] args) {
    JFrame frame = new JFrame("Tree");
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        Window win = e.getWindow();
        win.setVisible(false);
        win.dispose();
        System.exit(0);
      }
    } );

    frame.getContentPane().setLayout( new BorderLayout());

    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch (Exception e) {
      e.printStackTrace();
    }

    tree = new JTree();
  
    JScrollPane sp = new JScrollPane( tree );
    frame.getContentPane().add( sp, "Center" );

    frame.pack();
    frame.show();
  }
}

36.1 / La fenêtre d'une application

La fenêtre d'une application constitue le support sur lequel il sera possible de construire une interface graphique complexe. Bien que le paquetage AWT comporte une classe Window, il sera préférable en raison des limitations de cette dernière d'utiliser la classe JFrame du paquetage Swing pour la création de la fenêtre principale d'une application.

La classe chargée de construire l'interface graphique de l'application peut hériter de la classe JFrame.

public class Application extends JFrame  ... 

L'instanciation de la classe JFrame peut être réalisée directement dans la méthode principale main() et utiliser le constructeur de la classe pour initialiser la fenêtre.

import javax.swing.*;
class Fenetre extends JFrame 
 public Fenetre() 
   super("Nom de la fenêtre"); // Appel du constructeur de JFrame
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   setVisible(true);
 

 public static void main(String[] arguments) 
   JFrame fen = new Fenetre();
 

Une autre solution consiste à déclarer l'instance de la classe JFrame en tant que variable globale statique de sorte à pouvoir utiliser directement l'objet dans la méthode main().

import javax.swing.*;
class Fenetre extends JFrame 
 static JFrame fen = new JFrame("Nom de la fenêtre");

 public static void main(String[] arguments) 
   fen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   fen.setVisible(true);
 

La classe JFrame comprend plusieurs centaines de méthodes destinées à modifier les caractéristiques de la fenêtre. Il est possible par exemple de positionner l'objet sur l'écran, de le dimensionner, d'ajouter des composants, etc..

://java.sun.com/docs/books/tutorial/uiswing/components/panel.html

Une fenêtre JFrame comprend un certain nombre de couches superposées sur lesquelles des composants Swing peuvent être placés. En fait, l'objet JFrame doit posséder :

import javax.swing.*;
class Fenetre extends JFrame 
   public Fenetre() 
       super("Nom de la fenêtre");
       setSize(300, 200);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setVisible(true);
   }

   public static void main(String[] arguments) 
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
          public void run() {
              JFrame fen = new Fenetre();
          }
      });
   }

36.2 / Les gestionnaires de placement

Les gestionnaires de placement (layout manager) permettent de disposer des composants dans un panneau de contenu en fonction des caractéristiques qui leurs sont propres.

L'ensemble des gestionnaires de placement implémente l'interface java.awt.LayoutManager.

36.3 / La classe FlowLayout

L'instance de la classe FlowLayout dispose les composants dans un flux directionnel déterminé.

L'instance de la classe FlowLayout dispose les composants dans un flux directionnel déterminé. Les alignements utilisés correspondent aux directions d'écritures et aux alignements de texte.

FlowLayout.CENTER : centrage des composants.
FlowLayout.LEFT : justification à gauche des composants.
FlowLayout.RIGHT : justification à droite des composants.
FlowLayout.LEADING : justification par rapport au bord de départ fourni par l'orientation RTL (Right To Left) ou LTR (Left To Right) du conteneur.
FlowLayout.TRAILING : justification par rapport au bord d'arrivée fourni par l'orientation du conteneur.
FlowLayout flux = new FlowLayout(FlowLayout.LEFT);
Container panneauContenu = getContentPane();
panneauContenu.setLayout(flux));

Des intervalles entre les composants peuvent être fournis par le biais d'un constructeur (FlowLayout(int alignement, int h, int l)) ou de méthodes spécifiques (setHGap() et setVGap()).

L'objet FlowLayout constitue le gestionnaire de placement par défaut du conteneur d'un applet Java et des objets conteneur du type JPanel.

import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class FluxPlacement extends JFrame {
    public FluxPlacement() {
        super("Démonstration FlowLayout");
        
        this.creerInterface();
        super.setSize(300, 300);
        super.setVisible(true);
    }
    public void creerInterface() {
        JPanel pan = (JPanel)this.getContentPane();
        JTextField texte1 = new JTextField(20);
        JButton btn1 = new JButton("Premier bouton");
        JTextField texte2 = new JTextField(20);
        JButton btn2 = new JButton("Second bouton");

        FlowLayout gestionnaire = new FlowLayout();
        pan.setLayout(gestionnaire);
        pan.add(texte1);
        pan.add(btn1);
        pan.add(texte2);
        pan.add(btn2);
    }
    public static void main(String[] args) {
        FluxPlacement boite = new FluxPlacement();
    }
}

36.4 / Le gestionnaire BorderLayout

L'instance de la classe BorderLayout constitue le gestionnaire de placement par défaut d'un panneau de contenu.

L'objet BorderLayout comporte quatre zones en bordures (Nord, Est, Sud et Ouest) et une zone centrale. Chaque région ne peut contenir qu'un seul composant.

BorderLayout PlacementBordure = new BorderLayout();

Le dimensionnement des composants s'effectue selon leur positionnement. Les composants des régions Nord et Sud peuvent s'étirer horizontalement, ceux de l'Est et de l'Ouest s'étirent verticalement et celui du centre dans les deux directions.

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class PlacementBordure extends JFrame {
    public PlacementBordure() {
        super("Démonstration BorderLayout");

        this.creerInterface();

        super.pack();
        super.setVisible(true);
    }
    public void creerInterface() {
        JPanel pan = (JPanel)this.getContentPane();
        JTextField texte = new JTextField("Centre");
        texte.setPreferredSize(new Dimension(120, 120));
        JButton btnNord = new JButton("Nord");
        JButton btnEst = new JButton("Est");
        JButton btnSud = new JButton("Sud");
        JButton btnOuest = new JButton("Ouest");

        BorderLayout gestionnaire = new BorderLayout();
        pan.setLayout(gestionnaire);
        pan.add(texte, BorderLayout.CENTER);
        pan.add(btnNord, BorderLayout.NORTH);
        pan.add(btnEst, BorderLayout.EAST);
        pan.add(btnSud, BorderLayout.SOUTH);
        pan.add(btnOuest, BorderLayout.WEST);
    }
    public static void main(String[] args) {
        PlacementBordure boite = new PlacementBordure();
    }
}

36.5 / La classe BoxLayout

L'instance de la classe BoxLayout permet de disposer les composants selon un axe horizontal ou vertical.

Un objet de type Box peut être créé verticalement ou horizontalement, par l'intermédiaire de deux méthodes statiques de la classe Box, respectivement createVerticalBox() et createHorizontalBox().

Box boiteV = Box.createVerticalBox();
Box boiteH = Box.createHorizontalBox();

Ce gestionnaire de placement n'autorise pas un saut de ligne ou de colonne en cas de dépassement de la taille maximum possible. Dans ce cas, l'objet BoxLayout tente de réduire la taille des composants ou les tronque si cela n'est pas possible.

BoxLayout PlacementBoite = new BoxLayout(Container cible, int axe);

Quatre axes d'orientation, représentés par des constantes statiques de la classe BoxLayout, sont possibles :

BorderLayout.X_AXIS : Axe vertical.
BorderLayout.Y_AXIS : Axe horizontal.
BorderLayout.LINE_AXIS : Axe de la direction d'une ligne fournie par la propriété ComponentOrientation du panneau de contenu.
BorderLayout.PAGE_AXIS : Axe de la direction d'une page fournie par la propriété ComponentOrientation du panneau de contenu.
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Boite extends JFrame {
    public Boite() {
        super("Démonstration BoxLayout");

        this.creerInterface();

        super.pack();
        super.setVisible(true);
    }
    public void creerInterface() {
        JPanel pan = (JPanel)this.getContentPane();
        JTextField texte1 = new JTextField(25);
        JButton btn1 = new JButton("Premier bouton");
        JTextField texte2 = new JTextField(25);
        JButton btn2 = new JButton("Second bouton");

        BoxLayout gestionnaire = new BoxLayout(pan, BoxLayout.X_AXIS);
        pan.setLayout(gestionnaire);
        pan.add(texte1);
        pan.add(btn1);
        pan.add(texte2);
        pan.add(btn2);
    }
    public static void main(String[] args) {
        Boite boite = new Boite();
    }
}

36.6 / La classe CardLayout

L'instance de la classe CardLayout construit une pile de composants se plaçant les uns au dessus des autres.

L'objet CardLayout traite les composants comme des cartes dont une seule peut être visible, par défaut, la première de la pile.

CardLayout pileCarte = new CardLayout();

Le gestionnaire de placement fournit plusieurs méthodes destinées à parcourir les cartes (first(), last(), previous() et next()) et à les afficher (show()).

carte.next(getContentPane());

Il est possible de fournir des intervalles horizontaux et verticaux entre le conteneur et le composant par l'intermédiaire d'un constructeur (CardLayout(int h, int l)) ou de méthodes spécifiques (setHGap() et setVGap()).

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class CartePlacement extends JFrame implements ItemListener {
    private JPanel cartes;

    public CartePlacement() {
        super("Démonstration CardLayout");

        this.creerInterface();

        this.pack();
        this.setVisible(true);
    }
    public void creerInterface() {
        JPanel pan = (JPanel) this.getContentPane();

        JPanel panMenu = new JPanel();
        String menus[] = { "Première carte", "Seconde carte" };
        JComboBox jcbMenu = new JComboBox(menus);
        jcbMenu.addItemListener(this);
        panMenu.add(jcbMenu);

        JPanel carte1 = new JPanel();
        carte1.add(new JButton("Premier Bouton"));
        carte1.add(new JTextField(20));

        JPanel carte2 = new JPanel();
        carte2.add(new JTextField(20));
        carte2.add(new JButton("Second bouton"));

        cartes = new JPanel(new CardLayout());
        cartes.add(carte1, menus[0]);
        cartes.add(carte2, menus[1]);

        pan.add(panMenu, BorderLayout.NORTH);
        pan.add(cartes, BorderLayout.CENTER);
    }

    public void itemStateChanged(ItemEvent e) {
        CardLayout carte = (CardLayout) (cartes.getLayout());
        carte.show(cartes, (String) e.getItem());
    }
    public static void main(String[] args) {
        CartePlacement doite = new CartePlacement();
    }
}

36.7 / Le gestionnaire GridLayout

L'instance de la classe GridLayout propose un gestionnaire de placement disposant les composants à l'intérieur des cellules d'une grille rectangulaire régullière.

La classe GridLayout dispose de trois constructeurs.

GridLayout GL = new GridLayout();
Le constructeur par défaut permet d'instancier un objet GridLayout composé d'une seule ligne et d'une seule colonne.
GridLayout GL = new GridLayout(lignes, colonnes);
Le second constructeur permet de créer un objet GridLayout composé du nombre de lignes et de colonnes passés en argument.
GridLayout GL = new GridLayout(lignes, colonnes, espacesH, espacesV);
Le dernier constructeur crée un gestionnaire de placement composé d'un certain nombre de colonnes et de lignes, ainsi que d'espaces horizontaux et verticaux entre les composants.

Il faut qu'au moins une des valeurs représentant le nombre de colonnes et de lignes soit différente de zéro. De cette façon, un objet GridLayout pourra être soit une ligne, soit une colonne, composée d'un certain nombre de cellules.

GridLayout GL = new GridLayout(0, 10);

GridLayout GL = new GridLayout(10, 0);
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Grille extends JFrame {
    public Grille() {
        super("Démonstration GridLayout");

        this.creerInterface();

        super.pack();
        super.setVisible(true);
    }
    public void creerInterface() {
        JPanel pan = (JPanel)this.getContentPane();
        JTextField texte1 = new JTextField(20);
        JButton btn1 = new JButton("Premier bouton");
        JTextField texte2 = new JTextField(20);
        JButton btn2 = new JButton("Second bouton");
        JTextField texte3 = new JTextField(20);
        JButton btn3 = new JButton("Troisième bouton");
        JTextField texte4 = new JTextField(20);
        JButton btn4 = new JButton("Quatrième bouton");

        GridLayout gestionnaire = new GridLayout(4, 4);
        pan.setLayout(gestionnaire);
        pan.add(texte1);
        pan.add(btn1);
        pan.add(texte2);
        pan.add(btn2);
        pan.add(texte3);
        pan.add(btn3);
        pan.add(texte4);
        pan.add(btn4);
    }
    public static void main(String[] args) {
        Grille boite = new Grille();
    }
}

36.8 / Le gestionnaire GridBagLayout

L'instance de la classe GridBagLayout représente le gestionnaire de placement le plus complexe et le plus flexible de la plateforme Java.

L'objet GridBagLayout aligne les composants en les plaçant dans une grille composée de colonnes et de lignes. Chaque cellule peut contenir un à plusieurs composants. D'autre part, contrairement à l'objet GridLayout, il est possible que les composants soient placés sur une ou plusieurs cellules. De même, les lignes et les colonnes dans la grille ne sont pas nécessairement toutes de la même hauteur et de la même largeur.

La gestion du placement des composants nécessitent l'instanciation de la classe GridBagConstraints chargée d'exposer les contraintes de positionnement.

Container contentPane = getContentPane();
GridBagLayout grille = new GridBagLayout();
GridBagConstraints contraintes = new GridBagConstraints();
contentPane.setLayout(grille);

Chaque composant est placé dans une ou plusieurs cellules dont les caractéristiques doivent être fournies à un objet GridBagConstraints. Ce dernier contient un certain nombre de champs qui permettront au gestionnaire de placement de positionner précisément chaque composant.

// Instanciation du composant
ClasseGraphique obj = new ClasseGraphique();
// Définition des contraintes
contraintes.champs = valeur;
...
// Application des contraintes
grille.setConstraints(obj, contraintes);
// Ajout de l'objet dans le panneau de contenu
panneauContenu.add(obj);

Il est important de noter que ce processus doit être répété pour chaque composant à ajouter dans un panneau de contenu géré par le gestionnaire de placement GridBagLayout, et que les champs de l'objet GridBagConstraints doivent être réinitialisés pour chacun des objets graphiques, puisqu'en général une seule instance de la classe GridBagConstraints est employée pour l'ensemble de ces objets.

Le champs fill est utilisé pour la gestion du remplissage de la zone d'affichage du composant lorsque celui-ci possède une taille inférieure à l'espace disponible.

contraintes.fill = GridBagConstraints.CONSTANTE;
NONE : ne fournit aucune contrainte de taille (valeur par défaut).
HORIZONTAL : redimensionne horizontalement le composant afin de totalement remplir la zone d'affichage horizontale.
VERTICAL : redimensionne verticalement le composant afin de totalement remplir la zone d'affichage verticale.
BOTH : redimensionne horizontalement et verticalement le composant afin de totalement remplir la zone d'affichage.

L'ajout d'un composant dans ce gestionnaire de placement demande d'indiquer dans quelle cellule devra s'afficher le composant. L'objet GridBagConstraints dispose de deux champs gridx et gridy spécifiant les coordonnées de la cellule devant contenir le composant.

JButton bouton = new JButton("Un bouton");
contraintes.gridx = 0;
contraintes.gridy = 0;
grille.setConstraints(bouton, contraintes);
panneauContenu.add(bouton);

Il est également possible de spécifier une zone d'affichage comprenant plusieurs cellules. Un composant peut être placé sur des cellules alignées horizontalement ou verticalement par l'intermédiaire des champs gridheight et gridwidth.

JTextArea zoneTextuelle = new JTextArea("Une zone de texte");
// Spécification du nombre de cellules verticales 
// sur lesquelles s'afficheront le composant.
contraintes.gridwidth = 3;
// Spécification du nombre de cellules horizontales 
// sur lesquelles s'afficheront le composant.
contraintes.gridheight = 5;
// Affichage du composant sur la première colonne et la seconde ligne.
contraintes.gridx = 0;
contraintes.gridy = 1;
grille.setConstraints(zoneTextuelle, contraintes);
panneauContenu.add(zoneTextuelle);

Les espaces de remplissage au sein des composants peuvent être founis par l'intermédiaire des champs ipadx et ipady spécifiant respectivement des marges horizontales et verticales.

JButton bouton = new JButton("Soumettre");
contraintes.gridx = 1;
contraintes.gridy = 5;
// Spécifications de marges horizontales 
// de 10 pixels et verticales de 8 pixels.
contraintes.ipadx = 10;
contraintes.ipady = 8;
grille.setConstraints(bouton, contraintes);
panneauContenu.add(bouton);

Les espaces entre les composants sont définis par le biais d'un champs insets contenant un objet de type Insets, auquel sont passées quatre valeurs entières représentant les espaces supérieurs, inférieurs, droites et gauches.

constraintes.insets = 
      new Insets(valSup, valGau, valInf, valInf);

Les champs weightx et weighty permettent respectivement une redistribution des espaces libres horizontaux et verticaux entre les composants.

contraintes.weightx = 10;
contraintes.weighty = 12;

Le champs anchor fournit la position du composant au sein de sa zone d'affichage dans le panneau de contenu.

contraintes.anchor = GridBagConstraints.SOUTH;

Les valeurs possibles pour ce champs se décomposent en deux catégories.

les valeurs relatives : CENTER (valeur par défaut), NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST et NORTHWEST
les valeurs absolues : PAGE_START, PAGE_END, LINE_START, LINE_END, FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_START et LAST_LINE_END

La classe GridBagLayout possède deux constructeurs. Le premier ne contient aucun argument et le second demande de fournir toutes les valeurs explicitées précédemment à appliquer par défaut aux composants à ajouter dans le conteneur.

GridBagConstraints GBC = 
                  new GridBagConstraints(val_gridx,
                                            val_gridy,
                                            val_gridwidth,
                                            val_gridheight,
                                            val_weightx,
                                            val_weighty,
                                            val_anchor,
                                            val_fill,
                                            obj_insets,
                                            val_ipadx,
                                            val_ipady);
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class GrilleComplexe extends JFrame {
    public GrilleComplexe() {
        super("Démonstration GridBagLayout");

        this.creerInterface();

        super.pack();
        super.setVisible(true);
    }
    public void creerInterface() {
        JPanel pan = (JPanel)this.getContentPane();
        JTextField texte = new JTextField("Centre");
        texte.setPreferredSize(new Dimension(120, 120));
        JButton btnNord = new JButton("Nord");
        JButton btnEst = new JButton("Est");
        JButton btnSud = new JButton("Sud");
        JButton btnOuest = new JButton("Ouest");
        
        GridBagConstraints contraintes = new GridBagConstraints();
        GridBagLayout gestionnaire = new GridBagLayout();
        pan.setLayout(gestionnaire);
        
        contraintes.gridx = 0;
        contraintes.gridy = 0;
        contraintes.gridheight = 1;
        contraintes.gridwidth = 3;
        contraintes.weightx = 0;
        contraintes.weighty = 0;
        contraintes.fill = GridBagConstraints.HORIZONTAL;
        gestionnaire.setConstraints(btnNord, contraintes);
        pan.add(btnNord);
       
        contraintes.gridx = 0;
        contraintes.gridy = 1;
        contraintes.gridheight = 1;
        contraintes.gridwidth = 1;
        contraintes.weightx = 0;
        contraintes.weighty = 0;
        contraintes.fill = GridBagConstraints.VERTICAL;
        gestionnaire.setConstraints(btnOuest, contraintes);
        pan.add(btnOuest);

        contraintes.gridx = 1;
        contraintes.gridy = 1;
        contraintes.gridheight = 1;
        contraintes.gridwidth = 1;
        contraintes.weightx = 1;
        contraintes.weighty = 1;
        gestionnaire.setConstraints(texte, contraintes);
        pan.add(texte);

        contraintes.gridx = 2;
        contraintes.gridy = 1;
        contraintes.gridheight = 1;
        contraintes.gridwidth = 1;
        contraintes.weightx = 0;
        contraintes.weighty = 0;
        contraintes.fill = GridBagConstraints.VERTICAL;
        gestionnaire.setConstraints(btnEst, contraintes);
        pan.add(btnEst);

        contraintes.gridx = 0;
        contraintes.gridy = 2;
        contraintes.gridheight = 1;
        contraintes.gridwidth = 3;
        contraintes.weightx = 0;
        contraintes.weighty = 0;
        contraintes.fill = GridBagConstraints.HORIZONTAL;
        gestionnaire.setConstraints(btnSud, contraintes);
        pan.add(btnSud);
    }
    public static void main(String[] args) {
        GrilleComplexe boite = new GrilleComplexe();
    }
}

36.9 / Le gestionnaire SpringLayout

Le gestionnaire de placement SpringLayout s'appuie sur les bords des composants graphiques afin de les placer au sein d'un panneau de contenu. Il définit des relations entre les bords des composants.

SpringLayout ressort = new SpringLayout();

La classe SpringLayout.Constraints permet de spécifier les contraintes à appliquer à l'objet SpringLayout pour placer des composants graphiques. Cette classe permet de fixer ou de récupérer la valeur de quatre propriétés, les coordonnées (x et y) et la taille (height et width) à appliquer à un composant.

JtextField texte = new JTextField();
SpringLayout.Constraints contraintes = 
                         new SpringLayout.Constraints(texte);
//ou
SpringLayout.Constraints contraintes = 
                         SpringLayout.Constraints getConstraints(texte);

Les méthodes de la classe SpringLayout.Constraints utilise exclusivement des objets Spring pour spécifier ou obttenir les valeurs de contraintes précitées. Cette objet contient trois propriétés qui caractérise son comportement, les valeurs minimum, maximum et préférée. Chacune de ces propriétés peut être impliqué dans la définition de sa quetrième valeur, soit une propriété basée sur une série de règles.

JPanel pan = (JPanel)frame.getContentPane();
SpringLayout gestionnaire = new SpringLayout();
pan.setLayout(gestionnaire);

JButton bouton = new JButton("Bouton");
JTextField texte = new JTextField(20);
pan.add(bouton);
pan.add(texte);

SpringLayout.Constraints contraintesBouton = 
                               gestionnaire.getConstraints(bouton);
contraintesBouton.setX(Spring.constant(8));
contraintesBouton.setY(Spring.constant(8));

SpringLayout.Constraints contraintesTexte = 
                               gestionnaire.getConstraints(textField);
contraintesTexte.setX(
                  Spring.sum(
                          Spring.constant(5), 
                          contraintesBouton.getConstraint(SpringLayout.EAST)));
contraintesTexte.setY(Spring.constant(5));

La classe SpringLayout fournit quatre constantes désignant chacun des bords du composant graphique contraint (EAST, NORTH, SOUTH et WEST). Une constante passée à la méthode getConstraint() indique qu'un objet Spring concernant le bord spécifié doit être retourné.

Un instance de la classe Spring peut être assimilé à un ressort qui est capable de se comprimer ou de s'étirer entre des valeurs minimum et maximum autour de la valeur préférée. A cet effet, plusieurs méthodes de la classe Spring sont disponibles afin de déterminer les valeurs maximum, minimum et préférée, d'effectuer des soustractions et additions entre des objets Spring.

JTextField texte = new JTextField();
Spring ressortTexte = Spring.width(texte);
JButton bouton = new JButton("Bouton");
Spring ressortBouton = Spring.width(bouton);

int max = ressort.getMaximumValue();
int min = ressort.getMinimumValue();
int pref = ressort.getPreferredValue();

Spring resultatAddition = Spring(
                              ressortTexte, 
                              ressortBouton);
Spring resultatSoustraction = Spring(
                              ressortTexte, 
                              Spring.minus(ressortBouton));
import java.awt.Component;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Spring;
import javax.swing.SpringLayout;

public class RessortPlacement extends JFrame {
    public RessortPlacement() {
        super("Démonstration SpringLayout");

        this.creerInterface();

        super.pack();
        super.setVisible(true);
    }
    public void creerInterface() {
        JPanel pan = (JPanel) this.getContentPane();
        JLabel label1 = new JLabel("Premier label");
        JTextField textField1 = new JTextField(20);
        JButton bouton1 = new JButton("Premier bouton");
        JLabel label2 = new JLabel("Second label");
        JTextField textField2 = new JTextField(20);
        JButton bouton2 = new JButton("Second bouton");
        JLabel label3 = new JLabel("Troisième label");
        JTextField textField3 = new JTextField(20);
        JButton bouton3 = new JButton("Troisième bouton");

        SpringLayout ressort = new SpringLayout();
        pan.setLayout(ressort);

        pan.add(label1);
        pan.add(textField1);
        pan.add(bouton1);
        pan.add(label2);
        pan.add(textField2);
        pan.add(bouton2);
        pan.add(label3);
        pan.add(textField3);
        pan.add(bouton3);

        this.creerGrilleCompacte(pan, 3, 3, 5, 5, 5, 5);
    }
    public void creerGrilleCompacte(
                                JPanel panneau, 
                                int lignes, int colonnes,
                                int initialX, int initialY, 
                                int espacementX, int espacementY) {

        SpringLayout gestionnaire = null;
        if (panneau.getLayout() instanceof SpringLayout)
            gestionnaire = (SpringLayout) panneau.getLayout();
        else throw new ClassCastException();

        Spring x = Spring.constant(initialX);
        for (int col = 0; col < colonnes; col++) {
            Spring largeur = Spring.constant(0);
            for (int ligne = 0; ligne < lignes; ligne++) {
                largeur = Spring.max(largeur, getConstraintesComposant(ligne,
                        col, panneau, colonnes).getWidth());
            }
            for (int ligne = 0; ligne < lignes; ligne++) {
                SpringLayout.Constraints contraintes = getConstraintesComposant(
                        ligne, col, panneau, colonnes);
                contraintes.setX(x);
                contraintes.setWidth(largeur);
            }
            x = Spring
                    .sum(x, Spring.sum(largeur, Spring.constant(espacementX)));
        }
        Spring y = Spring.constant(initialY);
        for (int ligne = 0; ligne < lignes; ligne++) {
            Spring hauteur = Spring.constant(0);
            for (int colonne = 0; colonne < colonnes; colonne++) {
                hauteur = Spring.max(hauteur, getConstraintesComposant(ligne,
                        colonne, panneau, colonnes).getHeight());
            }
            for (int c = 0; c < colonnes; c++) {
                SpringLayout.Constraints contraintes = getConstraintesComposant(
                        ligne, c, panneau, colonnes);
                contraintes.setY(y);
                contraintes.setHeight(hauteur);
            }
            y = Spring
                    .sum(y, Spring.sum(hauteur, Spring.constant(espacementY)));
        }
        SpringLayout.Constraints contraintesPanneau = gestionnaire
                .getConstraints(panneau);
        contraintesPanneau.setConstraint(SpringLayout.SOUTH, y);
        contraintesPanneau.setConstraint(SpringLayout.EAST, x);
    }
    private SpringLayout.Constraints getConstraintesComposant(
                                        int ligne,
                                        int colonne,
                                        JPanel parent,
                                        int colonnes) {
        SpringLayout gestionnaire = (SpringLayout) parent.getLayout();
        Component composant = parent.getComponent(
                                         ligne * colonnes + colonne);
        return gestionnaire.getConstraints(composant);
    }
    public static void main(String[] args) {
        RessortPlacement ressort = new RessortPlacement();
    }
}

37 / Les applications

Le développement d'applications Java nécessite l'installation du JDK (Java Development Kit) qu'il est possible de télécharger à partir du site de Sun Microsystems.

L'environnement de développement proposé par le JDK de Sun permet d'exécuter des applications Java.

Un programme Java s'exécute dans un environnement virtuel standardisé dénommée JVM (Java Virtual Machine) indépendant de toutes plateformes telles que Mac OS, Windows, Linux, Solaris, etc..

Le JDK dispose d'un compilateur Java permettant de convertir un code source dans une liste d'instructions machines appelée pseudocode et d'une machine virtuelle.

Le JVM contient un interpréteur Java chargé d'exécuter le pseudocode sur n'importe quel système d'exploitation.

Le code source d'un programme Java est toujours contenu dans un fichier texte possédant l'extension .java. Un fichier .java peut être écrit à partir d'un quelconque éditeur de texte.

Evidemment, ce fichier doit être compilé par une commande en ligne, produisant la génération d'un pseudocode, lui-même stocké dans un nouveau fichier portant l'extension .class et un nom identique au fichier d'origine.

javac nom_programme.java

Suite à la compilation d'un programme Java, il devient possible de l'exécuter par l'interpréteur Java de l'environnement virtuel à l'aide d'une autre commande en ligne.

java nom_programme

L'extension .class est omise, car l'interpréteur traite une classe Java et non un fichier.

Une application Java doit être composée d'une à plusieurs classes pouvant être contenues dans un ou plusieurs fichiers .java, en général une classe par fichier.

Le fichier source doit avoir un nom identique à l'identificateur de la classe présente dans ce fichier.

La classe principale du programme Java doit contenir impérativement une méthode main chargée d'exécuter l'application.

38 / Les appliquettes Java

Les appliquettes (applets) Java sont des programmes fonctionnant dans une page HTML et à partir de navigateur web compatibles.

Le fonctionnement des appliquettes Java nécessite l'importation de classes ou de paquetages (packages).

En l'occurrence, il faut faire appel aux paquetages relatifs aux appliquettes et à l'affichage graphique par l'intermédiaire de l'instruction import.

import java.paquetage.Classe

import java.applet.Applet;
import java.awt.Graphics;

L'importation d'un paquetage complet peut s'accomplir en remplaçant le nom de la classe par une étoile '*'.

import java.paquetage.*

Il faut également déclarer la classe de l'appliquette comme une extension de la classe applet du paquetage importé.

/* La classe nom hérite des attributs 
  et comportements de la classe applet */
public class nom extends Applet
{
  //instructions...
}

En outre, il est possible d'utiliser une forme plus compacte.

public class nom extends java.applet.Applet

Une classe d'appliquette doit posséder une méthode paint destinée à afficher un contenu dans une interface utilisateur graphique.

// On peut écrire (java.awt.Graphics affiche)
public void paint(Graphics affiche)
{
  affiche.drawString("Une chaîne de caractères...", 30, 30);
}

Quatres autres méthodes sont utilisée couramment dans les appliquettes Java. Il s'agit de init, start, stop et destroy.

public class nom extends Applet
{
  ...
  public void init()
  {// Instructions d'initialisation}
  public void start()
  {// Instructions de démarrage}
  public void stop()
  {// Instruction d'arrêt}
  public void destroy()
  {// Instructions de fin}
  ...
}

La méthode init permet d'initialiser les variables et les objets nécessaires au fonctionnement de l'appliquette.

La méthode start exécute des instructions lorsque l'appliquette est chargée ou lorsque le visiteur recharge la page contenant l'appliquette.

La méthode stop exécute des instructions lorqu'un visiteur quitte la page contenant l'appliquette.

La méthode destroy permet de libérer les ressources utilisées par l'appliquette lors de son déchargement.

38.1 / Insertion des applets dans les pages HTML

L'insertion des applets dans les pages Web s'effectue par l'intermédiaire soit de la balise applet à partir des spécification HTML 3.2, soit de la balise object à partir de HTML 4.0.

La balise HTML applet est spécialisée dans l'insertion d'appliquette Java dans une page internet, mais elle a été déprécié par les spécifications HTML 4.0 et est remplacé progressivement par object.

<applet
      codebase="URL_de_base"
      archive="URL_archive,..., URL_archiveN"
      code="fichier.class"
      object="ressource"
      alt="description"
      name="nom_élément"
      width="largeur"
      height="longueur"
      align="alignement"
      hspace="espace_horizontal"
      vspace="espace_vertical"
      {autres attributs communs...}>
  <param name="nom_paramètre" value="valeur">
  ...
</applet>

<applet code="multiplication.class"
             width="320"
             height="240">
  <param name="nombre_1" value="10">
  <param name="nombre_2" value="12">
</applet>

La balise HTML object permet entre autre d'insérer des applets Java dans un document HTML. Néanmoins, cette balise est de plus en plus largement utilisée sur le Web.

<object
      declare
      classid="URL_objet_implémentation"
      codebase="URL_de_base"
      data="URL_objet_données"
      type="type_contenu_donnée"
      codetype="type_contenu_code"
      archive="URL_archive,..., URL_archiveN"
      standby="message attente"
      height="hauteur"
      width="largeur"
      align="alignement"
      border="taille_bordure"
      hspace="espace_horizontal"
      vspace="espace_vertical"
      name="nom_élément"
      tabindex="index_tabulation"
      {autres attributs communs...}>
  <param name="nom_paramètre" value="valeur">
  ...
</object>

<object
          classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
          codebase="http://java.sun.com/products/plugin/autodl
                       /jinstall-1_4_0-win.cab#version=1,4,0,0"
          width="160"
          height="120">
  <param name="code" value="magnetoscope.class">
  <param name="codebase" value="classes/">
  <param name="archive" value="megnetoscope.jar">
  <param name="archive" value="application/x-java-applet">
  <param name="type" value="france_bresil.mpg">
</object>

L'attribut classid prend la valeur de l'exemple ci-dessus pour les navigateurs Internet Explorer et Netscape 6 alors que pour Netscape 4, la valeur doit être égale à "clsid:CAFEEFAC-0014-0000-0000-ABCDEFFEDCBA" afin d'implémenter la version 1.4 du kit de développement Java.

La balise HTML param permet de déclarer les paramètres à passer au programme Java sollicité par les éléments applet ou object.

<param
      id="identificateur"
      name="nom_paramètre"
      value="valeur"
      valuetype="DATA|REF|OBJECT"
      type="type_contenu">

La balise HTML embed est utilisée parfois pour insérer des appliquettes Java dans des pages Internet destinées à être chargées par les navigateurs de Netscape.

<embed
      code="fichier.class"
      type="type_MIME"
      pluginspage="URL_instruction"
      pluginurl="URL_module"
      align="alignement"
      border="taille_bordure"
      frameborder="YES|NO"
      height="hauteur"
      width="largeur"
      units="PIXELS|EN"
      hidden="TRUE|FALSE
      hspace="espace_horizontal"
      vspace="espace_vertical"
      name="nom_élément"
      palette="FOREGROUND|BACKGROUND">
  ...
  <noembed>
  <img src="img.gif"
                   alt="Your browser understands the <applet> 
                           tag but isn't running the applet, for some reason."
 Your browser is completely ignoring the <applet> tag!
  </noembed>
</embed>

<embed code="lecture.class"
              pluginurl="magnetophone.jar"
              type="application/x-java-applet;version=1.4"
              soundsource = "audio"
              soundtrack = musique.au
              sounds = "3.au|4.au|5.au|6.au"
              pause = "100" 
              scriptable="false"
              pluginspage="http://java.sun.com/products
                              /plugin/index.html#download">
  <noembed>
  <b style="color:red">
      Désolé, votre navigateur ne supporte pas les appliquettes Java.
  </b>
  </noembed>
</embed>

Le type d'application précisée par l'attribut type permet dans ce cas de déclarer que le programme Java a été écrit conformément à la version 1.4 du kit de développement Java pour les navigateurs Netscape, tandis que pour les versions inférieures du JDK, il faudra utiliser ce type "application/x-java-applet;jpi-version=1.4".

Un module distribué par Sun, permet d'ajouter la machine virtuelle Java au navigateur tentant de charger la page web contenant l'applet et son attribut PLUGINSPAGE pointant vers le site de téléchargement spécifié ci-dessus.

De plus amples informations à ce sujet sont disponibles sur le site de Sun.

38.2 / Le paquetage java.applet

Le paquetage java.applet fournit les classes nécessaires à la création d'une appliquette Java et à la communication avec le contexte de l'appliquette.

Un applet est un programme incorporable dans une page Web. Plusieurs méthodes utilisées par le contexte de l'applet, pour son initialisation, son démarrage et son arrêt.

import java.applet.*
Les interfaces
Interface
Description
AppletContext
correspond à l'environnement d'un applet, soit le document contenant l'applet ainsi que d'éventuels autres.
AppletStub
lorsqu'un applet est créé pour la première fois, un morceau de l'applet est attaché en utilisant la méthode setSub.
AudioClip
constitue une simple abstraction pour jouer un extrait sonore.
Les classes
Classe
Description
applet
correspond à un applet destiné à être incorporé dans une autre application.

39 / Le paquetage java.lang

Le paquetage java.lang fournit les classes fondamentales à la conception à de tout programme Java.

Les interfaces
CharSequence représente une séquence lisible de caractères.
Cloneable une classe implémente l'interface CloneAble pour indiquer à la méthode Objetc.clone() qu'il est légal pour cette méthode de faire une copie champ par champ de cette classe.
Comparable impose une disposition totale sur les objets de chaque classe qui l'implémente.
Runnable devrait être implémentée par n'importe quelle classe dont les instances sont destinées à être exécutées par un thread.

Les classes
Boolean constitue une classe wrapper destinée à englober une valeur du type primitif booléen dans un objet.
Byte constitue une classe wrapper destinée à englober une valeur du type primitif byte dans un objet.
Character constitue une classe wrapper destinée à englober une valeur du type primitif char dans un objet.
Character.Subset Les instances de cette classe représente des sous-ensembles particuliers du jeu de caractères Unicode.
Character.UnicodeBlock sonstitue une famille de sous-ensembles de caractères représentant des groupes dans les spécifications Unicode.
Class Les instances de cette classe représentent des classes et des interfaces dans une application en exécution.
ClassLoader est un objet qui est responsable du chargement des classes.
Compiler est prévu pour supporter les compilateurs Java-to-native-code (code natif vers Java) et les services associés.
Double constitue une classe wrapper destinée à englober une valeur du type primitif double dans un objet.
Float constitue une classe wrapper destinée à englober une valeur du type primitif float dans un objet.
InheritableThreadLocal héritant de la classe ThreadLocal, fournit l'héritage des valeurs à partir du thread parent vers le thread enfant : lorsqu'un thread enfant est créé, l'enfant reçoit les valeurs initiales pour toutes les variables du thread local transmis pour lesquelles le parent a des valeurs.
Integer constitue une classe wrapper destinée à englober une valeur du type primitif int dans un objet.
Long constitue une classe wrapper destinée à englober une valeur du type primitif long dans un objet.
Math contient les méthodes pour exécuter les opérations numériques basiques telles que les exponentielles, les logarthment les puissances, les racines, etc..
Number représente la superclasse des classes BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, et Short.
Object constitue la classe racine de l'ensemble des classes Java.
Package contient les informations à propos de l'implémentation et des spécifications d'un paquetage Java.
Process Les méthodes Runtime.exec crée une exécution native et retourne une instance d'une sous-classe de Process qui peut être utilisée pour contrôer l'exécution et obtenir des informations à son propos.
Runtime Chaque application Java a une unique instance de la classe Runtime qui autorise l'application à se connecter avec l'environnement dans lequel l'application s'exécute.
RuntimePermission gère les permissions d'exécution.
SecurityManager est une classe qui autorise les applications à implémenter une politique de sécurité.
Short constitue une classe wrapper destinée à englober une valeur du type primitif short dans un objet.
StackTraceElement représente un élément dans une stack trace (suivi de la réalisation d'un programme phase après phase), retourné par Throwable.getStackTrace().
StrictMath contient les méthodes pour l'exécution d'opérations numériques de base.
String fournit des méthodes destinées à manipuler des chaînes de caractères immuables.
StringBuffer fournit des méthodes destinées à manipuler des chaînes de caractères mutables.
System contient plusieurs classes, champs et méthodes utiles telles que pour lancer le Garbage Collector, terminer l'exéution de la JVM, etc..
Thread fournit des outils pour gérer les unités d'exécution (threads) dans un programme.
ThreadGroup représente un jeu de threads.
ThreadLocal représente les variables d'un thread local.
Throwable représente le superclasse de toutes les erreurs et exceptions dans le langage Java.
Void est une classe qu'on ne peut instancier pour conserver une référence à la classe Object représentant le mot clé void.

Le exceptions
ArithmeticException Une condition arithmétique exceptionnelle s'est produite.
ArrayIndexOutOfBoundsException Un tableau a été accédé avec un index invalide.
ArrayStoreException Une tentative a été faite pour stocker un type d'objet erroné à l'intérieur d'un tableau d'objets.
ClassCastException Le code a tenté un transtypage d'un objet vers une sous-classe de laquelle elle n'est pas une instance.
ClassNotFoundException Un application essaie de charger dans une classe au moyen de son nom en utilisant la méthode forName dans une classe Class.
CloneNotSupportedException Une méthode clone dans une classe Object a été appelée à cloner un objet, mais que la classe de l'objet n'implémente pas l'interface Cloneable.
Exception La classe Exception et ses sous-classes sont une forme de classe Throwable qui indique les conditions qu'une application raisonnable peut vouloir attraper.
IllegalAccessException Une application essaie de créer réflectivement une instance (autre qu'un tableau), fixe ou obtient un champ ou invoque une méthode mais couramment l'exécution de la méthode n'a pas accès à la définition de la classe, champ, méthode ou constructeur spécifié.
IllegalArgumentException Une méthode a passé un argument illégal ou inapproprié.
IllegalMonitorStateException Un thread a tenté d'attendre sur un moniteur d'objet ou notifier d'autres threads attendant sur un moniteur d'objet sans posséder le moniteur spécifié.
IllegalStateException Une méthode a été invoquée à une période illégale ou inappropriée.
IllegalThreadStateException Un thread n'est pas dans un état approprié pour l'opération requise.
IndexOutOfBoundsException Un index d'une certaine catégorie est hors de l'intervalle pour un tableau, une chaîne de caractères ou un vecteur.
InstantiationException Une application essaie de créer une instance d'une classe utilisant la méthode newInstance dans la classe Class, mais la classe d'objet spécifiée ne peut être instanciée parcequ'il est une interface ou est une classe abstraite.
InterruptedException Un thread est en attente, en sommeil ou en pause pour une longue période et un autre thread interrompt son utilisation en utilisant la méthode interrupt dans la classe Thread.
NegativeArraySizeException Une application essaie de créer un tableau avec une taille négative.
NoSuchFieldException Une classe n'a pas un champ avec le nom spécifié.
NoSuchMethodException Une méthode particulière ne peut être trouvée.
NullPointerException Une application tente d'utiliser null dans un cas ou un objet est requis.
NumberFormatException Une application a tenté de convertir une chaîne de caractères vers un des types numériques, mais que la chaîne de caractères n'a pas un format approprié.
RuntimeException La classe RuntimeException est la superclasse de ces exceptions qui peut être lancée durant les opérations normales de la JVM (Java Virtual Machine).
SecurityException Le gestionnaire de sécurité indique une violation de sécurité.
StringIndexOutOfBoundsException Les méthodes de chaînes de caractères indique qu'un index est soit négatif, soit trop grand par rapport à la taille de la chaîne de caractères.
UnsupportedOperationException L'opération requise n'est pas supportée.

Les erreurs
AbstractMethodError Une application essaie d'apeler une méthode abstraite.
AssertionError Une assertion a échoué.
ClassCircularityError Une circularité a été détecté pendant l'initialisation d'une classe.
ClassFormatError La JVM tente de lire un fichier classe et détermine que ce dernier est malformé ou ne peut être interprété comme un fichier classe.
Error Une classe Error est une sous-classe de Throwable qui indique de sérieux problèmes qu'une application raisonnable devrait essayer d'attraper.
ExceptionInInitializerError Une exception inattendue s'est produite dans un initialisateur statique.
IllegalAccessError Une application tente d'accéder ou de modifier un champ ou d'appeler une méthode qu'elle ne peut accéder.
IncompatibleClassChangeError Une échange de classe incompatible s'est produit.
InstantiationError Une application essaie d'utiliser le constructeur Java new pour instancier une classe abstraite ou une interface.
InternalError Une certaine erreur interne inattendue s'est produite dans la JVM.
LinkageError Une classa a une certaine dépendance sur une autre classe; toutefois la seconde classe a fait une échange incompatible après la compilation de la classe précédente.
NoClassDefFoundError La JVM ou une instance de ClassLoader essaie de charger dans la définition d'une classe (comme une partie de l'appel d'une méthode normal ou de la création d'une nouvelle instance utilisant l'expression new) et non la définition de la classe instance qui pourra être trouvée.
NoSuchFieldError Une application essaie d'accéder ou de modifier un champ spécifié d'un objet et que ce dernier peu raisonnable a ce champ.
NoSuchMethodError Une application essaie d'appeler une méthode spécifée d'une classe (soit statique,sois une instance) et qu'une classe peu raisonnable a une définition de cette méthode.
OutOfMemoryError La JVM ne peut allouer un objet parcequ'elle est en dépassement de mémoire et aucune mémoire ne peut être rendu disponible par le Garbage Collector.
StackOverflowError Un débordement de mémoire (stack : tas) se produit parcequ'une application s'exécute récursivement trop profondément.
ThreadDeath Une instance de la classe ThreadDeath est lancée dans un thread victime lorsque la méthode stop avec aucun argument dans la classe Thread est applelé.
UnknownError Une exception sérieuse mais inconnue s'est produite dans la JVM.
UnsatisfiedLinkError La JVM ne peut pas trouver une définition de langage natif appropriée d'une méthode déclarée native.
UnsupportedClassVersionError La JVM tente de lire un fichier classe et détermine que les numéros de version majeur et mineur dans le fichier ne sont pas supportés.
VerifyError Le "vérificateur" détecte qu'un fichier classe pourtant bien formé, contient plusieurs sortes d'inconsistances internes ou de problèmes de sécurité.
VirtualMachineError La JVM est interrompue ou a exécuterdes ressources nécessaires pour qu'il continue l'opération.

39.1 / La classe Boolean

La classe wrapper Boolean englobe une valeur de type primitif booléen dans un objet. Un objet de type booléen contient un seul champ, lequel est de type booléen.

Les champs
static Boolean FALSE
Ce champ représente l'objet Boolean correspondant à la valeur primitive FALSE.
static Boolean TRUE
Ce champ représente l'objet Boolean correspondant à la valeur primitive TRUE.
static Class TYPE
Ce champ représente l'objet Class correspondant au type booléen primitif.


Les constructeurs
Boolean(boolean valeur)
alloue un objet booléen représentant l'argument valeur.
Boolean(String chaine)
alloue un objet booléen représentant la valeur true si la chaîne de caractères passée en argument n'est pas nulle et est égal en ignorant la casse à la chaîne de caractères "true".


Les champs
boolean booleanValue()
retourne la valeur de l'objet booléen comme un booléen primitif.
boolean equals(Object obj)
retourne true si et seulement si l'argument n'est pas nul et est un objet booléen qui représente la même valeur booléenne que cet objet.
static boolean getBoolean(String name)
retourne true si et seulement si la propriété système nommée par l'argument existe et est égal à la chaîne de caractères "true".
int hashCode()
retourne un hash code pour cet objet booléen.
String toString()
retourne un objet String représentant la valeur de l'objet Boolean.
static String toString(boolean b)
retourne un objet String représentant la valeur de l'objet Boolean.
static Boolean valueOf(boolean b)
retourne une instance de la classe Boolean représentant la valeur booléenne spécifiée.
static Boolean valueOf(String s)
retourne un objet Boolean représenté par la chaîne de caractères spécifiée.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.2 / La classe Byte

La classe wrapper Byte englobe une valeur de type primitif byte dans un objet. Un objet de type Byte contient un seul champ, lequel est de type primitif byte.

Les champs
static byte MAX_VALUE
Ce champ représente une constante contenant la valeur maximum, soit une valeur de type byte égale à 27-1.
static byte MIN_VALUE
Ce champ représente un constante contenant la valeur minimum, soit une valeur de type byte égale à -27.
static Class TYPE
Ce champ représente l'objet Byte correspondant à la valeur primitive de type byte.


Les constructeurs
Byte(byte value)
alloue un objet Byte que représente la valeur de type primitif byte.
Byte(String s)
alloue un objet Byte par l'intermédiaire d'une chaîne de caractères représentant une valeur de type primitif byte.


Les méthodes
byte byteValue()
retourne la valeur de l'objet Byte comme un type primitif byte.
int compareTo(Byte anotherByte)
compare numériquement deux objets Byte.
int compareTo(Object o)
compare l'objet Byte à un autre objet.
static Byte decode(String nm)
décode un objet String à l'intérieur d'un objet Byte.
double doubleValue()
retourne la valeur de l'objet Byte comme un type primitif double.
boolean equals(Object obj)
compare l'objet Byte par rapport à un autre objet passé en argument.
float floatValue()
retourne la valeur de l'objet Byte comme un type primitif float.
int hashCode()
retourne un hash code pour l'objet Byte.
int intValue()
retourne la valeur de l'objet Byte comme un type primitif int.
long longValue()
retourne la valeur de l'objet Byte comme un type primitif long.
static byte parseByte(String s)
analyse l'argument String comme une valeur byte décimale signée.
static byte parseByte(String s, int radix)
analyse l'argument String comme une valeur byte signée dans la racine spécifiée par le second argument.
short shortValue()
retourne la valeur de l'objet Byte comme un type primitif byte.
String toString()
retourne un objet String représentant la valeur de l'objet Byte.
static String toString(byte b)
retourne un nouvel objet String représentant la valeur byte spécifiée.
static Byte valueOf(String s)
retourne un objet Byte contenant la valeur donnée par la chaîne de caractères passée en argument.
static Byte valueOf(String s, int radix)
retourne un objet Byte contenant la valeur extraite à partir de la chaîne de caractères et de la racine.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.3 / La classe Character

La classe wrapper Character englobe dans un objet une valeur de type primitif char. Cet objet Character contient un unique champ dont le type est char.

Les classes imbriquées
static class Character.Subset
Les instances de cette classe représentent des sous-ensembles particuliers du jeu de caractères Unicode.
static class Character.UnicodeBlock
représente une famille de sous-ensembles de blocs de caractères dans la spécification Unicode.

Les champs
static byte COMBINING_SPACING_MARK
représente la catégorie générale "Mc" dans la spécification Unicode.
static byte CONNECTOR_PUNCTUATION
représente la catégorie générale "Pc" dans la spécification Unicode.
static byte CONTROL
représente la catégorie générale "Cc" dans la spécification Unicode.
static byte CURRENCY_SYMBOL
représente la catégorie générale "Sc" dans la spécification Unicode.
static byte DASH_PUNCTUATION
représente la catégorie générale "Pd" dans la spécification Unicode.
static byte DECIMAL_DIGIT_NUMBER
représente la catégorie générale "Nd" dans la spécification Unicode.
static byte DIRECTIONALITY_ARABIC_NUMBER
représente le type de caractère bidirectionnel de poids faible "AN" dans la spécification Unicode.
static byte DIRECTIONALITY_BOUNDARY_NEUTRAL
représente le type de caractère bidirectionnel de poids faible "BN" dans la spécification Unicode.
static byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
représente le type de caractère bidirectionnel de poids faible "CS" dans la spécification Unicode.
static byte DIRECTIONALITY_EUROPEAN_NUMBER
représente le type de caractère bidirectionnel de poids faible "EN" dans la spécification Unicode.
static byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
représente le type de caractère bidirectionnel de poids faible "ES" dans la spécification Unicode.
static byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
représente le type de caractère bidirectionnel de poids faible "ET" dans la spécification Unicode.
static byte DIRECTIONALITY_LEFT_TO_RIGHT
représente le type de caractère bidirectionnel de poids fort "L" dans la spécification Unicode.
static byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
représente le type de caractère bidirectionnel de poids fort "LRE" dans la spécification Unicode.
static byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
représente le type de caractère bidirectionnel de poids fort "LRO" dans la spécification Unicode.
static byte DIRECTIONALITY_NONSPACING_MARK
représente le type de caractère bidirectionnel de poids faible "NSM" dans la spécification Unicode.
static byte DIRECTIONALITY_OTHER_NEUTRALS
représente le type de caractère bidirectionnel de poids neutre "ON" dans la spécification Unicode.
static byte DIRECTIONALITY_PARAGRAPH_SEPARATOR
représente le type de caractère bidirectionnel de poids neutre "B" dans la spécification Unicode.
static byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
représente le type de caractère bidirectionnel de poids faible "PDF" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT
représente le type de caractère bidirectionnel de poids fort "R" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
représente le type de caractère bidirectionnel de poids fort "AL" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
représente le type de caractère bidirectionnel de poids fort "RLE" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
représente le type de caractère bidirectionnel de poids fort "RLO" dans la spécification Unicode.
static byte DIRECTIONALITY_SEGMENT_SEPARATOR
représente le type de caractère bidirectionnel de poids neutre "S" dans la spécification Unicode.
static byte DIRECTIONALITY_UNDEFINED
représente le type de caractère indéfini.
static byte DIRECTIONALITY_WHITESPACE
représente le type de caractère bidirectionnel de poids neutre "WS" dans la spécification Unicode.
static byte ENCLOSING_MARK
représente la catégorie générale "Me" dans la spécification Unicode.
static byte END_PUNCTUATION
représente la catégorie générale "Pe" dans la spécification Unicode.
static byte FINAL_QUOTE_PUNCTUATION
représente la catégorie générale "Pf" dans la spécification Unicode.
static byte FORMAT
représente la catégorie générale "Cf" dans la spécification Unicode.
static byte INITIAL_QUOTE_PUNCTUATION
représente la catégorie générale "Pi" dans la spécification Unicode.
static byte LETTER_NUMBER
représente la catégorie générale "Nl" dans la spécification Unicode.
static byte LINE_SEPARATOR
représente la catégorie générale "Zl" dans la spécification Unicode.
static byte LOWERCASE_LETTER
représente la catégorie générale "Ll" dans la spécification Unicode.
static byte MATH_SYMBOL
représente la catégorie générale "Sm" dans la spécification Unicode.
static int MAX_RADIX
représente la racine maximum disponible pour la conversion vers et à partir de chaînes de caractères.
static char MAX_VALUE
La valeur constante de ce champ est la valeur la plus grande du type char, soit 'uFFFF'.
static int MIN_RADIX
La racine minimum disponible pour la conversion vers et à partir de chaînes de caractères.
static char MIN_VALUE
La valeur constante de ce champ est la valeur la plus petite du type char, soit 'u0000'.
static byte MODIFIER_LETTER
représente la catégorie générale "Lm" dans la spécification Unicode.
static byte MODIFIER_SYMBOL
représente la catégorie générale "Sk" dans la spécification Unicode.
static byte NON_SPACING_MARK
représente la catégorie générale "Mn" dans la spécification Unicode.
static byte OTHER_LETTER
représente la catégorie générale "Lo" dans la spécification Unicode.
static byte OTHER_NUMBER
représente la catégorie générale "No" dans la spécification Unicode.
static byte OTHER_PUNCTUATION
représente la catégorie générale "Po" dans la spécification Unicode.
static byte OTHER_SYMBOL
représente la catégorie générale "So" dans la spécification Unicode.
static byte PARAGRAPH_SEPARATOR
représente la catégorie générale "Zp" dans la spécification Unicode.
static byte PRIVATE_USE
représente la catégorie générale "Co" dans la spécification Unicode.
static byte SPACE_SEPARATOR
représente la catégorie générale "Zs" dans la spécification Unicode.
static byte START_PUNCTUATION
représente la catégorie générale "Ps" dans la spécification Unicode.
static byte SURROGATE
représente la catégorie générale "Cs" dans la spécification Unicode.
static byte TITLECASE_LETTER
représente la catégorie générale "Lt" dans la spécification Unicode.
static Class TYPE
représente l'instance de classe représentant le type primitif char.
static byte UNASSIGNED
représente la catégorie générale "Cn" dans la spécification Unicode.
static byte UPPERCASE_LETTER
représente la catégorie générale "Lu" dans la spécification Unicode.

Les constructeurs
Character(char value)
construit un nouvel objet de type Character avec pour valeur le caractère spécifié en argument.

Les méthodes
char charValue()
retourne la valeur de l'objet Character.
int compareTo(Character anotherCharacter)
compare deux objets Character numériquement.
int compareTo(Object o)
compare l'objet Character à un autre objet.
static int digit(char ch, int radix)
retourne la valeur numérique du caractère passé en argument par rapport à la racine également passée en argument.
boolean equals(Object obj)
teste l'égalité de l'objet Character par rapport à celui passé en argument.
static char forDigit(int digit, int radix)
détermine si la représentation du caractère pour un chiffre spécifique dans la racine spécifiée.
static byte getDirectionality(char ch)
retourne la propriété directionnelle Unicode pour le caractère donné.
static int getNumericValue(char ch)
retourne la valeur entière représentée par le caractère Unicode spécifié.
static int getType(char ch)
retourne une valeur indiquant la catégorie générale du caractère passé en argument.
int hashCode()
retourne un code de hachage pour l'objet Character.
static boolean isDefined(char ch)
détermine si un caractère est défini dans l'Unicode.
static boolean isDigit(char ch)
détermine si le caractère spécifié est un chiffre.
static boolean isIdentifierIgnorable(char ch)
détermine si le caractère spécifié devrait être un caractère à ignorer dans un identificateur Java ou Unicode.
static boolean isISOControl(char ch)
détermine si le caractère spécifié est un caractère de contrôle ISO.
static boolean isJavaIdentifierPart(char ch)
détermine si le caractère spécifié peut être une partie d'un identificateur Java et autre que le premier caractère.
static boolean isJavaIdentifierStart(char ch)
détermine si le caractère spécifié est permis comme premier caractère d'un identificateur Java.
static boolean isJavaLetter(char ch)
Dépréciée. Voir isJavaIdentifierStart(char).
static boolean isJavaLetterOrDigit(char ch)
Dépréciée. Voir isJavaIdentifierPart(char).
static boolean isLetter(char ch)
détermine si le caractère spécifié est une lettre.
static boolean isLetterOrDigit(char ch)
détermine si le caractère spécifié est une lettre ou un chiffre.
static boolean isLowerCase(char ch)
détermine si le caractère spécifié est un caractère minuscule.
static boolean isMirrored(char ch)
détermine si le caractère est représenté en accord avec la spécification Unicode.
static boolean isSpace(char ch)
Dépréciée. Voir isWhitespace(char).
static boolean isSpaceChar(char ch)
détermine si le caractère spécifié est un caractère d'espace Unicode.
static boolean isTitleCase(char ch)
détermine si le caractère spécifié est un caractère de type titlecase.
static boolean isUnicodeIdentifierPart(char ch)
détermine si le caractère spécifié peut être une partie d'un identificateur Unicode, autre que le premier caractère.
static boolean isUnicodeIdentifierStart(char ch)
détermine si le caractère spécifié est permis comme premier caractère d'un identificateur Unicode.
static boolean isUpperCase(char ch)
détermine si le caractère spécifié est un caractère majuscule.
static boolean isWhitespace(char ch)
détermine si le caractère spécifié est un espace blanc en accord avec Java.
static char toLowerCase(char ch)
convertit le caractère passé en argument en casse minuscule.
String toString()
retourne un objet String représentant la valeur de l'objet Character.
static String toString(char c)
retourne un objet String représentant la valeur de la valeur de type char passé en argument.
static char toTitleCase(char ch)
convertit le caractère passé en argument en titlecase.
static char toUpperCase(char ch)
convertit le caractère passé en argument en casse majuscule.
Les méthodes héritées de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Les classes imbriquées
static class Character.Subset
Les instances de cette classe représentent des sous-ensembles particuliers du jeu de caractères Unicode.
static class Character.UnicodeBlock
représente une famille de sous-ensembles de blocs de caractères dans la spécification Unicode.

Les champs
static byte COMBINING_SPACING_MARK
représente la catégorie générale "Mc" dans la spécification Unicode.
static byte CONNECTOR_PUNCTUATION
représente la catégorie générale "Pc" dans la spécification Unicode.
static byte CONTROL
représente la catégorie générale "Cc" dans la spécification Unicode.
static byte CURRENCY_SYMBOL
représente la catégorie générale "Sc" dans la spécification Unicode.
static byte DASH_PUNCTUATION
représente la catégorie générale "Pd" dans la spécification Unicode.
static byte DECIMAL_DIGIT_NUMBER
représente la catégorie générale "Nd" dans la spécification Unicode.
static byte DIRECTIONALITY_ARABIC_NUMBER
représente le type de caractère bidirectionnel de poids faible "AN" dans la spécification Unicode.
static byte DIRECTIONALITY_BOUNDARY_NEUTRAL
représente le type de caractère bidirectionnel de poids faible "BN" dans la spécification Unicode.
static byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
représente le type de caractère bidirectionnel de poids faible "CS" dans la spécification Unicode.
static byte DIRECTIONALITY_EUROPEAN_NUMBER
représente le type de caractère bidirectionnel de poids faible "EN" dans la spécification Unicode.
static byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
représente le type de caractère bidirectionnel de poids faible "ES" dans la spécification Unicode.
static byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
représente le type de caractère bidirectionnel de poids faible "ET" dans la spécification Unicode.
static byte DIRECTIONALITY_LEFT_TO_RIGHT
représente le type de caractère bidirectionnel de poids fort "L" dans la spécification Unicode.
static byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
représente le type de caractère bidirectionnel de poids fort "LRE" dans la spécification Unicode.
static byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
représente le type de caractère bidirectionnel de poids fort "LRO" dans la spécification Unicode.
static byte DIRECTIONALITY_NONSPACING_MARK
représente le type de caractère bidirectionnel de poids faible "NSM" dans la spécification Unicode.
static byte DIRECTIONALITY_OTHER_NEUTRALS
représente le type de caractère bidirectionnel de poids neutre "ON" dans la spécification Unicode.
static byte DIRECTIONALITY_PARAGRAPH_SEPARATOR
représente le type de caractère bidirectionnel de poids neutre "B" dans la spécification Unicode.
static byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
représente le type de caractère bidirectionnel de poids faible "PDF" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT
représente le type de caractère bidirectionnel de poids fort "R" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
représente le type de caractère bidirectionnel de poids fort "AL" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
représente le type de caractère bidirectionnel de poids fort "RLE" dans la spécification Unicode.
static byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
représente le type de caractère bidirectionnel de poids fort "RLO" dans la spécification Unicode.
static byte DIRECTIONALITY_SEGMENT_SEPARATOR
représente le type de caractère bidirectionnel de poids neutre "S" dans la spécification Unicode.
static byte DIRECTIONALITY_UNDEFINED
représente le type de caractère indéfini.
static byte DIRECTIONALITY_WHITESPACE
représente le type de caractère bidirectionnel de poids neutre "WS" dans la spécification Unicode.
static byte ENCLOSING_MARK
représente la catégorie générale "Me" dans la spécification Unicode.
static byte END_PUNCTUATION
représente la catégorie générale "Pe" dans la spécification Unicode.
static byte FINAL_QUOTE_PUNCTUATION
représente la catégorie générale "Pf" dans la spécification Unicode.
static byte FORMAT
représente la catégorie générale "Cf" dans la spécification Unicode.
static byte INITIAL_QUOTE_PUNCTUATION
représente la catégorie générale "Pi" dans la spécification Unicode.
static byte LETTER_NUMBER
représente la catégorie générale "Nl" dans la spécification Unicode.
static byte LINE_SEPARATOR
représente la catégorie générale "Zl" dans la spécification Unicode.
static byte LOWERCASE_LETTER
représente la catégorie générale "Ll" dans la spécification Unicode.
static byte MATH_SYMBOL
représente la catégorie générale "Sm" dans la spécification Unicode.
static int MAX_RADIX
représente la racine maximum disponible pour la conversion vers et à partir de chaînes de caractères.
static char MAX_VALUE
La valeur constante de ce champ est la valeur la plus grande du type char, soit 'uFFFF'.
static int MIN_RADIX
La racine minimum disponible pour la conversion vers et à partir de chaînes de caractères.
static char MIN_VALUE
La valeur constante de ce champ est la valeur la plus petite du type char, soit 'u0000'.
static byte MODIFIER_LETTER
représente la catégorie générale "Lm" dans la spécification Unicode.
static byte MODIFIER_SYMBOL
représente la catégorie générale "Sk" dans la spécification Unicode.
static byte NON_SPACING_MARK
représente la catégorie générale "Mn" dans la spécification Unicode.
static byte OTHER_LETTER
représente la catégorie générale "Lo" dans la spécification Unicode.
static byte OTHER_NUMBER
représente la catégorie générale "No" dans la spécification Unicode.
static byte OTHER_PUNCTUATION
représente la catégorie générale "Po" dans la spécification Unicode.
static byte OTHER_SYMBOL
représente la catégorie générale "So" dans la spécification Unicode.
static byte PARAGRAPH_SEPARATOR
représente la catégorie générale "Zp" dans la spécification Unicode.
static byte PRIVATE_USE
représente la catégorie générale "Co" dans la spécification Unicode.
static byte SPACE_SEPARATOR
représente la catégorie générale "Zs" dans la spécification Unicode.
static byte START_PUNCTUATION
représente la catégorie générale "Ps" dans la spécification Unicode.
static byte SURROGATE
représente la catégorie générale "Cs" dans la spécification Unicode.
static byte TITLECASE_LETTER
représente la catégorie générale "Lt" dans la spécification Unicode.
static Class TYPE
représente l'instance de classe représentant le type primitif char.
static byte UNASSIGNED
représente la catégorie générale "Cn" dans la spécification Unicode.
static byte UPPERCASE_LETTER
représente la catégorie générale "Lu" dans la spécification Unicode.

Les constructeurs
Character(char value)
construit un nouvel objet de type Character avec pour valeur le caractère spécifié en argument.

Les méthodes
char charValue()
retourne la valeur de l'objet Character.
int compareTo(Character anotherCharacter)
compare deux objets Character numériquement.
int compareTo(Object o)
compare l'objet Character à un autre objet.
static int digit(char ch, int radix)
retourne la valeur numérique du caractère passé en argument par rapport à la racine également passée en argument.
boolean equals(Object obj)
teste l'égalité de l'objet Character par rapport à celui passé en argument.
static char forDigit(int digit, int radix)
détermine si la représentation du caractère pour un chiffre spécifique dans la racine spécifiée.
static byte getDirectionality(char ch)
retourne la propriété directionnelle Unicode pour le caractère donné.
static int getNumericValue(char ch)
retourne la valeur entière représentée par le caractère Unicode spécifié.
static int getType(char ch)
retourne une valeur indiquant la catégorie générale du caractère passé en argument.
int hashCode()
retourne un code de hachage pour l'objet Character.
static boolean isDefined(char ch)
détermine si un caractère est défini dans l'Unicode.
static boolean isDigit(char ch)
détermine si le caractère spécifié est un chiffre.
static boolean isIdentifierIgnorable(char ch)
détermine si le caractère spécifié devrait être un caractère à ignorer dans un identificateur Java ou Unicode.
static boolean isISOControl(char ch)
détermine si le caractère spécifié est un caractère de contrôle ISO.
static boolean isJavaIdentifierPart(char ch)
détermine si le caractère spécifié peut être une partie d'un identificateur Java et autre que le premier caractère.
static boolean isJavaIdentifierStart(char ch)
détermine si le caractère spécifié est permis comme premier caractère d'un identificateur Java.
static boolean isJavaLetter(char ch)
Dépréciée. Voir isJavaIdentifierStart(char).
static boolean isJavaLetterOrDigit(char ch)
Dépréciée. Voir isJavaIdentifierPart(char).
static boolean isLetter(char ch)
détermine si le caractère spécifié est une lettre.
static boolean isLetterOrDigit(char ch)
détermine si le caractère spécifié est une lettre ou un chiffre.
static boolean isLowerCase(char ch)
détermine si le caractère spécifié est un caractère minuscule.
static boolean isMirrored(char ch)
détermine si le caractère est représenté en accord avec la spécification Unicode.
static boolean isSpace(char ch)
Dépréciée. Voir isWhitespace(char).
static boolean isSpaceChar(char ch)
détermine si le caractère spécifié est un caractère d'espace Unicode.
static boolean isTitleCase(char ch)
détermine si le caractère spécifié est un caractère de type titlecase.
static boolean isUnicodeIdentifierPart(char ch)
détermine si le caractère spécifié peut être une partie d'un identificateur Unicode, autre que le premier caractère.
static boolean isUnicodeIdentifierStart(char ch)
détermine si le caractère spécifié est permis comme premier caractère d'un identificateur Unicode.
static boolean isUpperCase(char ch)
détermine si le caractère spécifié est un caractère majuscule.
static boolean isWhitespace(char ch)
détermine si le caractère spécifié est un espace blanc en accord avec Java.
static char toLowerCase(char ch)
convertit le caractère passé en argument en casse minuscule.
String toString()
retourne un objet String représentant la valeur de l'objet Character.
static String toString(char c)
retourne un objet String représentant la valeur de la valeur de type char passé en argument.
static char toTitleCase(char ch)
convertit le caractère passé en argument en titlecase.
static char toUpperCase(char ch)
convertit le caractère passé en argument en casse majuscule.
Les méthodes héritées de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.4 / La classe Character.Subset

Les instances de la classe Character.Subset représente des sous-ensembles particuliers du jeu de caractères Unicode.

La seule famille de sous-ensembles définie dans la classe Character est l'UnicodeBlock. D'autres parties de l'API Java définissent d'autres sous-ensembles pour leurs propres besoins.

Les constructeurs
protected Character.Subset(String name)
construit une nouvelle instance de la classe Subset.

Les méthodes
boolean equals(Object obj)
Compare l'égalité de deux objets Subset.
int hashCode()
retourne la hash code standard comme défini par la méthode Object.hashCode().
String toString()
Returns the name of this subset.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.5 / La classe Character.UnicodeBlock

La classe Character.UnicodeBlock est une famille de caractères représentant des blocs de caractères dans la spécification Unicode.

Les groupes de caractères définissent généralement les caractères utilisés pour un script ou un besoin spécifique. Un caractère est contenu par au maximum un groupe de caractères Unicode.

Les champs
BASIC_LATIN, CURRENCY_SYMBOLS, CYRILLIC, GREEK, GEOMETRIC_SHAPES,
MATHEMATICAL_OPERATORS, etc. (voir documentation API Java)
représente un constante pour le bloc de caractères Unicode du même nom.
Les méthodes
static Character.UnicodeBlock of(char c)
Returns the object representing the Unicode block containing the given character, or null if the character is not a member of a defined block.
Les méthodes héritées de la classe racine java.lang.Character.Subset
equals, hashCode, toString
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.6 / La classe Class

Les instances de la classe Class représentent des classes et des interfaces dans une exécution d'une application Java.

Egalement, chaque tableau appartient à une classe qui est reflétée comme un objet Class qui est partagé par tous les tableaux avec le même type d'éléments et de nombre de dimensions.

Les types primitifs Java (boolean, byte, char, short, int, long, float, et double), et le mot clé void sont aussi représentés comme des objets Class.

La classe Class ne possède pas de constructeur public. A la place, les instances de la classe Class sont construites automatiquement par la machine virtuelle Java si les classes sont chargées et par des appels à la méthode Loader.defineClass.

Les méthodes
boolean desiredAssertionStatus()
retourne le statut de l'assertion qui sera assigné à cette classe si elle était initialisée au moment ou cette méthode est invoquée.
static Class forName(String className)
retourne l'objet Class associé à la classe ou l'interface avec le nom spécifié sous forme d'une chaîne de caractères.
static Class forName(String name, boolean initialize, ClassLoader loader)
retourne l'objet Class associé à la classe ou l'interface avec le nom donné et en utilisant la classe Loader spécifiée.
Class[] getClasses()
retourne un tableau contenant les objets Class représentant toutes les classes et interfaces publiques qui sont membres de la classe représentée par l'objet Class.
ClassLoader getClassLoader()
retourne la classe Loader pour la classe.
Class getComponentType()
retourne l'objet Class représentant le type composant d'un tableau.
Constructor getConstructor(Class[] parameterTypes)
retourne un objet Constructor qui reflète le constructeur public spécifié de la classe représentée par l'objet Class.
Constructor[] getConstructors()
retourne un tableau contenant des objets Constructor reflétant tous les constructeurs publics de la classe représentée par l'objet Class.
Class[] getDeclaredClasses()
retourne un tableau d'objets Class reflétant toutes les classes et interfaces déclarées comme membres de la classe représentée par l'objet Class.
Constructor getDeclaredConstructor(Class[] parameterTypes)
retourne un objet Constructor qui reflète le constructeur spécifié de la classe ou interface représentée par la l'objet Class.
Constructor[] getDeclaredConstructors()
retourne un tableau d'objets Constructor reflétant tous les constructeurs déclarés par la classe représentée par l'objet Class.
Field getDeclaredField(String name)
retourne un objet Field qui refléte le champ déclaré spécifié de la classe ou de l'interface représentée par l'objet Class.
Field[] getDeclaredFields()
retourne un tableau d'objets Field reflétant tous les champs déclarés par la classe ou l'interface représentée par l'objet Class.
Method getDeclaredMethod(String name, Class[] parameterTypes)
retourne un objet Method qui reflète la méthode déclarée spécifiée de la classe ou de l'interface représentée par l'objet Class.
Method[] getDeclaredMethods()
retourne un tableau d'objets Method reflétant toutes les méthodes déclarées par la classe ou l'interface représentée par l'objet Class.
Class getDeclaringClass()
Si la classe ou l'interface représentée par l'objet Class est un membre d'une autre classe, retourne l'objet Class représentant la classe dans laquelle elle était déclarée.
Field getField(String name)
retourne un objet Field qui reflète le champ membre public spécifié de la classe ou de l'interface représentée par l'objet Class.
Field[] getFields()
retourne un tableau contenant les objets Field reflètant tous les champs publics accessibles de la classe ou de l'interface représentée par l'objet Class.
Class[] getInterfaces()
détermine les interfaces implémentées par la classe ou l'interface représentée par l'objet Class.
Method getMethod(String name, Class[] parameterTypes)
retourne un objet Method qui reflète la méthode membre public spécifiée de la classe ou de l'interface représentée par l'objet Class.
Method[] getMethods()
retourne un tableau contenant les objets Method reflètant toutes les méthodes membres publiques de la classe ou de l'interface représentée par l'objet Class, incluant celles déclarées par les classes ou interface et également celles héritées à partir des superclasses et superinterfaces.
int getModifiers()
retourne les modificateurs du langage Java pour la classe ou l'interface, encodés dans un entier.
String getName()
retourne le nom de l'entité (classe, interface, tableau, type primitif, ou void) représentée par l'objet Class, dans une chaîne de caractères.
Package getPackage()
retourne le paquetage pour l'objet Class.
ProtectionDomain getProtectionDomain()
retourne l'objet ProtectionDomain de l'objet Class.
URL getResource(String name)
trouve une ressource à partir d'un nom donné.
InputStream getResourceAsStream(String name)
trouve une ressource à partir d'un nom donné.
Object[] getSigners()
retourne les signataires (signers) de l'objet Class
Class getSuperclass()
retourne l'objet Class représentant la superclasse de l'entité (classe, interface, type primitif ou void) représentée par l'objet Class.
boolean isArray()
détermine si l'objet Class représente une classe de tableau.
boolean isAssignableFrom(Class cls)
détermine si les objets de la classe spécifiée peuvent être assignés aux objets de la classe objet.
boolean isInstance(Object obj)
détermine si l'objet spécifié est est une instance la classe représentée par l'objet Class.
boolean isInterface()
détermine si l'objet Class spécifié représente un type d'interface.
boolean isPrimitive()
détermine si l'objet Class spécifié représente un type primitif.
Object newInstance()
crée une nouvelle instance de la classe représentée par l'objet Class.
String toString()
convertit l'objet vers une chaine de caractères.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

39.7 / La classe ClassLoader

La classe ClassLoader est un objet qui est responsable du chargement des classes.

La classe ClassLoader est une classe abstraite. Donner le nom d'une classe signifie qu'une classe ClassLoader doit tenter de localiser ou de générer des données qui constituent la définition de la classe.

Chaque objet Class contient une référence vers l'objet ClassLoader qui le définit.

Les constructeurs
protected ClassLoader()
crée un objet ClassLoader utilisant une classe de chargement retournée par la méthode ClassLoader.getSystemClassLoader().
protected ClassLoader(ClassLoader parent)
crée un objet ClassLoader utilisant une classe de chargement parente pour une délégation.

Les méthodes
void clearAssertionStatus()
fixe le statut de l'assertion par défaut pour l'objet ClassLoader à false et abandonne n'importe quels paquetages par défaut associés à l'objet ClassLoader.
protected Class defineClass(byte[] b, int off, int len)
Dépréciée et remplacée par defineClass(java.lang.String, byte[], int, int).
protected Class defineClass(String name, byte[] b, int off, int len)
convertit un tableau d'octets en une instance de la classe Class.
protected Class defineClass(String name, byte[] b,
int off, int len, ProtectionDomain protectionDomain)
convertit un tableau d'octets en une instance de la classe Class, avec un objet optionnel ProtectionDomain.
protected Package definePackage(String name, String specTitle,
String specVersion, String specVendor, String implTitle,
String implVersion, String implVendor, URL sealBase)
définit un paquetage par son nom dans un objet ClassLoader.
protected Class findClass(String name)
trouve la classe spécifiée.
protected String findLibrary(String libname)
retourne le chemin absolu d'une bibliothèque native.
protected Class findLoadedClass(String name)
trouve la classe avec le nom donné si elle a été chargée auparavant au moyen de l'objet ClassLoader.
protected URL findResource(String name)
trouve la ressource avec le nom donné.
protected Enumeration findResources(String name)
retourne un objet Enumeration des adresses URLs représentant toutes les ressources avec le nom donné.
protected Class findSystemClass(String name)
trouve une classe avec le nom spécifié en la chargeant si cela est nécessaire.
protected Package getPackage(String name)
retourne un paquetage qui a été défini par l'objet ClassLoader ou n'importe lequel de ses ancêtres.
protected Package[] getPackages()
retourne tous les paquetages définis par l'objet ClassLoader et ses ancêtres.
ClassLoader getParent()
retourne l'objet ClassLoader parent pour une délégation.
URL getResource(String name)
trouve la ressource avec le nom spécifié.
InputStream getResourceAsStream(String name)
retourne un flux entrant pour une lecture de la ressource spécifiée.
Enumeration getResources(String name)
trouve toutes les ressources avec le nom donné.
static ClassLoader getSystemClassLoader()
retourne la classe de chargement système pour une délégation.
static URL getSystemResource(String name)
trouve une ressource du nom spécifié à partir du chemin de recherche utilisé pour charger les classes.
static InputStream getSystemResourceAsStream(String name)
ouvre en lecture, une ressource du nom spécifié à partir du chemin de recherche utilisé pour charger les classes.
static Enumeration getSystemResources(String name)
trouve toutes les ressource du nom spécifié à partir du chemin de recherche utilisé pour charger les classes.
Class loadClass(String name)
charge la classe avec le nom spécfiée.
protected Class loadClass(String name, boolean resolve)
charge la classe avec le nom spécfiée.
protected void resolveClass(Class c)
relie la classe spécifiée.
void setClassAssertionStatus(String className, boolean enabled)
fixe le statut de l'assertion désirée pour la classe de niveau supérieur nommée dans la classe de chargement et n'importe quelles classes imbriquées contenues à l'intérieur.
void setDefaultAssertionStatus(boolean enabled)
fixe le statut de l'assertion par défaut pour la classe de chargement.
void setPackageAssertionStatus(String packageName, boolean enabled)
fixe le statut de l'assertion du paquetage par défaut pour le paquetage nommé.
protected void setSigners(Class c, Object[] signers)
fixe les signataires (signers) d'une classe.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.8 / La classe Compiler

La classe Compiler est prévue pour supporter les compilateurs Java-to-native-code (Java vers code natif) et les services liés.

Par conception, la classe Compiler ne fait rien, elle a pour rôle de favoriser une implémentation de compilateur JIT (Just In Time : au moment nécessaire)

Lorsque la JVM (Java Virtual Machine) démarre la première fois, il détermine si la propriété système java.compiler existe. Les propriétés systèmes sont accessibles au moyen de la méthode System.getProperty. S'il en est ainsi, il est présumé être le nom d'une bibliothèque avec un type et une localisation exacte dépendant de la plateforme hôte, la méthode System.loadLibrary est appelée pour charger cette bibliothèque. Si ce chargement résussi, la fonction dénommée java_lang_compiler_start() de cette bibliothèque est appelée. S'il n'y a pas de compilateur disponible, ces méthodes ne font rien.

Les méthodes
static Object command(Object any)
examine le type d'argument et ses champs et exécute une certaine opération documentée.
static boolean compileClass(Class clazz)
compile la classe spécifiée.
static boolean compileClasses(String string)
compile toutes les classes dont le nom correspond à la chaîne de caractères.
static void disable()
indique au compilateur de cesser l'opération en cours.
static void enable()
indique au compilateur de reprendre l'opération en cours.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.9 / La classe Double

La classe wrapper Double englobe une valeur de type primitif double dans un objet. Un objet de type Double contient un seul champ, lequel est de type primitif double.

Les champs
static double MAX_VALUE
Ce champ représente une constante contenant la valeur maximum positive, soit une valeur de type byte égale à 21023.
static double MIN_VALUE
Ce champ représente une constante contenant la valeur minimum positive, soit une valeur de type double égale à 2-1074.
static double NaN
Ce champ représente une constante contenant un NaN (Not-a-Number).
static double NEGATIVE_INFINITY
Ce champ représente une constante contenant la valeur infinie négative (-infinity).
static double POSITIVE_INFINITY
Ce champ représente une constante contenant la valeur infinie positive (infinity).
static Class TYPE
Ce champ représente l'objet Double correspondant à la valeur primitive de type double.
Les constructeurs
Double(double value)
construit un nouvel objet Double initialisé à la valeur de type double passée en argument.
Double(String s)
construit un nouvel objet Double initialisé à la valeur de type double représentée par une chaîne de caractères passée en argument.

Les méthodes
byte byteValue()
retourne la valeur de l'objet Double dans un type primitif byte.
static int compare(double d1, double d2)
compare les deux valeurs de type double spécifiées.
int compareTo(Double anotherDouble)
compare numériquement deux objets Double.
int compareTo(Object o)
compare l'objet Double à un autre objet.
static long doubleToLongBits(double value)
retourne une représentation de la valeur de type double spécifiée en accord avec la disposition binaire IEEE 754 floating-point.
static long doubleToRawLongBits(double value)
retourne une représentation de la valeur de type double spécifiée en accord avec la disposition binaire IEEE 754 floating-point en préservant les valeurs NaN (Not a Number).
double doubleValue()
retourne une valeur de type double de l'objet Double.
boolean equals(Object obj)
compare l'objet Double par rapport à un autre objet passé en argument.
float floatValue()
retourne la valeur de l'objet Double dans un type primitif float.
int hashCode()
retourne le hash code pour l'objet Double.
int intValue()
retourne la valeur de l'objet Double dans un type primitif int.
boolean isInfinite()
retourne true si la valeur de l'objet Double est infini, sinon elle retourne false.
static boolean isInfinite(double v)
retourne true si la valeur de type double spécifiée est infini, sinon elle retourne false.
boolean isNaN()
retourne true si la valeur de l'objet Double n'est pas un nombre (NaN), sinon elle retourne false.
static boolean isNaN(double v)
retourne true si la valeur de type double spécifiée n'est pas un nombre (NaN), sinon elle retourne false.
static double longBitsToDouble(long bits)
retourne la valeur de type double correspondant à une représentation binaire spécifiée.
long longValue()
retourne la valeur de l'objet Double dans un type primitif long.
static double parseDouble(String s)
retourne une valeur de type primitif double initialisé à la valeur représentée par la chaîen de caractères spécifiée.
short shortValue()
retourne la valeur de l'objet Double dans un type primitif short.
String toString()
retourne un objet String représentant la valeur de l'objet Double.
static String toString(double d)
retourne un objet String représentant la valeur de la variable de type double passée en argument.
static Double valueOf(String s)
retourne un objet Double contenant la valeur primitive double re^résentée par la chaîne de caractères passée en argument.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.10 / La classe Float

La classe wrapper Float englobe une valeur de type primitif float dans un objet. Un objet de type Float contient un seul champ, lequel est de type primitif float.

Les champs
static float MAX_VALUE
Ce champ représente une constante contenant la valeur maximum positive, soit une valeur de type byte égale à 2127.
static float MIN_VALUE
Ce champ représente une constante contenant la valeur minimum positive, soit une valeur de type float égale à 2-149.
static float NaN
Ce champ représente une constante contenant un NaN (Not-a-Number).
static float NEGATIVE_INFINITY
Ce champ représente une constante contenant la valeur infinie négative (-infinity).
static float POSITIVE_INFINITY
Ce champ représente une constante contenant la valeur infinie positive (infinity).
static Class TYPE
Ce champ représente l'objet Float correspondant à la valeur primitive de type float.
Les constructeurs
Float(double value)
construit un nouvel objet Float initialisé à la valeur, passée en argument, de type double converti en float.
Float(float value)
construit un nouvel objet Float initialisé à la valeur de type float passée en argument.
Float(String s)
construit un nouvel objet Float initialisé à la valeur de type float représentée par une chaîne de caractères passée en argument.

Les méthodes
byte byteValue()
retourne la valeur de l'objet Float dans un type primitif byte.
static int compare(float d1, float d2)
compare les deux valeurs de type float spécifiées.
int compareTo(Float anotherFloat)
compare numériquement deux objets Float.
int compareTo(Object o)
compare l'objet Float à un autre objet.
double doubleValue()
retourne une valeur de type double de l'objet Float.
boolean equals(Object obj)
compare l'objet Float par rapport à un autre objet passé en argument.
static long floatToIntBits(float value)
retourne une représentation de la valeur de type float spécifiée en accord avec la disposition binaire IEEE 754 floating-point.
static long floatToRawIntBits(float value)
retourne une représentation de la valeur de type float spécifiée en accord avec la disposition binaire IEEE 754 floating-point en préservant les valeurs NaN (Not a Number).
float floatValue()
retourne la valeur de l'objet Float dans un type primitif float.
int hashCode()
retourne le hash code pour l'objet Float.
static float intBitsToFloat(int bits)
retourne la valeur de l'objet Float correspondant à la représentation binaire donnée.
int intValue()
retourne la valeur de l'objet Float dans un type primitif int.
boolean isInfinite()
retourne true si la valeur de l'objet Float est infini, sinon elle retourne false.
static boolean isInfinite(float v)
retourne true si la valeur de type float spécifiée est infini, sinon elle retourne false.
boolean isNaN()
retourne true si la valeur de l'objet Float n'est pas un nombre (NaN), sinon elle retourne false.
static boolean isNaN(float v)
retourne true si la valeur de type float spécifiée n'est pas un nombre (NaN), sinon elle retourne false.
long longValue()
retourne la valeur de l'objet Float dans un type primitif long.
static float parseFloat(String s)
retourne une valeur de type primitif float initialisé à la valeur représentée par la chaîen de caractères spécifiée.
short shortValue()
retourne la valeur de l'objet Float dans un type primitif short.
String toString()
retourne un objet String représentant la valeur de l'objet Float.
static String toString(float f)
retourne un objet String représentant la valeur de la variable de type float passée en argument.
static Float valueOf(String s)
retourne un objet Float contenant la valeur primitive float re^résentée par la chaîne de caractères passée en argument.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.11 / La classe InheritableThreadLocal

La classe InheritableThreadLocal fournit l'héritage des valeurs à partir du thread parent vers le thread enfant.

Lorsque ce dernier est créé, il reçoit les valeurs initiales pour toutes les variables du thread local hérité, pour lesquelles le parent possède des valeurs. Normalement, les valeurs de l'enfant seront identiques à celles du parent. Toutefois, la valeur de l'enfant peut être créée par une fonction arbitraire du parent, par surcharge de la méthode childValue dans cette classe.

Les variable du thread local hérité sont utilisés de préférence vers des variable d'un thread local ordinaire lorsque les attributs du thread partagé étant maintenu dans la variable (cf : User ID, Transaction ID), doivent être automatiquement transmis vers n'importe quel thread créé.

Les constructeurs
InheritableThreadLocal()
construit une instance de la classe InheritableThreadLocal.

Les méthodes
protected Object childValue(Object parentValue)
calcul la valeur initiale des enfants pour cette variable du thread local hérité comme une fonction de la valeur du parent au moment ou l'enfant est créé.
Les méthodes héritées de la classe java.lang.ThreadLocal
get, initialValue, set
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.12 / La classe Integer

La classe wrapper Integer englobe une valeur de type primitif integer dans un objet. Un objet de type Integer contient un seul champ, lequel est de type primitif integer.

Les champs
static int MAX_VALUE
Ce champ représente un constante contenant la valeur entière maximum égale à 231-1.
static int MIN_VALUE
Ce champ représente un constante contenant la valeur entière minimum égale à -231.
static Class TYPE
Ce champ représente une instance de cla classe Class représentant un type primitif int.

Les constructeurs
Integer(int value)
construit une instance de la classe Integer qui représente la valeur de type int spécifiée.
Integer(String s)
construit une instance de la classe Integer qui représente la valeur de type int déduite de la chaîne de caractères spécifiée.

Les méthodes
byte byteValue()
retourne la valeur de l'objet Integer sous la forme d'un type primitif byte.
int compareTo(Integer anotherInteger)
compare numériquement deux objets Integer.
int compareTo(Object o)
compare l'objet Integer à un autre objet.
static Integer decode(String nm)
décode une chaîne de caratères à l'intérieur d'un objet Integer.
double doubleValue()
retourne la valeur de l'objet Integer sous la forme d'un type primitif double.
boolean equals(Object obj)
compare l'objet Integer à l'objet spécifié.
float floatValue()
retourne la valeur de l'objet Integer sous la forme d'un type primitif float.
static Integer getInteger(String nm)
détermine la valeur entière de la propriété système possédant le nom spécifié.
static Integer getInteger(String nm, int val)
détermine la valeur entière de la propriété système avec le nom spécifié.
static Integer getInteger(String nm, Integer val)
retourne la valeur entière de la propriété système spécifiée.
int hashCode()
retourne le hash code pour l'objet Integer.
int intValue()
retourne la valeur de l'objet Integer sous la forme d'un type ptimitif int.
long longValue()
retourne la valeur de l'objet Integer sous la forme d'un type ptimitif long.
static int parseInt(String s)
analyse la chaîne de caractères passée en argument comme un entier décimal signé.
static int parseInt(String s, int radix)
analyse la chaîne de caractères passée en argument comme un entier signé avec une racine spécifiée par le second argument.
short shortValue()
retourne la valeur de l'objet Integer sous la forme d'un type primitif short.
static String toBinaryString(int i)
retourne une représentation de l'argument entier sous la forme d'un entier non-signé en base 2.
static String toHexString(int i)
retourne une représentation de l'argument entier sous la forme d'un entier non-signé en base 16.
static String toOctalString(int i)
retourne une représentation de l'argument entier sous la forme d'un entier non-signé en base 8.
String toString()
retourne un objet String représentant la valeur entière de l'objet String.
static String toString(int i)
retourne un objet String représentant la valeur entière spécifiée.
static String toString(int i, int radix)
retourne une représentation sous la forme d'une chaîne de caractères un entier donné et selon une racine spécifiée.
static Integer valueOf(String s)
retourne un objet Integer contenant la valeur représentée par l'objet String spécifié.
static Integer valueOf(String s, int radix)
retourne un objet Integer contenant la valeur extriate à partir de l'objet String spécifié analysé avec la racine donné par l'intermédiaire du second argument.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.13 / La classe Long

La classe wrapper Long englobe une valeur de type primitif long dans un objet. Un objet de type Long contient un seul champ, lequel est de type primitif long.

Les champs
static long MAX_VALUE
Ce champ représente un constante contenant la valeur entière maximum égale à 263-1.
static long MIN_VALUE
Ce champ représente un constante contenant la valeur entière minimum égale à -263.
static Class TYPE
Ce champ représente une instance de cla classe Class représentant un type primitif long.

Les constructeurs
Long(long value)
construit une instance de la classe Long qui représente la valeur de type long spécifiée.
Long(String s)
construit une instance de la classe Long qui représente la valeur de type long déduite de la chaîne de caractères spécifiée.

Les méthodes
byte byteValue()
retourne la valeur de l'objet Long sous la forme d'un type primitif byte.
int compareTo(Long anotherLong)
compare numériquement deux objets Long.
int compareTo(Object o)
compare l'objet Long à un autre objet.
static Long decode(String nm)
décode une chaîne de caratères à l'intérieur d'un objet Long.
double doubleValue()
retourne la valeur de l'objet Long sous la forme d'un type primitif double.
boolean equals(Object obj)
compare l'objet Long à l'objet spécifié.
float floatValue()
retourne la valeur de l'objet Long sous la forme d'un type primitif float.
static Long getLong(String nm)
détermine la valeur entière de la propriété système possédant le nom spécifié.
static Long getLong(String nm, int val)
détermine la valeur entière de la propriété système avec le nom spécifié.
static Long getLong(String nm, Long val)
retourne une valeur entière de la propriété système avec le nom spécifiée.
int hashCode()
retourne le hash code pour l'objet Long.
int intValue()
retourne la valeur de l'objet Long sous la forme d'un type ptimitif int.
long longValue()
retourne la valeur de l'objet Long sous la forme d'un type ptimitif long.
static long parseLong(String s)
analyse la chaîne de caractères passée en argument comme un entier décimal signé.
static long parseLong(String s, int radix)
analyse la chaîne de caractères passée en argument comme un entier signé avec une racine spécifiée par le second argument.
short shortValue()
retourne la valeur de l'objet Long sous la forme d'un type primitif short.
static String toBinaryString(long l)
retourne une représentation de l'argument entier sous la forme d'un entier non-signé en base 2.
static String toHexString(long l)
retourne une représentation de l'argument entier sous la forme d'un entier non-signé en base 16.
static String toOctalString(long l)
retourne une représentation de l'argument entier sous la forme d'un entier non-signé en base 8.
String toString()
retourne un objet String représentant la valeur entière de l'objet String.
static String toString(long l)
retourne un objet String représentant la valeur entière spécifiée.
static String toString(long l, int radix)
retourne une représentation sous la forme d'une chaîne de caractères un entier donné et selon une racine spécifiée.
static Long valueOf(String s)
retourne un objet Long contenant la valeur représentée par l'objet String spécifié.
static Long valueOf(String s, int radix)
retourne un objet Long contenant la valeur extriate à partir de l'objet String spécifié analysé avec la racine donné par l'intermédiaire du second argument.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass,
notify, notifyAll, wait, wait, wait

39.14 / La classe Math

La classe Math contient des méthodes pour exécuter des opérations numériques de base telles que l'exponentiel, le logarithme, la racine carrée, les fonctions trigonométriques, les minimums et les maximums.

Les champs
static double E
Ce champ représente la valeur double approchée de e, soit la base du logarithme naturel.
static double PI
Ce champ représente la valeur double approchée de PI, soit le ratio de la circonférence d'un cercle par rapport a son diamètre.

Les méthodes
static double abs(double a)
retourne la valeur absolue d'une valeur de type double.
static float abs(float a)
retourne la valeur absolue d'une valeur de type float.
static int abs(int a)
retourne la valeur absolue d'une valeur int.
static long abs(long a)
retourne la valeur absolue d'une valeur long.
static double acos(double a)
retourne l'arc-cosinus d'un angle, dans l'intervalle 0.0 jusqu'à PI.
static double asin(double a)
retourne l'arc-sinus d'un angle dans l'intervalle de -PI/2 jusqu'à PI/2.
static double atan(double a)
retourne l'arc-tangente d'un angle dans l'intervalle de -PI/2 jusqu'à PI/2.
static double atan2(double y, double x)
convertit des coordonnées rectangulaires (x, y) en polaires (r, theta).
static double ceil(double a)
retourne la plus petite valeur double (prôche de l'infini négatif : -infinity) qui n'est pas plus petit que l'argument et est égal à un entier mathématique.
static double cos(double a)
retourne le cosinus trigonométrique d'un angle.
static double exp(double a)
retourne le nombre d'Euler e élevé à la puissance d'une valeur double.
static double floor(double a)
retourne la plus grande valeur double (prôche de l'infini positif : infinity) qui n'est pas plus grand que l'argument et est égal à un entier mathématique.
static double IEEEremainder(double f1, double f2)
calcul l'opération restante sur deux arguments comme prescrit dans le standard IEEE 754.
static double log(double a)
retourne le logarithme naturel (base e) d'une valeur double.
static double max(double a, double b)
retourne la plus grande des deux valeurs de type double.
static float max(float a, float b)
retourne la plus grande des deux valeurs de type float.
static int max(int a, int b)
retourne la plus grande des deux valeurs de type int.
static long max(long a, long b)
retourne la plus grande des deux valeurs de type long.
static double min(double a, double b)
retourne la plus petite des deux valeurs de type double.
static float min(float a, float b)
retourne la plus petite des deux valeurs de type float.
static int min(int a, int b)
retourne la plus petite des deux valeurs de type int.
static long min(long a, long b)
retourne la plus petite des deux valeurs de type long.
static double pow(double a, double b)
retourne la valeur d'un double élevé à la puissance représentée par le second argument (ab).
static double random()
retourne une valeur double avec un signe positif, plus grand ou égal à 0.0 et plus petit que 1.0.
static double rint(double a)
retourne la valeur double qui est la plus prôche de la valeur de l'argument et est égal à un entier mathématique.
static long round(double a)
retourne la plus prôche valeur de type long de l'argument.
static int round(float a)
retourne la plus prôche valeur de type int de l'argument.
static double sin(double a)
retourne le sinus trigonométrique d'un angle.
static double sqrt(double a)
retourne la valeur positive arrondie de la racine carrée d'une valeur de type double.
static double tan(double a)
retourne la tangente trigonométrique d'un angle.
static double toDegrees(double angrad)
convertit approximativement un angle mesuré en radians en degrés.
static double toRadians(double angdeg)
convertit approximativement un angle mesuré en degrés en radians.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.15 / La classe Number

La classeabstraite Number constitue la superclasse des classes BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, et Short.

Les constructeurs
Number()
construit un nouvel objet Number.

Les méthodes
byte byteValue()
retourne la valeur du nombre spécifié sous la forme d'un type primitif byte.
abstract double doubleValue()
retourne la valeur du nombre spécifié sous la forme d'un type primitif double.
abstract float floatValue()
retourne la valeur du nombre spécifié sous la forme d'un type primitif float.
abstract int intValue()
retourne la valeur du nombre spécifié sous la forme d'un type primitif int.
abstract long longValue()
retourne la valeur du nombre spécifié sous la forme d'un type primitif long.
short shortValue()
retourne la valeur du nombre spécifié sous la forme d'un type primitif short.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.16 / La classe Object

La classe Object est la racine de l'ensemble de la hiérarchie de classes Java. Chaque classe possède une classe Object comme superclasse.

Tous les objets, incluant les tableaux, implémente les méthodes de la classe Object.

Les constructeurs
Object()
construit un nouvelle instance de la classe Object.

Les méthodes
protected Object clone()
crée et retourne une copie de l'objet.
boolean equals(Object obj)
indique si l'objet est égal à un autre.
protected void finalize()
appelé par le Garbage Collector sur un objet lorsque ce dernier détermine qu'il n'y a plus de références vers des objets.
Class getClass()
retourne la classe d'exécution d'un objet.
int hashCode()
retourne une valeur hash code pour l'objet.
void notify()
réveille un unique thread qui est en attente sur le moniteur d'objet.
void notifyAll()
réveille tous les threads qui sont en attente sur le moniteur d'objet.
String toString()
retourne une chaîne de caractères représentant l'objet.
void wait()
indique au thread courant d'attendre jusqu'à ce qu'un autre thread invoque la méthode notify() ou notifyAll() pour l'objet.
void wait(long timeout)
indique au thread courant d'attendre jusqu'à ce qu'un autre thread invoque la méthode notify() ou notifyAll() pour l'objet, ou qu'un certain temps se soit écoulé.
void wait(long timeout, int nanos)
indique au thread courant d'attendre jusqu'à ce qu'un autre thread invoque la méthode notify() ou notifyAll() pour l'objet, ou que plusieurs autres threads interrompent le thread courant, ou qu'un certain temps se soit écoulé.

39.17 / La classe Package

Les objets Package contiennent les informations de version à propos de l'implémentation et de la spécification d'un paquetage (package) Java.

Ces informations sont récupérées et rendues disponibles par l'instance de la classe ClassLoader qui a chargée les classes. Typiquement, elles sont stockées dans la déclaration qui est distribuée avec les classes.

Les méthodes
String getImplementationTitle()
retourne le titre du paquetage.
String getImplementationVendor()
retourne le nom de l'organisation, du vendeur ou de la compagnie qui a fournit l'implémentation.
String getImplementationVersion()
retourne la version de l'implémentation.
String getName()
retourne le nom du paquetage.
static Package getPackage(String name)
trouve un paquetage par l'intermédiaire d'un nom dans l'instance de classe ClassLoader du demandeur.
static Package[] getPackages()
obtient les paquetages courants connus pour l'instance de la classe ClassLoader du demandeur.
String getSpecificationTitle()
retourne le titre de la spécification que le paquetage implémente.
String getSpecificationVendor()
retourne le nom de l'organisation, du vendeur, ou de la compagnie qui possèdent et maintiennent la spécification des classes qui implément le paquetage.
String getSpecificationVersion()
retourne le numéro de version de la spécification que le paquetage implémente.
int hashCode()
retourne le hash code calculé à partir du nom de paquetage.
boolean isCompatibleWith(String desired)
compare la version de spécification du paquetage avec une version désirée.
boolean isSealed()
retourne true si le paquetage est scellé.
boolean isSealed(URL url)
retourne true si le paquetage est scellé en respectant l'adresse URL du code source spécifiée.
String toString()
retourne une chaîne de caractères représentant le paquetage.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass,
notify, notifyAll, wait, wait, wait

39.18 / La classe Process

Les méthodes Runtime.exec créent un processus natif et retourne une instance d'une sous-classe de Process qui peut être utilisée pour contrôler le processus et obtenir des informations à son propos.

La classe Process fournit des méthodes pour l'entrée d'exécution depuis le processus, la sortie d'exécution vers le processus, attendant que le processus s'achève, vérifiant le statut de sortie du processus et détruisant le processus.

Les constructeurs
Process()
construit un nouvelle instance de la classe Process.

Les méthodes
abstract void destroy()
détruit les sous-processus.
abstract int exitValue()
retourne la valeur de sortie pour le sous-processus.
abstract InputStream getErrorStream()
obtient le flux d'erreur du sous-processus.
abstract InputStream getInputStream()
obtient le flux d'entrée du sous-processus.
abstract OutputStream getOutputStream()
obtient le flux de sortie du sous-processus.
abstract int waitFor()
indique au thread courant d'attendre, si nécessaire jusqu'à ce que le processus représenté par l'objet Process soit terminé.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.19 / La classe Runtime

Chaque application Java a une unique instance de la classe Runtime qui permet l'application à interfacer avec l'environnement dans l'application est exécutée. L'exécution courante peut être obtenue à partir de la méthode getRuntime.

Une application en peut créer ses propres instances de la classe Runtime.

Les méthodes
void addShutdownHook(Thread hook)
enregistre un nouvel incident d'arrêt de la Machine Virtuelle Java (JVM).
int availableProcessors()
retourne le nombre de processeurs disponibles pour la JVM.
Process exec(String command)
exécute une commande dans un processus séparé.
Process exec(String[] cmdarray)
éxécute une commande et des arguments dans un processus séparé.
Process exec(String[] cmdarray, String[] envp)
éxécute une commande et des arguments dans un processus séparé avec l'environnement spécifié.
Process exec(String[] cmdarray, String[] envp, File dir)
éxécute une commande et des arguments dans un processus séparé avec l'environnement spécifié et un répertoire de travail.
Process exec(String cmd, String[] envp)
éxécute une commande dans un processus séparé avec l'environnement spécifié.
Process exec(String command, String[] envp, File dir)
éxécute une commande dans un processus séparé avec l'environnement spécifié et un répertoire de travail.
void exit(int status)
termine l'exécution courante de la JVM en initiant sa séquence d'arrêt.
long freeMemory()
retourne la quantité de mémoire libre dans la JVM.
void gc()
lance le Garbage Collector.
InputStream getLocalizedInputStream(InputStream in)
Dépréciée. Voir les classes InputStreamReader et BufferedReader.
OutputStream getLocalizedOutputStream(OutputStream out)
Dépréciée. Voir les classes OutputStreamWriter, BufferedWriter, et PrintWriter.
static Runtime getRuntime()
retourne l'objet Runtime associé à l'application java courante.
void halt(int status)
force le terme de l'exécution courante de la JVM.
void load(String filename)
charge le nom de fichier spécifié comme une librairie dynamique.
void loadLibrary(String libname)
charge la librairie dynamique par l'intermadiaire de son nom.
long maxMemory()
retourne la quantité maximum de mémoire que la JVM tente d'utiliser.
boolean removeShutdownHook(Thread hook)
enlève les incidents d'arrêt de la JVM, enregistrés précédemment.
void runFinalization()
lance les méthodes de finalisation de n'importe quel objet pendant une opération de finalisation.
static void runFinalizersOnExit(boolean value)
Dépréciée. provoque un comportement érratique et des blocages.
long totalMemory()
retourne la quantité de mémoire total dans la JVM.
void traceInstructions(boolean on)
active ou désactive le traçage d'instructions.
void traceMethodCalls(boolean on)
active ou désactive le traçage d'appels de méthode.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.20 / La classe RuntimePermission

La classe RuntimePermission est utilisée pour les permissions d'exécution. Une classe de ce type contient un nom également connue sous le nom de nom cible, mais aucune liste d'actions, vous possédez ou ne possédez pas la permission nommée.

Le nom cible est le nom de la permission d'exécution. Le convention de nommage suit la convention de nommage des propriétés hiérarchiques. C'est-à-dire, qu'un astérisque peut apparaître à la fin du nom en suivant un point ou être seul pour remplacer un nom ou un groupe de noms (nomCible.* ou *).

Les permissions
createClassLoader
création d'une instance de ClassLoader.
getClassLoader
récupération d'une instance de ClassLoader.
setContextClassLoader
détermination du contexte d'une instance de ClassLoader utilisée par un thread.
setSecurityManager
détermination de l'instance de classe SecurityManager.
createSecurityManager
création d'une instance de SecurityManager.
exitVM
Arrêt de la Machine Virtuelle Java.
shutdownHooks
Enregistrement et annulation des incidents d'arrêt de la JVM.
setIO
Détermination de System.out, System.in et System.err.
modifyThread
Modification des threads à l'image des appels des méthodes de la classe Thread : stop, suspend, resume, setPriority, et setName.
stopThread
arrêt des threads via des appels de la méthode stop de la classe Thread.
modifyThreadGroup
Modification des groupes de threads à l'image des appels des méthodes de la classe ThreadGroup : destroy, getParent, resume, setDaemon, setMaxPriority, stop, et suspend.
getProtectionDomain
Récupération de l'objet ProtectionDomain pour une classe.
readFileDescriptor
Lecture de descripteurs de fichier.
writeFileDescriptor
Ecriture de descripteurs de fichier.
loadLibrary.{library name}
Liaison dynamique de la librairie spécifiée.
accessClassInPackage.{package name}
Accès au paquetage spécifée par l'intermédiaire de la méthode ClassLoader.loadClass, lorsque la classe chargeur appelle la méthode SecurityManager.checkPackageAccess.
defineClassInPackage.{package name}
Définition de classes dans le paquetage spécifié, par l'intermédiaire de la méthode ClassLoader.defineClass lorsque la classe chargeur appelle la méthode SecurityManager.checkPackageDefinition.
accessDeclaredMembers
Accès aux membres déclarés d'une classe.
queuePrintJob
Initiation d'une requête de travail d'impression.

Les constructeurs
RuntimePermission(String name)
crée un nouvel objet RuntimePermission avec le nom spécifié.
RuntimePermission(String name, String actions)
crée un nouvel objet RuntimePermission avec le nom spécifié.

Les méthodes
Les méthodes héritées de la classe java.security.BasicPermission
equals, getActions, hashCode, implies, newPermissionCollection
Les méthodes héritées de la classe java.security.Permission
checkGuard, getName, toString
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass,
notify, notifyAll, wait, wait, wait

39.21 / La classe SecurityManager

Le gestonnaire de sécurité est une classe qui permet aux applications d'implémenter une politique de sécurité.

Elle autorise une application à déterminer avant l'exécution d'une possible opération dangereuse ou sensible,que l'opération est, si elle a été tentée dans un contexte de sécurité, d'autoriser l'opération à être exécutée. L'application peut permettre ou interdire l'opération.

Les champs
protected boolean inCheck
Dépréciée. Ce type de vérification de permission n'est pas recommandé. Il est plutôt recommandé de faire appel à checkPermission.

Les constructeurs
SecurityManager()
construit une nouvelle instance de la classe SecurityManager.

Les méthodes
void checkAccept(String host, int port)
lance une exception SecurityException si le thread appelant n'est pas permis d'accepter une connexion par socket à partir de l'hôte spécifié et du numéro de port.
void checkAccess(Thread t)
lance une exception SecurityException si le thread appelant n'est pas autorisé à modifier l'argument du thread.
void checkAccess(ThreadGroup g)
lance une exception SecurityException si le thread appelant n'est pas autorisé à modifier l'argument de groupe de thread.
void checkAwtEventQueueAccess()
lance une exception SecurityException si le thread appelant n'est pas autorisé à accéder à la file d'attente d'événement AWT.
void checkConnect(String host, int port)
lance une exception SecurityException si le thread appelant n'est pas autorisé à ouvrir une connexion par socket vers l'hôte et le numéro de port spécifiés.
void checkConnect(String host, int port, Object context)
lance une exception SecurityException si le contexte de sécurité n'est pas autorisé à ouvrir une connexion par socket vers l'hôte et le numéro de port spécifiés.
void checkCreateClassLoader()
lance une exception SecurityException si le thread appelant n'est pas autorisé à créer une nouvelle classe chargeur.
void checkDelete(String file)
lance une exception SecurityException si le thread appelant n'est pas autorisé à supprimer le fichier spécifié.
void checkExec(String cmd)
lance une exception SecurityException si le thread appelant n'est pas autorisé à créer un sous-processus.
void checkExit(int status)
lance une exception SecurityException si le thread appelant n'est pas autorisé à indiquer à la JVM d'arrêter avec le code de statut spécifié.
void checkLink(String lib)
lance une exception SecurityException si le thread appelant n'est pas autorisé à lier dynamiquement le code de bibliothèque spécifié par le fichier argument de type String.
void checkListen(int port)
lance une exception SecurityException si le thread appelant n'est pas autorisé à attendre pour une requête de connexion sur le numéro de port local spécifié.
void checkMemberAccess(Class clazz, int which)
lance une exception SecurityException si le thread appelant n'est pas autorisé à accéder aux membres.
void checkMulticast(InetAddress maddr)
lance une exception SecurityException si le thread appelant n'est pas autoriser à utiliser (join/leave/send/receive) la multi-disitribution (multicast) IP.
void checkMulticast(InetAddress maddr, byte ttl)
Dépréciée. Voir checkPermission(java.security.Permission).
void checkPackageAccess(String pkg)
lance une exception SecurityException si le thread appelant n'est pas autorisé à accéder au paquetage spécifié par l'argument.
void checkPackageDefinition(String pkg)
lance une exception SecurityException si le thread appelant n'est pas autorisé à définir des classes dans le paquetage spécifié par l'argument.
void checkPermission(Permission perm)
lance une SecurityException si l'accès requis, spécifié par la permission donnée, n'est pas permis sur la base de la politique courante de sécurité.
void checkPermission(Permission perm, Object context)
lance une exception SecurityException si le contexte de sécurité a un accès refusé vers la ressource spécifiée par la permission donnée.
void checkPrintJobAccess()
lance une exception SecurityException si le thread appelant n'est pas autorisé à initier une requête de travail d'impression.
void checkPropertiesAccess()
lance une exception SecurityException si le thread appelant n'est pas autorisé à accéder ou à modifier les propriétés systèmes.
void checkPropertyAccess(String key)
lance une exception SecurityException si le thread appelant n'est pas autorisés à accéder la propriété système avec le nom spécifié.
void checkRead(FileDescriptor fd)
lance une exception SecurityException si le thread appelant n'est pas autorisé à lire à partir du descripteur de fichier spécifié.
void checkRead(String file)
lance une exception SecurityException si le thread appelant n'est pas autorisé à lire le fichier spécifié par l'argument de type String.
void checkRead(String file, Object context)
lance une exception SecurityException si le contexte de sécurité spécifié n'est pas autorisé à lire le fichier spécifié par l'argument de type String.
void checkSecurityAccess(String target)
détermine si la permission avec le nom cible spécifié devrait être alloué ou refusé.
void checkSetFactory()
lance une exception SecurityException si le thread appelant n'est pas autorisé à déterminer la fabrication de socket utilisée par l'objet ServerSocket ou Socket, ou la fabrique de gestionnaire de flux utilisé par l'objet URL.
void checkSystemClipboardAccess()
lance une exception SecurityException si le thread appelant n'est pas autorisé à accéder au presse-papier système.
boolean checkTopLevelWindow(Object window)
retourne false si le thread appelant n'est pas fiable pour élever la fenêtre de niveau supérieur indiqué par l'argument window.
void checkWrite(FileDescriptor fd)
lance une exception SecurityException si le thread appelant n'est pas autorisé à écrire le descripteur de fichier spécifié.
void checkWrite(String file)
lance une exception SecurityException si le thread appelant n'est pas autorisé à écrire le fichier spécifié par l'argument de type String.
protected int classDepth(String name)
Dépréciée. Voir checkPermission.
protected int classLoaderDepth()
Dépréciée. Voir checkPermission.
protected ClassLoader currentClassLoader()
Dépréciée. Voir checkPermission.
protected Class currentLoadedClass()
Dépréciée. Voir checkPermission.
protected Class[] getClassContext()
retourne la pile d'exécution courante dans un tableau de classes.
boolean getInCheck()
Dépréciée. Voir checkPermission.
Object getSecurityContext()
crée un objet qui encapsule l'environnement d'exécution courante.
ThreadGroup getThreadGroup()
retourne le groupe de thread à l'intérieur duquel est instancié n'importe quel nouveau thread, créé au moment ou celui-ci a été appelé.
protected boolean inClass(String name)
Dépréciée. Voir checkPermission.
protected boolean inClassLoader()
Dépréciée. Voir checkPermission.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.22 / La classe Short

La classe wrapper Short englobe une valeur de type primitif short dans un objet. Un objet de type Short contient un seul champ, lequel est de type primitif short.

Les champs
static short MAX_VALUE
Ce champ représente une constante contenant la valeur maximum, soit une valeur de type short égale à 215-1.
static short MIN_VALUE
Ce champ représente un constante contenant la valeur minimum, soit une valeur de type short égale à -215.
static Class TYPE
Ce champ représente l'objet Short correspondant à la valeur primitive de type short.

Les constructeurs
Short(short value)
alloue un objet Short que représente la valeur de type primitif short.
Short(String s)
alloue un objet Short par l'intermédiaire d'une chaîne de caractères représentant une valeur de type primitif short.

Les méthodes
byte byteValue()
retourne la valeur de l'objet Short comme un type primitif byte.
int compareTo(Short anotherShort)
compare numériquement deux objets Short.
int compareTo(Object o)
compare l'objet Short à un autre objet.
static Short decode(String nm)
décode un objet String à l'intérieur d'un objet Short.
double doubleValue()
retourne la valeur de l'objet Short comme un type primitif double.
boolean equals(Object obj)
compare l'objet Short par rapport à un autre objet passé en argument.
float floatValue()
retourne la valeur de l'objet Short comme un type primitif float.
int hashCode()
retourne un hash code pour l'objet Short.
int intValue()
retourne la valeur de l'objet Short comme un type primitif int.
long longValue()
retourne la valeur de l'objet Short comme un type primitif long.
static short parseShort(String s)
analyse l'argument String comme une valeur short décimale signée.
static short parseShort(String s, int radix)
analyse l'argument String comme une valeur short signée dans la racine spécifiée par le second argument.
short shortValue()
retourne la valeur de l'objet Short comme un type primitif short.
String toString()
retourne un objet String représentant la valeur de l'objet Short.
static String toString(short s)
retourne un nouvel objet String représentant la valeur short spécifiée.
static Short valueOf(String s)
retourne un objet Short contenant la valeur donnée par la chaîne de caractères passée en argument.
static Short valueOf(String s, int radix)
retourne un objet Short contenant la valeur extraite à partir de la chaîne de caractères et de la racine.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.23 / La classe StackTraceElement

Un élément dans une pile de traces, comme retourné par la méthode Throwable.getStackTrace(). représente un unique cadre de traces.

Tous les cadres de traces à l'exception de celle au-dessus de la pile, représente une méthode d'invocation. Le cadre au-dessus de la pile représente le point d'exécution auquel la trace de pile était générée. Typiquement, ceci est le point auquel le lancement d'exception correspondant à la trace de pile était créé.

Les méthodes
boolean equals(Object obj)
retourne true si l'objet spécifié est une autre instance de la classe StackTraceElement représentant la même point d'exécution que cette instance.
String getClassName()
retourne le nom qualidfié complet de la classe contenant le point d'exécution représenté par l''objet StackTraceElement.
String getFileName()
retourne le nom du fichier source contenant le point d'exécution représenté par l'objet StackTraceElement.
int getLineNumber()
retourne le numéro de ligne de la source contenant le point d'exécution représenté par l'objet StackTraceElement.
String getMethodName()
retourne le nom de la méthode contenant le point d'exécution représenté par l'objet StackTraceElement.
int hashCode()
retourne la valeur hash code pour l'objet StackTraceElement.
boolean isNativeMethod()
retourne true si la méthode contenant le point d'exécution représenté par l'objet StackTraceElement, est une méthode native.
String toString()
retourne une représentation sous la forme d'un objet String de l'objet StackTraceElement.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.24 / La classe StrictMath

La classe StrictMath contient des méthodes pour exécuter des opérations numériques de base telles que l'exponentiel, le logarithme, la racine carrée, les fonctions trigonométriques, les minimums et les maximums.

Contrairement à plusieurs méthodes numériques de la classe StrictMath, toutes les implémentations des fontions équivalentes de la classe Math ne sont pas définies pour retourner des résultats identiques bit à bit. Ce relâchement permet d'exécuter d'une meilleure façon les implémentations ou la reprodutibilité stricte n'est pas requise.

Les champs
static double E
Ce champ représente la valeur double approchée de e, soit la base du logarithme naturel.
static double PI
Ce champ représente la valeur double approchée de PI, soit le ratio de la circonférence d'un cercle par rapport a son diamètre.

Les méthodes
static double abs(double a)
retourne la valeur absolue d'une valeur de type double.
static float abs(float a)
retourne la valeur absolue d'une valeur de type float.
static int abs(int a)
retourne la valeur absolue d'une valeur int.
static long abs(long a)
retourne la valeur absolue d'une valeur long.
static double acos(double a)
retourne l'arc-cosinus d'un angle, dans l'intervalle 0.0 jusqu'à PI.
static double asin(double a)
retourne l'arc-sinus d'un angle dans l'intervalle de -PI/2 jusqu'à PI/2.
static double atan(double a)
retourne l'arc-tangente d'un angle dans l'intervalle de -PI/2 jusqu'à PI/2.
static double atan2(double y, double x)
convertit des coordonnées rectangulaires (x, y) en polaires (r, theta).
static double ceil(double a)
retourne la plus petite valeur double (prôche de l'infini négatif : -infinity) qui n'est pas plus petit que l'argument et est égal à un entier mathématique.
static double cos(double a)
retourne le cosinus trigonométrique d'un angle.
static double exp(double a)
retourne le nombre d'Euler e élevé à la puissance d'une valeur double.
static double floor(double a)
retourne la plus grande valeur double (prôche de l'infini positif : infinity) qui n'est pas plus grand que l'argument et est égal à un entier mathématique.
static double IEEEremainder(double f1, double f2)
calcul l'opération restante sur deux arguments comme prescrit dans le standard IEEE 754.
static double log(double a)
retourne le logarithme naturel (base e) d'une valeur double.
static double max(double a, double b)
retourne la plus grande des deux valeurs de type double.
static float max(float a, float b)
retourne la plus grande des deux valeurs de type float.
static int max(int a, int b)
retourne la plus grande des deux valeurs de type int.
static long max(long a, long b)
retourne la plus grande des deux valeurs de type long.
static double min(double a, double b)
retourne la plus petite des deux valeurs de type double.
static float min(float a, float b)
retourne la plus petite des deux valeurs de type float.
static int min(int a, int b)
retourne la plus petite des deux valeurs de type int.
static long min(long a, long b)
retourne la plus petite des deux valeurs de type long.
static double pow(double a, double b)
retourne la valeur d'un double élevé à la puissance représentée par le second argument (ab).
static double random()
retourne une valeur double avec un signe positif, plus grand ou égal à 0.0 et plus petit que 1.0.
static double rint(double a)
retourne la valeur double qui est la plus prôche de la valeur de l'argument et est égal à un entier mathématique.
static long round(double a)
retourne la plus prôche valeur de type long de l'argument.
static int round(float a)
retourne la plus prôche valeur de type int de l'argument.
static double sin(double a)
retourne le sinus trigonométrique d'un angle.
static double sqrt(double a)
retourne la valeur positive arrondie de la racine carrée d'une valeur de type double.
static double tan(double a)
retourne la tangente trigonométrique d'un angle.
static double toDegrees(double angrad)
convertit approximativement un angle mesuré en radians en degrés.
static double toRadians(double angdeg)
convertit approximativement un angle mesuré en degrés en radians.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.25 / La classe String

La classe String représente une séquence de caractères. Tous les littéraux de type String dans un programme Java sont implémentées comme des instances de cette classe.

String chaine = "Une chaîne de caractères quelconque !";

es chaînes de caractères sont des constantes, leur valeur ne peut être modifiée après leur création. La classe StringBuffer supporte des modifications directement dans l'objet contenant une chaîne de caractères. Lorsqu'une chaîne de caractères de type String subit une modification de valeur, en réalité, un second objet est créé contenant la chaîne d'origine modifiée.

String part1 = "Quand aurons-nous ";
part1 = part1 + "une réelle démocratie ?";

Cet exemple montre qu'un premier objet String est créé, auquel on rajoute une seconde chaîne de caractères. En mémoire, est créé un premier objet référencé par la variable part1. Un second objet composé du premier concaténé à une autre chaîne de caractères est également créé en mémoire, provoquant la suppression de la référence (contenue dans la variable part1) vers le premier objet en la changeant par une référence vers le second objet.

Les champs
static Comparator CASE_INSENSITIVE_ORDER
Ce champ représente un comparateur qui ordonne les objets String selon compareToIgnoreCase.

Les constructeurs
String()
initialise un nouvel objet avec une chaîne de caractères vide.
String(byte[] bytes)
construit un nouvel objet String en décodant le tableau d'octets à partir d'un jeu de caractères par défaut de la plateforme.
String(byte[] ascii, int hibyte)
Dépréciée.
String(byte[] bytes, int offset, int length)
construit un nouvel objet String en décodant le tableau d'octets à partir d'un intervalle spécifié par une position et une longueur.
String(byte[] ascii, int hibyte, int offset, int count)
Dépréciée.
String(byte[] bytes, int offset, int length, String charsetName)
construit un nouvel objet String en décodant le tableau d'octets à partir d'un certaine intervalle et d'un jeu de caractères spécifié.
String(byte[] bytes, String charsetName)
construit un nouvel objet String en décodant le tableau d'octets à partir d'un jeu de caractères spécifié.
String(char[] value)
alloue un nouvel objet String contenant les caractères provenant du tableau.
String(char[] value, int offset, int count)
alloue un nouvel objet String contenant les caractères provenant du tableau et à partir d'une position spécifiée et jusqu'à une certaine longueur.
String(String original)
initialise un nouvel objet String avec une chaîne de caractères passée en argument.
String(StringBuffer buffer)
alloue un nouvel objet String contenant la séquence de caractères de l'objet StringBuffer passé en argument.

Les méthodes
char charAt(int index)
retourne la caractère positionné à l'index spécifié.
int compareTo(Object o)
compare l'objet String à un autre objet.
int compareTo(String anotherString)
compare deux chaînes lexicographiquement.
int compareToIgnoreCase(String str)
compare deux chaînes lexicographiquement en ignorant la casse de caractères.
String concat(String str)
concatène l'objet String à une autre chaîne de caractères.
boolean contentEquals(StringBuffer sb)
retourne true si et seulement si l'objet String représente la même séquence de caractères comme l'objet StringBuffer spécifié.
static String copyValueOf(char[] data)
retourne un objet String qui représente la séquence de caractères dans le tableau spécifié.
static String copyValueOf(char[] data, int offset, int count)
retourne un nouvel objet String qui représente la séquence de caractères dans le tableau spécifié.
boolean endsWith(String suffix)
teste si la fin de l'objet String correspond au suffixe spécifié.
boolean equals(Object anObject)
compare deux chaînes de caractères entre elles.
boolean equalsIgnoreCase(String anotherString)
compare l'objet String à un autre objet de même type en ignorant la casse de caractères.
byte[] getBytes()
encode un objet String à l'intérieur d'un tableau d'octets en utilisant le jeu de caractères par défaut de la plateforme.
void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)
Déprécié. Voir getBytes().
byte[] getBytes(String charsetName)
encode l'objet String à l'intérieur d'une séquence d'octets utilisant le jeu de caractères nommé et stocke le résultat à l'intérieur d'un tableau d'octets.
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
copie des caractères à partir de l'objet String à l'intérieur d'un tableau de caractères de destination en suivant des positions de commencement et de fin sur la source et un index de départ au niveau du tableau.
int hashCode()
retourne un hash code pour l'objet String.
int indexOf(int ch)
retourne l'index à l'intérieur l'objet String de la première occurrence du caractère spécifié.
int indexOf(int ch, int fromIndex)
retourne l'index à l'intérieur l'objet String de la première occurrence du caractère spécifié à partir d'une certaine position.
int indexOf(String str)
retourne l'index à l'intérieur l'objet String de la première occurrence de la sous-chaîne spécifiée.
int indexOf(String str, int fromIndex)
retourne l'index à l'intérieur l'objet String de la première occurrence de la sous-chaîne spécifiée à partir d'une certaine position.
String intern()
retourne une représentation canonique pour l'objet String.
int lastIndexOf(int ch)
retourne l'index à l'intérieur l'objet String de la dernière occurrence du caractère spécifié.
int lastIndexOf(int ch, int fromIndex)
retourne l'index à l'intérieur l'objet String de la dernière occurrence du caractère spécifié à partir d'une certaine position.
int lastIndexOf(String str)
retourne l'index à l'intérieur l'objet String de la dernière occurrence de la sous-chaîne spécifiée.
int lastIndexOf(String str, int fromIndex)
retourne l'index à l'intérieur l'objet String de la dernière occurrence de la sous-chaîne spécifiée à partir d'une certaine position.
int length()
retourne la longueur de l'objet String.
boolean matches(String regex)
indique si l'objet String correspond à l'expression régulière donnée.
boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len)
teste si deux parties de chaînes de caractères, délimitées chacun par une position de démarrage et une certaine longueur, sont égales en ignorant la casse de caractères.
boolean regionMatches(int toffset, String other, int ooffset, int len)
teste si deux parties de chaînes de caractères, délimitées chacun par une position de démarrage et une certaine longueur, sont égales.
String replace(char oldChar, char newChar)
retourne un nouvel objet String résultant du remplacement de toutes les occurrences d'un caractère donnée par un autre caractère.
String replaceAll(String regex, String replacement)
remplace dans une chaîne de caractères, chaque sous-chaîne qui correspondent à l'expression régulière fournie, par une chaîne de caractères de remplacement.
String replaceFirst(String regex, String replacement)
remplace dans un objet String, la première sous-chaîne qui correspond à l'expression régulière fournie, par la chaîne de remplacement.
String[] split(String regex)
découpe une chaîne de caractères autour des correspondances données par l'expression régulière.
String[] split(String regex, int limit)
découpe, selon une certaine limite, une chaîne de caractères autour des correspondances trouvées par l'expression régulière.
boolean startsWith(String prefix)
teste si l'objet String démarre au préfixe spécifié.
boolean startsWith(String prefix, int toffset)
teste si l'objet String démarre au préfixe spécifié jusqu'à une position donnée.
CharSequence subSequence(int beginIndex, int endIndex)
retourne un objet CharSequence qui est une sous-séquence de l'objet String par l'intermédiaire d'un intervalle spécifié.
String substring(int beginIndex)
retourne une nouvelle chaîne de caractères qui est une sous-chaîne de l'objet String par l'intermédiaire d'un intervalle commençant à l'index spécifié jusqu'à la fin.
String substring(int beginIndex, int endIndex)
retourne une nouvelle chaîne de caractères qui est une sous-chaîne de l'objet String par l'intermédiaire d'un intervalle spécifié.
char[] toCharArray()
convertit l'objet String vers un nouveau tableau de caractères.
String toLowerCase()
convertit tous les caractères dans l'objet String en casse minuscule en utilisant les règles de l'objet Locale par défaut.
String toLowerCase(Locale locale)
convertit tous les caractères dans l'objet String en casse minuscule en utilisant les règles de l'objet Locale fourni.
String toString()
retourne une chaîne de caractères issue de l'objet String.
String toUpperCase()
convertit tous les caractères dans l'objet String en casse majuscule en utilisant les règles de l'objet Locale par défaut.
String toUpperCase(Locale locale)
convertit tous les caractères dans l'objet String en casse majuscule en utilisant les règles de l'objet Locale fourni.
String trim()
retourne une copie de l'objet String en supprimant les espaces blancs avant et après la chaîne de caractères.
static String valueOf(boolean b)
retourne un représentation sous forme d'un objet String de la valeur de type booléen passée en argument.
static String valueOf(char c)
retourne un représentation sous forme d'un objet String de la valeur de type char passée en argument.
static String valueOf(char[] data)
retourne un représentation sous forme d'un objet String d'un tableau de caractères passé en argument.
static String valueOf(char[] data, int offset, int count)
retourne un représentation sous forme d'un objet String d'un tableau de caractères avec une position et un nombre de cellules, passés en argument.
static String valueOf(double d)
retourne un représentation sous forme d'un objet String de la valeur de type double passée en argument.
static String valueOf(float f)
retourne un représentation sous forme d'un objet String de la valeur de type float passée en argument.
static String valueOf(int i)
retourne un représentation sous forme d'un objet String de la valeur de type int passée en argument.
static String valueOf(long l)
retourne un représentation sous forme d'un objet String de la valeur de type long passée en argument.
static String valueOf(Object obj)
retourne un représentation sous forme d'un objet String de l'objet passé en argument.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

39.26 / La classe StringBuffer

La classe StringBuffer implémente une séquence de caractères mutable. Un objet StringBuffer est comme un objet String, mais peut être modifié dynamiquement.

StringBuffer chaine = new StringBuffer("Une chaîne de caractères...");

La longueur et le contenu de l'objet StringBuffer peut être changé par l'intermédiaire de plusieurs méthodes spécialisées. Ainsi, il est possible d'effectuer un ajout, une suppression, une insertion d'un ou plusieurs caractères à l'objet StringBuffer initial.

chaine = chaine.replace(chaine.indexOf("..."), 
                             chaine.length(), 
                             " quelconque modifiée !");
Les constructeurs
StringBuffer()
construit un objet StringBuffer sans caractères et une capacité initiale de 16 caractères.
StringBuffer(int length)
construit un objet StringBuffer sans caractères et une capacité initiale spécifiée par un certaine longueur fournie en argument.
StringBuffer(String str)
construit un objet StringBuffer dont le contenu est une copie de la chaîne de caractères passée en argument.

Les méthodes
StringBuffer append(boolean b)
ajoute à l'objet StringBuffer la représentation d'une chaîne de caractères de l'argument booléen.
StringBuffer append(char c)
ajoute à l'objet StringBuffer la représentation de l'argument de type char.
StringBuffer append(char[] str)
ajoute à l'objet StringBuffer la représentation d'un tableau de caractères.
StringBuffer append(char[] str, int offset, int len)
ajoute à l'objet StringBuffer la représentation d'une partie d'un tableau de caractères, délimité par une position et une longueur.
StringBuffer append(double d)
ajoute à l'objet StringBuffer la représentation d'une valeur de type double.
StringBuffer append(float f)
ajoute à l'objet StringBuffer la représentation d'une valeur de type float.
StringBuffer append(int i)
ajoute à l'objet StringBuffer la représentation d'une valeur de type int.
StringBuffer append(long l)
ajoute à l'objet StringBuffer la représentation d'une valeur de type long.
StringBuffer append(Object obj)
ajoute à l'objet StringBuffer la représentation d'un objet.
StringBuffer append(String str)
ajoute à l'objet StringBuffer une chaîne de caractères.
StringBuffer append(StringBuffer sb)
ajoute à l'objet StringBuffer un autre objet de même type.
int capacity()
retourne la capacité courante de l'objet StringBuffer.
char charAt(int index)
retourne le caractère positionné à l'index spécifié dans l'objet StringBuffer.
StringBuffer delete(int start, int end)
supprime les caractères situés dans un intervalle spécifié de l'objet StringBuffer.
StringBuffer deleteCharAt(int index)
supprime le caractère situé à la position spécifiée de l'objet StringBuffer.
void ensureCapacity(int minimumCapacity)
assure que la capacité du tampon est au moins égal au minimum spécifié.
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
Les caractères sont copiés à partir de l'objet StringBuffer vers un tableau de caractères de destination en respectant un intervalle dans la chaîne de caractères source et un certain index dans le tableau.
int indexOf(String str)
retourne l'index à l'intérieur de l'objet StringBuffer de la première occurrence de l'objet String passé en argument.
int indexOf(String str, int fromIndex)
retourne l'index à l'intérieur de l'objet StringBuffer de la première occurrence de l'objet String et à partir d'une certaine position.
StringBuffer insert(int offset, boolean b)
insère dans l'objet StringBuffer la représentation de la valeur de type boolean à une position précisée.
StringBuffer insert(int offset, char c)
insère dans l'objet StringBuffer la représentation de la valeur de type char à une position précisée.
StringBuffer insert(int offset, char[] str)
insère dans l'objet StringBuffer la représentation d'un tableau de caractères à une position précisée.
StringBuffer insert(int index, char[] str, int offset, int len)
insère dans l'objet StringBuffer la représentation d'une partie d'un tableau de caractères à une position dans la chaîne de caractères et un intervalle dans le tableau.
StringBuffer insert(int offset, double d)
insère dans l'objet StringBuffer la représentation de la valeur de type double à une position précisée.
StringBuffer insert(int offset, float f)
insère dans l'objet StringBuffer la représentation de la valeur de type float à une position précisée.
StringBuffer insert(int offset, int i)
insère dans l'objet StringBuffer la représentation de la valeur de type int à une position précisée.
StringBuffer insert(int offset, long l)
insère dans l'objet StringBuffer la représentation de la valeur de type long à une position précisée.
StringBuffer insert(int offset, Object obj)
insère dans l'objet StringBuffer la représentation d'un objet à une position précisée.
StringBuffer insert(int offset, String str)
insère dans l'objet StringBuffer un objet de type String à une position précisée.
int lastIndexOf(String str)
retourne la position de la première occurrence de la chaîne de caractères passée en argument trouvée à partir de la fin de l'objet String.
int lastIndexOf(String str, int fromIndex)
retourne la position de la première occurrence de la chaîne de caractères passée en argument trouvée à partir d'un certain index de l'objet String.
int length()
retourne la longueur en nombre de caractères de l'objet StringBuffer.
StringBuffer replace(int start, int end, String str)
remplace les caractères dans une sous-chaîne de l'objet StringBuffer, délimité par un certain intervalle spécifié, par les caractères d'un objet String passé en argument.
StringBuffer reverse()
remplace le contenu initial de l'objet StringBuffer par le même contenu inversé.
void setCharAt(int index, char ch)
remplace le caractère positionné à l'index fourni par le caractère passé en argument dans l'objet StringBuffer.
void setLength(int newLength)
fixe la longueur de l'objet StringBuffer.
CharSequence subSequence(int start, int end)
retourne une nouvelle séquence de caractères qui est déterminé par un intervalle de l'objet StringBuffer.
String substring(int start)
retourne un nouvel objet String qui contient une sous-chaîne de l'objet StringBuffer, délimité par une position de départ jusqu'à la fin de l'objet précité.
String substring(int start, int end)
retourne un nouvel objet String qui contient une sous-chaîne de l'objet StringBuffer, déterminée par un intervalle spécifié.
String toString()
convertit la représentation d'un objet StringBuffer vers un objet String.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

39.27 / La classe System

La classe System contient plusieurs champs et méthodes utilitaires. Cette classe ne peut être instanciée.

Les champs
static PrintStream err
Ce champ représente le flux d'erreur standard.
static InputStream in
Ce champ représente le flux d'entrée standard.
static PrintStream out
Ce champ représente le flux de sortie standard.

Les méthodes
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
copie une partie d'un tableau source, délimitée par une position et jusqu'à une certaine longueur, dans un autre tableau de destination.
static long currentTimeMillis()
retourne le temps courant en millisecondes.
static void exit(int status)
termine l'exécution courante de la JVM (Java Virtual Machine).
static void gc()
exécute le Garbage Collector.
static String getenv(String name)
Dépréciée. Voir java.lang.System.getProperty et getTypeName.
static Properties getProperties()
détermine les propriétés systèmes courantes.
static String getProperty(String key)
obtient la propriété système indiquée par la clé spécifiée.
static String getProperty(String key, String def)
obtient la propriété système indiquée par la clé spécifiée et une certaine définition.
static SecurityManager getSecurityManager()
obtient l'interface de sécurité du système.
static int identityHashCode(Object x)
retourne le même hash code pour l'objet donné comme devrait l'effectuer la méthode hashCode() par défaut, qu'il en soit ainsi ou non, la classe de l'objet donné surcharge la méthode hashcode() whether or not the given object's class overrides hashCode().
static void load(String filename)
charge un fichier code avec le nom de fichier spécifié à partir du système de fichier local à l'image d'une bibliothèque dynamique.
static void loadLibrary(String libname)
charge la bibliothèque système spécifiée précisée par l'argument libname.
static String mapLibraryName(String libname)
décrit un nom de bibliothèque à l'intérieur chaîne de caractères spécifique à la plateforme repréentant une bibliothèque native.
static void runFinalization()
exécute les méthodes de finalisation de n'importe quel objet pendant l'opération de finalisation.
static void runFinalizersOnExit(boolean value)
Dépréciée. provoque un comportement erratique et de blocage.
static void setErr(PrintStream err)
réassigne le flux de sortie d'erreur standard.
static void setIn(InputStream in)
réassigne le flux d'entrée standard.
static void setOut(PrintStream out)
réassigne le flux de sortie standard.
static void setProperties(Properties props)
fixe les propriétés systèmes aux propriétés désignées par l'argument.
static String setProperty(String key, String value)
fixe la propriété système indiquée par la clé passée en argument.
static void setSecurityManager(SecurityManager s)
fixe la sécurité de l'objet System par l'argument spécifié.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.28 / La classe Thread

Un thread est l'une des unités d'exécution que peut posséder un programme Java. La Machine Virtuelle Java permet à une application d'exécuter plusieurs threads simultanément.

Chaque thread a une priorité. Les objets Thread avec une priorité élevée sont exécuté avant les threads de basses priorités. Chaque thread peut ou ne peut pas être marqué comme un démon. Lorsque le code d'exécution dans quelques threads crée un nouvel objet Thread, le nouveau thread a sa priorité initialement égale à la priorité créant et est un trhead démon si et seulement si le thread créant et un démon.

Lorsqu'une JVM démarre, il y a un unique thread non-démon (lequel typiquement appele le méthode main de quelques classes désignées). La JVM continue à exécuter les threads jusqu'à l'un des événements suivants :

Il y a deux façons de créer un nouveau thread d'exécution. La première est de déclarer une classe qui est une sous-classe d'un objet Thread. Cette sous-classe doit surcharger la méthode run de la classe Thread. Une instance de la sous-classe peut alors être allouée et démarrée.

Les champs
static int MAX_PRIORITY
Ce champ représente la priorité maximum qu'un thread peut posséder.
static int MIN_PRIORITY
Ce champ représente la priorité minimum qu'un thread peut posséder.
static int NORM_PRIORITY
Ce champ représente la priorité par défaut qui est assignée à un thread.

Les constructeurs
Thread()
alloue un nouvel objet Thread.
Thread(Runnable target)
alloue un nouvel objet Thread en lui fournissant une cible Runnable.
Thread(Runnable target, String name)
alloue un nouvel objet Thread en lui affectant une cible Runnable et un nom.
Thread(String name)
alloue un nouvel objet Thread en lui affectant un nom.
Thread(ThreadGroup group, Runnable target)
alloue un nouvel objet Thread en lui affectant un groupe de threads et une cible Runnable.
Thread(ThreadGroup group, Runnable target, String name)
alloue un nouvel objet Thread à l'aide d'un groupe de threads, d'un objet cible Runnable et de son nom.
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
alloue un nouvel objet Thread à l'aide d'un groupe de threads, d'un objet cible Runnable, de son nom et d'une taille de pile.
Thread(ThreadGroup group, String name)
alloue un nouvel objet Thread.

Les méthodes
static int activeCount()
retourne le nombre de threads actifs dans le groupe de threads du thread courant.
void checkAccess()
détermine si l'objet Thread courant possède la permission de modifier le thread.
int countStackFrames()
Dépréciée. Voir suspend().
static Thread currentThread()
retourne une référence vers l'objet Thread d'exécution courant.
void destroy()
détruit l'objet Thread, sans aucun nettoyage.
static void dumpStack()
imprime une trace de pile de l'objet Thread courant.
static int enumerate(Thread[] tarray)
copie à l'intérieur d'un tableau spécifié chaque thread actif dans le groupe de thread de thread et ses sous-groupes.
ClassLoader getContextClassLoader()
retourne l'objet ClassLoader du contexte pour l'objet Thread.
String getName()
retourne le nom de l'objet Thread.
int getPriority()
retourne la priorité de l'objet Thread.
ThreadGroup getThreadGroup()
retourne le groupe du thread vers lequel l'objet Thread appartient.
static boolean holdsLock(Object obj)
retourne true si et seulement si le thread courant conserve le verrou du moniteur sur l'objet spécifié.
void interrupt()
interrompt l'objet Thread.
static boolean interrupted()
teste si l'objet Thread courant a été interrompu.
boolean isAlive()
teste si l'objet Thread est actif.
boolean isDaemon()
teste si l'objet Thread est un thread démon.
boolean isInterrupted()
teste si l'objet Thread a été interrompu.
void join()
attends pour faire mourrir l'objet Thread.
void join(long millis)
attends au maximum quelques millisecondes pour faire mourrir l'objet Thread.
void join(long millis, int nanos)
attends au maximum quelques millisecondes auxquelles s'ajoutent plusieurs nanosecondes pour faire mourrir l'objet Thread.
void resume()
Déprécié. Risque de blocage.
void run()
si le thread était construit en utilisant un objet Runnable séparé , alors la méthode run() de ce dernier est appelée, autrement cette méthode ne fait et ne retourne rien.
void setContextClassLoader(ClassLoader cl)
fixe l'objet ClassLoader du contexte pour le thread courant.
void setDaemon(boolean on)
désigne l'objet Thread comme soit un thread démon (daemon thread), soit un thread utilisateur (user thread).
void setName(String name)
modifie le nom de l'objet Thread au bénéfice du nouveau nom passé en argument.
void setPriority(int newPriority)
modifie la priorité de l'objet Thread.
static void sleep(long millis)
provoque la mise en sommeil de l'objet Thread courant pendant un certain nombre de millisecondes.
static void sleep(long millis, int nanos)
provoque la mise en sommeil de l'objet Thread courant pendant un certain nombre de millisecondes et de nanosecondes.
void start()
provoque le démarage de l'objet Thread, la JVM appelant la méthode run() de ce thread.
void stop()
Déprécié. Risque de blocage.
void stop(Throwable obj)
Déprécié. Risque de blocage.
void suspend()
Déprécié. Risque de blocage.
String toString()
retourne une représentation sous forme d'un objet String de l'objet Thread incluant le nom, la priorité et le groupe du thread.
static void yield()
provoque la mise en pause temporaire de l'objet Thread courant pour permetre l'exécution d'autres threads.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

39.29 / La classe ThreadGroup

Une instance de la classe ThreadGroup représente un jeu de threads. De plus, un groupe de threads peut aussi inclure d'autres objets ThreadGroup. Les groupes de threads forment une arborescence dans laquelle chaque groupe de threads à l'exception du groupe initial posséde un parent.

Un thread est autorisé à accéder aux informations à propos de son objet ThreadGroup parent, mais il ne peut accéder aux informations à propos des parents de son propre groupe en encore moins à n'importe quel autres objets ThreadGroup.

Les constructeurs
ThreadGroup(String name)
crée un nouvel objet ThreadGroup en spécifiant un nom pour l'objet.
ThreadGroup(ThreadGroup parent, String name)
crée un nouvel objet ThreadGroup en spécifiant un groupe de threads parent et un nom pour l'objet.

Les méthodes
int activeCount()
retourne une estimation du nombre de threads actifs dans l'objet ThreadGroup.
int activeGroupCount()
retourne une estimation du nombre de groupes de threads actifs dans l'objet ThreadGroup.
boolean allowThreadSuspension(boolean b)
Dépréciée. Voir suspend().
void checkAccess()
détermine si le thread d'exécution courant possède la permission de modifier l'objet ThreadGroup.
void destroy()
détruit un groupe de threads et tous ses sous-groupes.
int enumerate(Thread[] list)
copie à l'intérieur d'un tableau de threads spécifié chaque sous-groupe actif dans l'objet ThreadGroup.
int enumerate(Thread[] list, boolean recurse)
copie à l'intérieur d'un tableau de threads spécifié chaque sous-groupe actif dans l'objet ThreadGroup. L'argument booléen indique si une énumération récursive de tous les objet ThreadGroup inclus doit être effectuée.
int enumerate(ThreadGroup[] list)
copie à l'intérieur d'un tableau de groupes de threads spécifié chaque sous-groupe actif dans l'objet ThreadGroup.
int enumerate(ThreadGroup[] list, boolean recurse)
copie à l'intérieur d'un tableau de groupes de threads spécifié chaque sous-groupe actif dans l'objet ThreadGroup. L'argument booléen indique si une énumération récursive de tous les objet ThreadGroup inclus doit être effectuée.
int getMaxPriority()
retourne lea priorité maximum de l'objet ThreadGroup.
String getName()
retourne le nom de l'objet ThreadGroup.
ThreadGroup getParent()
retourne le parent de l'objet ThreadGroup.
void interrupt()
interrompt tous les threads dans cet objet ThreadGroup.
boolean isDaemon()
teste si le groupe de threads est un objet ThreadGroup démon.
boolean isDestroyed()
teste si l'objet ThreadGroup a été détruit.
void list()
imprime les informations à propos de l'objet ThreadGroup vers la sortie standard.
boolean parentOf(ThreadGroup g)
teste si l'objet ThreadGroup est soit le groupe de threads passé en argument, soit l'un de ses groupes de threads ancêtres.
void resume()
Dépréciée. Voir Thread.suspend().
void setDaemon(boolean daemon)
modifie le statut de démon de l'objet ThreadGroup.
void setMaxPriority(int pri)
fixe la priorité maximum du groupe de threads.
void stop()
Dépréciée. Voir Thread.stop().
void suspend()
Dépréciée. Voir Thread.suspend().
String toString()
retourne une représentation sous forme d'un objet String de l'objet ThreadGroup.
void uncaughtException(Thread t, Throwable e)
appelé par la JVM lorsqu'un thread dans l'objet ThreadGroup arrête à caude d'une exception insaisissable.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

39.30 / La classe ThreadLocal

La classe ThreadLocal fournit des variables locales au thread. Ces variables diffèrent de leurs homologues existant dans d'autres threads qui sont accédées via de mutateurs ou des accesseurs, ont leurs propres copies initialisées et indépendantes.

Les instances de la classe ThreadLocal possèdent typiquement des champs privés et statiques, qui veulent associer l'état avec un thread, tel qu'un ID utilisateur ou une ID trnasactionnel.

Chaque thread conserve une référence implicite vers sa copie d'une variable local au thread tant que le thread est actif et l'instance de la classe ThreadLocal est accessible, après qu'un thread aille plus loin, toutes ses copies d'instance de ThreadLocal sont soumis au Garbage Collector à moins que d'autres références à ses copies existent.

Les constructeurs
ThreadLocal()
construit un nouvel objet ThreadLocal.

Les méthodes
Object get()
retourne la valeur dans la copie du thread courant de l'objet ThreadLocal.
protected Object initialValue()
retourne la valeur initiale du thread pour l'objet ThreadLocal.
void set(Object value)
fixe la copie du thread courant de l'objet ThreadLocal à la valeur spécifiée.
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

39.31 / La classe Throwable

La classe Throwable est la superclasse de toutes les erreurs et exceptions rencontrées dans le langage de programation Java.

Seulement, les objets qui ont des instances de cette classe ou un de ses sous-classes sont lancés par la Machine Virtuelle Java (JVM) ou peuvent être lancés par l'instruction throw dans un programme. Similairement, seulement cette classe ou une de ses sous-classes peut être le type d'argument dans une clause catch.

Les instances des deux sous-classes, Error et Exception sont conventionnellement utilisées pour indiquer que des situations exceptionnels se sont produites. Typiquement, ces instances sont nouvellement créées dans le contexte de situation exceptionnelle afin d'inclure l'information appropriée telle qu'une donnée de trace de pile.

Les constructeurs
Throwable()
construit un nouvel objet Throwable avec une valeur nulle pour son message d'erreur.
Throwable(String message)
construit un nouvel objet Throwable avec un message d'erreur spécifié.
Throwable(String message, Throwable cause)
construit un nouvel objet Throwable avec un message d'erreur et un autre objet Throwable indiquant sa cause.
Throwable(Throwable cause)
construit un nouvel objet Throwable à partir d'un autre objet Throwable indiquant la cause et le message d'erreur associé.

Les méthodes
Throwable fillInStackTrace()
remplit une trace dans la pile d'exécution.
Throwable getCause()
retourne la cause de l'objet Throwable ou la valeur null si la cause n'existe pas ou est inconnue.
String getLocalizedMessage()
crée une description localisée de l'objet Throwable.
String getMessage()
retourne un objet String représentant un message d'erreur de l'objet Throwable.
StackTraceElement[] getStackTrace()
fournit un accès programmatique à une information de l'objet StackTrace imprimée par la méthode printStackTrace().
Throwable initCause(Throwable cause)
initialise la cause de l'objet Throwable à la valeur spécifiée.
void printStackTrace()
imprime l'objet Throwable et sa trace de retour vers le flux d'erreur standard.
void printStackTrace(PrintStream s)
imprime l'objet Throwable et sa trace de retour vers le flux d'impression spécifié.
void printStackTrace(PrintWriter s)
imprime l'objet Throwable et sa trace de retour vers le flux d'écriture spécifié.
void setStackTrace(StackTraceElement[] stackTrace)
fixe les éléments de la trace de pile qui seraient retournés par la méthode getStackTrace() et imprimé par les méthodes printStackTrace() et apparentées.
String toString()
retourne une courte description de l'objet Throwable.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

39.32 / La classe Void

La classe Void ne peut être instanciée. Elle permet de conserver une référence à la classe Object représentant le mot clé Java void.

Les champs
static Class TYPE
Ce champ représente le type primitif void.

Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40 / Le paquetage java.io

Le paquetage java.io fournit le système d'entrée et de sortie par l'intermédiaire des flux de données, des outils permettant la sérialisation et d'autres pour gérer le système de fichiers.

Les interfaces
DataInput L'interface DataInput fournit pour les octets lus à partir d'un flux binaire et reconstruisant à partir de leurs données dans n'importe quel des types primitifs Java.
DataOutput L'interface DataOutput fournit pour la conversion de données de n'importe lequel des types primitifs Java vers une série de byte et écrivant ces octets vers un flux binaire.
Externalizable Seulement les identités de classe d'une ainstance de la classe Externalizable est écrit dans un flux de sérialisation et est le responsable de la classe pour la sauvegarde et la restauration du contenu de ses instances.
FileFilter L'interface FileFilter est un filtre pour les chemins abstraits.
FilenameFilter Les instances de classes qui implémente l'interface FilenameFilter sont utilisées pour filtrer les noms de fichiers.
ObjectInput L'interface ObjectInput hérite de l'interface DataInput pour inclure la lecture d'objets.
ObjectInputValidation Le rappel d'interface permet la validation des objets à l'intérieur d'un graphe.
ObjectOutput L'interface ObjectOutput hérite de l'interface DataOutput pour inclure l'écriture d'objets.
ObjectStreamConstants L'interface ObjectStreamConstants représente les constantes écrites à l'intérieur d'un flux de sérialisation d'objet.
Serializable La capacité de sérialiser une classe est activée par la classe implémentant l'interface Serializable.

Les classes
BufferedInputStream La classe BufferedInputStream ajoute des fonctionnalités à un autre flux d'entrée, la capacité de stocker dans un tampon l'entrée et de supporter les méthodes mark et reset.
BufferedOutputStream La classe BufferedOutputStream implémenté un flux de sortie placé dans en mémoire tampon.
BufferedReader La classe BufferedReader lit du texte à partir d'un flux d'entrée de caractères, mettant en mémoire tampon les caractères afin de fournir pour une lecture efficace des caractères, de tableaux et de lignes.
BufferedWriter La classe BufferedWriter écrit du texte vers un flux de sortie de caractères, mettant en mémoire tampon les caractères pour une écriture efficace de caractères, de tableaux et de chaînes de caractères.
ByteArrayInputStream La classe ByteArrayInputStream contient une mémoire tampon interne qui conserve les octets pouvant être lus à partir d'un flux.
ByteArrayOutputStream La classe ByteArrayOutputStream implémente un flux de sortie dans lequel les données sont écrites à l'intérieur d'un tableau d'octets.
CharArrayReader La classe CharArrayReader implémente une mémoire tampon de caractères pouvant être utilisé comme un flux d'entrée de caractères.
CharArrayWriter La classe CharArrayWriter implémente une mémoire tampon de caractères pouvant être utilisé comme un flux de sortie de caractères.
DataInputStream Un flux d'entrée de données laisse une application lire les types de données Java primitifs à partir d'un flux d'entrée sous-jacent dans une direction indépendante de la machine.
DataOutputStream Un flux de sortie de données laisse une application écrire les types de données Java primitifs à partir d'un flux de sortie sous-jacent dans une direction indépendante de la machine.
File La classe File constitue une représentation abstraite de chemins de fichiers et de répertoires.
FileDescriptor Les instances de la classe FileDescriptor servent de gestionnaire non-transparents vers la structure de machines spécifiques sous-jacentes représentant un fichier ou une socket ouverte, etc..
FileInputStream La classe FileInputStream obtient les octets d'entrée à partir d'un fichier dans un système de fichiers.
FileOutputStream La classe FileOutputStream est un flux de sortie pour l'écriture de données vers un objet File ou FileDescriptor.
FilePermission La classe FilePermission représente un accès à un fichier ou un répertoire.
FileReader Convenience class for reading character files.
FileWriter La classe FileWriter permet d'écrire des fichiers composés de caractères.
FilterInputStream La classe FilterInputStream contient certains autres flux d'entrée, qu'elle utilise en tant que source de données basique, probablement en transformant les données d'après la méthode ou fournissant des fonctionnalités additionnelles.
FilterOutputStream La classe FilterOutputStream est la superclasse de toutes les classes qui filtre les flux de sortie.
FilterReader La classe abstraite FilterReader permet de filtrer les flux d'entrée de caractères.
FilterWriter La classe abstraite FilterReader permet de filtrer les flux de sortie de caractères.
InputStream La classe abstraite InputStream est la superclasse de toutes les classes représentant un flux d'entrée d'octets.
InputStreamReader La classe InputStreamReader est un pont des flux d'octets vers des flux de caractères : il lit des octets et les décode selon des caractères utilisant un jeu de caractères spécifié.
LineNumberInputStream Dépréciée. La classe LineNumberInputStream suppose incorrectement que des octets représentent convenablement des caractères.
LineNumberReader La classe LineNumberReader représente un flux d'entrée de caractères qui conserve la piste des numéros de ligne.
ObjectInputStream Une classe ObjectInputStream désérialise des données et des objets primitifs précédemment écrits en utilisant un objet ObjectOutputStream.
ObjectInputStream.GetField La classe ObjectInputStream.GetField fournit un accès en lecture à des champs du flux d'entrée.
ObjectOutputStream La classe ObjectOutputStream écrit des types de données primitives et des graphes d'objets Java vers un objet OutputStream.
ObjectOutputStream.PutField La classe ObjectOutputStream.PutField fournit un accès programmatique à des champs persistants pour être écrit vers un objet ObjectOutput.
ObjectStreamClass La classe ObjectStreamClass est un descripteur de l'objet Serializationpour les classes.
ObjectStreamField La classe ObjectStreamField représente une description d'un champ Serializable à partir d'une classe Serializable.
OutputStream La classe abstraite OutputStream est la superclasse de toutes les classes représentant un flux de sortie d'octets.
OutputStreamWriter La classe OutputStreamWriter représente un pont entre les flux de caractères et les flux d'octets : les caractères écrits vers elle, sont codés dans des octets en utilisant un jeu de caractères spécifié.
PipedInputStream Un flux d'entrée doit être connecté à un flux de sortie, le conduit du flux d'entrée fournit alors quelques octets de données qui sont écrits vers le conduit du flux de sortie.
PipedOutputStream Un flux de sortie peut être connecté à un flux d'entrée pour créer un conduit de communications.
PipedReader La classe PipedReader représente un conduit de flux d'entrée de caractères.
PipedWriter La classe PipedWriter représente un conduit de flux de sortie de caractères.
PrintStream La classe PrintStream ajoute des fonctionnalités à un autre flux de sortie, c'est-à-dire, la capacité d'imprimer des représentations de diverses valeurs de données fonctionnelles.
PrintWriter La classe PrintWriter imprime des représentations formatées d'objets vers un flux de sortie textuel.
PushbackInputStream La classe PushbackInputStream ajoute des fonctionnalités à un autre flux d'entrée, c'est-à-dire, la capacité de repousser ou de ne pas lire un octet.
PushbackReader La classe PushbackReader représente une lecture d'un flux de caractères qui autorise les caractères à être repoussés dans un flux.
RandomAccessFile Les instances de la classe RandomAccessFile supportent la lecture et l'écriture vers un fichier à accès aléatoire.
Reader La classe abstraite Reader est utilisée pour la lecture des flux de caractères.
SequenceInputStream La classe SequenceInputStream représente la concaténation logique d'autres flux d'entrée.
SerializablePermission La classe SerializablePermission sert pour les permissions d'objet Serializable.
StreamTokenizer La classe StreamTokenizer prend un flux d'entrée et l'analyse en jeton (token), autorisant les jetons à être lus un par un.
StringBufferInputStream Dépréciée. La classe StringBufferInputStream ne convertit pas correctement les caractères en octets.
StringReader La classe StringReader représente un flux de caractères dont la source est un objet String.
StringWriter La classe StringWriter représente un flux de caractères qui collecte son entrée dans un objet StringBuffer qui peut alors être utilisé pour construire un objet String.
Writer La classe abstraite Writer sert pour la lecture de flux de caractères.

Le exceptions
CharConversionException Une classe de base pour les exceptions dûes à une conversion de caractère.
EOFException signale que la fin du fichier ou d'un flux a été atteinte d'une façon inattendue durant l'entrée.
FileNotFoundException signale qu'une tentative d'ouvrir le fichier dénoté par un chemin spécifié n'a pas réussi.
InterruptedIOException signale qu'une opération d'entrée/sortie a été interrrompue.
InvalidClassException est lancée lorsque l'exécution de l'objet Serialization détecte un des problèmes suivants avec une classe.
InvalidObjectException indique qu'un ou plusieurs objets désérialisés n'ont pas réussi les tests de validation.
IOException signale qu'une exception d'entrée/sortie s'est produite.
NotActiveException est lancée lorsqu'un sérialisation ou une désérialisation n'est pas active.
NotSerializableException est lancé lorsqu'une instance est requise de posséder une interface Serializable.
ObjectStreamException constitue la superclasse de toutes les exceptions spécifique aux classes de flux d'objets.
OptionalDataException indique l'échec de l'opération de lecture d'un objet dû à une donnée primitive illisible ou la fin de données appartenant à un objet sérialisé dans le flux.
StreamCorruptedException est lancée lorsque l'information de contrôle qui était lue à partir d'un flux d'objet a violé la vérification logique interne.
SyncFailedException signale qu'une opération de synchronisation a échoué.
UnsupportedEncodingException signale que l'encodage de caractères n'est pas supporté.
UTFDataFormatException signale qu'une chaîne de caractères UTF-8 malformée a été lue dans une flux d'entrée de données ou paar n'importe quelle classe qui implémente l'interface d'entrée de données.
WriteAbortedException signale qu'un des objets ObjectStreamExceptions était lancé durant une opération d'écriture.

40.1 / La classe BufferedInputStream

Un objet BufferedInputStream ajoute des fonctionnalités à un autre flux d'entrée, la capacité à placer en mémoire tampon l'entrée et de supporter les méthodes mark et reset.

Lorsque l'objet BufferedInputStream est créé, un tableau tampon interne est également créé. Le tampon interne est rempli au fur et à mesure de la lecture du flux d'entrée par octet. Lorsqu'un octet est sauté, le tableau n'est pas modifié. L'opération de marquage conserve un point précis dans le flux d'entrée et l'opération de réinitialisation provoque la relecture de tous les octets lus depuis la marque la plus récente, jusqu'aux nouveaux octets.

Les champs
protected byte[] buf
Ce champ représente le tableau tampon interne où les données sont stockées.
protected int count
Ce champ représente l'index plus grand que l'index précédent représentant le dernier octet valide dans le tampon interne.
protected int marklimit
Ce champ représente le maximum lu auparavant autorisé après un appel à la méthode mark avant les appels subséquents à l'échec de la méthode reset.
protected int markpos
Ce champ représente la valeur du champ pos au moment où la dernière méthode mark a été appelée.
protected int pos
Ce champ représente la position courante dans le tampon interne.
Les champs hérités de la classe java.io.FilterInputStream
in

Les constructeurs
BufferedInputStream(InputStream in)
construit un objet BufferedInputStream et sauvegarde son argument, in, pour une utilisation ultérieure.
BufferedInputStream(InputStream in, int size)
construit un objet BufferedInputStream avec la taille du tampon interne spécifiée et sauvegarde son argument, in, pour une utilisation ultérieure.

Les méthodes
int available()
retourne le nombre d'octets qui peuvent être lus à partir du flux d'entrée sans blocage.
void close()
ferme le flux d'entrée et libère les ressources systèmes qui lui étaient affectées.
void mark(int readlimit)
Voir le contrat général de la méthode mark de l'objet InputStream.
boolean markSupported()
teste si le flux d'entrée supporte les méthodes mark et reset.
int read()
Voir le contrat général de la méthode read de l'objet InputStream.
int read(byte[] b, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
void reset()
Voir le contrat général de la méthode reset de l'objet InputStream.
long skip(long n)
Voir le contrat général de la méthode skip de l'objet InputStream.
Les méthodes héritées de la classe java.io.FilterInputStream
read
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.2 / La classe BufferedOutputStream

La classe BufferedOutputStream implémente un flux de sortie mis en mémoire tampon. Une application peut écrire des octets dans l'objet BufferedOutputStream sous-jacent sans nécessairement provoquer un appel au système sous-jacent pour chaque octet écrit.

Les données sont écrites dans une mémoire tampon interne, et ensuite sont écrites vers le flux sous-jacent. Si la mémoire tampon parvient à la limite supérieure de sa capacité, l'objet BufferedOutputStream est fermé ou est explicitement vidé.

Les champs
protected byte[] buf
Ce champ représente la mémoire tampon interne où sont stockées les données.
protected int count
Ce champ représente le nombre d'octets valides dans la mémoire tampon.
Les champs hérités de la classe java.io.FilterOutputStream
out

Les constructeurs
BufferedOutputStream(OutputStream out)
crée un nouvel objet BufferedOutputStream à partir d'un autre objet BufferedOutputStream sous-jacent avec une taille de mémoire tampon par défaut égale à 512 octets.
BufferedOutputStream(OutputStream out, int size)
crée un nouvel objet BufferedOutputStream à partir d'un autre objet BufferedOutputStream sous-jacent avec une certaine taille de mémoire tampon.

Les méthodes
void flush()
vide le contenu de l'objet BufferedOutputStream.
void write(byte[] b, int off, int len)
écrit dans un objet BufferedOutputStream, une certaine longueur d'octets à partir du tableau d'octets spécifié et en démarrant à la position passée en argument.
void write(int b)
écrit l'octet spécifié vers l'objet BufferedOutputStream.
Les méthodes héritées de la classe java.io.FilterOutputStream
close, write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.3 / La classe BufferedReader

La classe BufferedReader lit du texte à partir d'un flux d'entrée de caractères, mettant en mémoire tampon les caractères afin de fournir une plus grande efficacité pour la lecture de caractères, de tableaux et de lignes.

Les champs
Les champs hérités de la classe java.io.Reader
lock
Les constructeurs
BufferedReader(Reader in)
crée un objet BufferedReader qui utilise une mémoire tampon d'entrée d'une taille par défaut.
BufferedReader(Reader in, int sz)
crée un objet BufferedReader qui utilise une mémoire tampon d'entrée d'une certaine taille.
Les méthodes
void close()
ferme le flux.
void mark(int readAheadLimit)
marque la position actuelle dans le flux.
boolean markSupported()
indique si le flux supporte la méthode mark().
int read()
lit un unique caractère.
int read(char[] cbuf, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
String readLine()
lit une ligne de texte.
boolean ready()
indique si le flux est prêt à être lu.
void reset()
réinitialise le flux vers la marque la plus récente.
long skip(long n)
saute des caractères.
Les méthodes héritées de la classe java.io.Reader
read
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.4 / La classe BufferedWriter

La classe BufferedWriter écrit du texte vers un flux de sortie de caractères, mettant en mémoire tampon les caractères pour une écriture efficace de caractères, de tableaux et de chaînes de caractères.

Les champs
Les champs hérités de la classe java.io.Writer
lock

Les constructeurs
BufferedWriter(Writer out)
crée un nouvel objet BufferedWriter qui utilise une mémoire tampon de sortie et une taille par défaut.
BufferedWriter(Writer out, int sz)
crée un nouvel objet BufferedWriter qui utilise une mémoire tampon de sortie et une certaine taille.

Les méthodes
void close()
ferme le flux.
void flush()
vide le contenu du flux.
void newLine()
écrit un séparateur de ligne.
void write(char[] cbuf, int off, int len)
écrit une portion d'un tableau de caractères, délimitée par une position de départ et une longueur.
void write(int c)
écrit un unique caractère.
void write(String s, int off, int len)
écrit une portion de chaîne de caractères, délimitée par une position de départ et une longueur.
Les méthodes héritées de la classe java.io.Writer
write, write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.5 / La classe ByteArrayInputStream

Un objet ByteArrayInputStream contient une mémoire tampon interne conservant les octets pouvant être lus à partir d'un flux. Un compteur interne garde la piste du prochain octet qui sera fourni par la méthode read.

La fermeture d'un objet ByteArrayInputStream n'a aucun effet. Les méthodes de cette classe peuvent être appelées après que le flux ait été fermé sans générer d'exception IOException.

Les champs
protected byte[] buf
Ce champ représente un tableau d'octets qui était fourni lors de la création de l'objet ByteArrayInputStream.
protected int count
Ce champ représente l'index plus grand que l'index du dernier caractère valide dans le flux d'entrée.
protected int mark
Ce champ représente la position de marquage dans le flux.
protected int pos
Ce champ représente l'index du prochain caractère à lire dans le flux d'entrée mis en mémoire tampon.

Les constructeurs
ByteArrayInputStream(byte[] buf)
crée un objet ByteArrayInputStream qui utilise une tableau d'octets complet.
ByteArrayInputStream(byte[] buf, int offset, int length)
crée un objet ByteArrayInputStream qui utilise une portion d'un tableau d'octets, délimitée par une position de départ et une longueur.

Les méthodes
int available()
retourne le nombre d'octets qui peut peuvent être lus dans le flux d'entrée sans blocage.
void close()
ferme l'objet ByteArrayInputStream, mais n'a aucun effet.
void mark(int readAheadLimit)
fixe la position de marquage courante dans le flux d'entrée.
boolean markSupported()
teste si l'objet ByteArrayInputStream supporte les méthodes mark et reset.
int read()
lit le prochain octet dans le flux d'entrée.
int read(byte[] b, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
void reset()
réinitialise la mémoire tampon à la position du dernier marquage.
long skip(long n)
saute un certain nombre d'octets du flux d'entrée.
Les méthodes héritées de la classe java.io.InputStream
read
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.6 / La classe ByteArrayOutputStream

La classe ByteArrayOutputStream implémente un flux de sortie dans lequel les données sont écrites dans un tableau d'octets. La mémoire tampon croît automatiquement lorsque les données y sont écrites. Les données peuvent être récupérées en utilisant la méthode toByteArray() ou toString().

La fermeture de l'objet ByteArrayOutputStream n'a aucun effet. Les méthodes de cette classe peuvent être appelées après que le flux ait été fermé sans générer d'exception d'entrée/sortie.

Les champs
protected byte[] buf
Ce champ représente la mémoire tampon où sont stockées les données.
protected int count
Ce champ représente le nombre d'octets valides dans la mémoire tampon.

Les constructeurs
ByteArrayOutputStream()
créee un nouvel objet ByteArrayOutputStream.
ByteArrayOutputStream(int size)
crée un nouvel objet ByteArrayOutputStream avec taille de tampon précisée.

Les méthodes
void close()
ferme l'objet ByteArrayOutputStream, mais n'a aucun effet.
void reset()
réinitialise le champ count de l'objet ByteArrayOutputStream à zéro, de telle façon que toutes les sorties accumulées actuellement dans le flux de sortie sont abandonnées.
int size()
retourne la taille courante de la mémoire tampon.
byte[] toByteArray()
crée un nouveau tableau d'octets alloué.
String toString()
convertir le contenu de la mémoire tampon en une chaîne de caractères en traduisant les octets en caractères en accord avec l'encodage des caractères par défaut de la plateforme.
String toString(int hibyte)
Dépréciée. voir toString().
String toString(String enc)
convertit le contenu de la mémoire tampon dans une chaîne de caractères en traduisant les octets en caractères conformément à l'encodage de caractères spécifié.
void write(byte[] b, int off, int len)
écrit une certaine longueur d'octets à partir d'un tableau d'octets et en démarrant à la position spécifié et jusqu'à une certaine longueur dans le tableau.
void write(int b)
écrit l'octet spécifié dans l'objet ByteArrayOutputStream.
void writeTo(OutputStream out)
écrit le contenu complet de l'objet ByteArrayOutputStream dans le flux de sortie passsé en argument.
Les méthodes héritées de la classe java.io.OutputStream
flush, write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

40.7 / La classe CharArrayReader

La classe CharArrayReader implémente une mémoire tampon de caractères qui peut être utilisée comme un flux d'entrée de caractères.

Les champs
protected char[] buf
Ce champ représente la mémoire tampon de caractères.
protected int count
Ce champ représente l'index du dernier caractère dans la mémoire tampon.
protected int markedPos
Ce champ représente la position de la marque dans la mémoire tampon.
protected int pos
Ce champ représente la position courante dans la mémoire tampon.
Les champs hérités de la classe java.io.Reader
lock

Les constructeurs
CharArrayReader(char[] buf)
crée un CharArrayReader à partir d'une partie du tableau de caractères spécifié.
CharArrayReader(char[] buf, int offset, int length)
crée un CharArrayReader à partir d'une partie du tableau de caractères spécifié, délimitée par une position de départ et une longueur.

Les méthodes
void close()
ferme le flux.
void mark(int readAheadLimit)
marque la position actuelle dans le flux.
boolean markSupported()
indique si le flux supporte la méthode mark().
int read()
lit un unique caractère
int read(char[] b, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
boolean ready()
indique si le flux est prêt à être lu.
void reset()
réinitialise le flux à la marque la plus récente ou au début s'il n'y a pas de marque
long skip(long n)
saute des caractères.
Les méthodes héritées de la classe java.io.Reader
read
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.8 / La classe CharArrayWriter

La classe CharArrayWriter implémente une mémoire tampon de caractères qui peut être utilisée comme un objet Writer.

La mémoire tampon croît automatiquement lorsque des données sont écrites dans le flux. Les données peuvent être récupérées par l'intermédiaire des méthodes toCharArray() et toString().

Les champs
protected char[] buf
Ce champ représente la mémoire tampon de caractères.
protected int count
Ce champ représente l'index du dernier caractère dans la mémoire tampon.
Les champs hérités de la classe java.io.Writer
lock

Les constructeurs
CharArrayWriter()
crée un nouvel objet CharArrayWriter.
CharArrayWriter(int initialSize)
crée un noouvel objet CharArrayWriter en lui spécifiant une taille initiale.

Les méthodes
void close()
ferme le flux.
void flush()
vide le flux.
void reset()
réinitialise la mémoire tampon de telle façon qu'il est encore possible de l'utiliser sans se débarrasser de la mémoire tampon déjà allouée.
int size()
retourne la taille courante de la mémoire tampon.
char[] toCharArray()
retourne une copie des données d'entrées dans un tableau de caractères.
String toString()
convertit les données d'entrée vers une chaîne de caractères.
void write(char[] c, int off, int len)
écrit des caractères extraits d'un tableau selon une position de départ et une longueur, dans la mémoire tampon.
void write(int c)
écrit un caractère dans la mémoire tampon.
void write(String str, int off, int len)
écrit une portion d'un objet String dans la mémoire tampon.
void writeTo(Writer out)
écrit le contenu de la mémoire tampon dans un autre flux de caractères.
Les méthodes héritées de la classe java.io.Writer
write, write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

40.9 / La classe DataInputStream

L'objet DataInputStream laisse une application lire les types de données primitifs à partir d'un flux d'entrée sous-jacent d'une manière indépendante de la machine.

Une application utilise des données de sortie pour écrire des données qui peuvent être lus plus tard par un objet DataInputStream.

Les champs
Les champs hérités de la classe java.io.FilterInputStream
in

Les constructeurs
DataInputStream(InputStream in)
crée un DataInputStream qui utilise l'objet InputStream sous-jacent passé en argument.

Les méthodes
int read(byte[] b)
lit plusieurs octets à partir du flux d'entrée contenu et les stocke dans le tableau d'octets passé en argument.
int read(byte[] b, int off, int len)
lit depuis une position de départ et jusqu'à une certaine longueur de données à partir du flux d'entrée contenu et les stocke dans un tableau de d'octets.
boolean readBoolean()
Voir le contrat général de la méthode readBoolean() de la classe DataInput.
byte readByte()
Voir le contrat général de la méthode readByte() de la classe DataInput.
char readChar()
Voir le contrat général de la méthode readChar() de la classe DataInput.
double readDouble()
Voir le contrat général de la méthode readDouble() de la classe DataInput.
float readFloat()
Voir le contrat général de la méthode readFloat() de la classe DataInput.
void readFully(byte[] b)
Voir le contrat général de la méthode readFully() de la classe DataInput.
void readFully(byte[] b, int off, int len)
Voir le contrat général de la méthode readFully() de la classe DataInput.
int readInt()
Voir le contrat général de la méthode readInt() de la classe DataInput.
String readLine()
Dépréciée. Voir la classe BufferedReader
long readLong()
Voir le contrat général de la méthode readLong() de la classe DataInput.
short readShort()
Voir le contrat général de la méthode readShort() de la classe DataInput.
int readUnsignedByte()
Voir le contrat général de la méthode readUnsignedByte() de la classe DataInput.
int readUnsignedShort()
Voir le contrat général de la méthode readUnsignedShort() de la classe DataInput.
String readUTF()
Voir le contrat général de la méthode readUTF() de la classe DataInput.
static String readUTF(DataInput in)
lit dans le flux une représentation d'une chaîne de caractères Unicode encodée dans le format UTF-8 spécifique à Java. Cette chaîne de caractères est retournée dans un objet String.
int skipBytes(int n)
Voir le contrat général de la méthode skipBytes() de la classe DataInput.
Les méthodes héritées de la classe java.io.FilterInputStream
available, close, mark, markSupported, read, reset, skip
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.10 / La classe DataOutputStream

La classe DataOutputStream laisse une application écrire des types de données primitifs dans un flux de sortie sous-jacent d'une manière indépendante de la machine.

Une application peut alors utiliser un objet DataOutputStream pour la lecture des données.

Les champs
protected int written
Ce champ représente le nombre d'octets écrit dans l'objet DataOutputStream.
Les champs hérités de la classe java.io.FilterOutputStream
out

Les constructeurs
DataOutputStream(OutputStream out)
crée un nouvel objet DataOutputStream pour écrire des données vers l'objet OutputStream sous-jacent.

Les méthodes
void flush()
vide le flux de sortie de données.
int size()
retourne le nombre d'octets écrit dans l'objet DataOutputStream sous-jacent.
void write(byte[] b, int off, int len)
écrit des octets contenus dans le tableau à partir d'une position de départ et d'une certaine longueur dans l'objet DataOutputStream sous-jacent.
void write(int b)
écrit le huitième bits inférieur de la valeur entière dans l'objet DataOutputStream.
void writeBoolean(boolean v)
écrit une valeur booléenne dans l'objet DataOutputStream sous la forme d'une valeur d'un octet.
void writeByte(int v)
écrit une valeur entière dans l'objet DataOutputStream sous-jacent sous la forme d'une valeur d'un octet.
void writeBytes(String s)
écrit une chaîne de caractères dans l'objet DataOutputStream sous-jacent sous la forme d'une séquence d'octets.
void writeChar(int v)
écrit un caractère dans l'objet DataOutputStream sous-jacent sous la forme de deux octets.
void writeChars(String s)
écrit une chaîne de caractères dans l'objet DataOutputStream sous-jacent sous la forme d'une séquence de caractères.
void writeDouble(double v)
convertir un nombre double vers un long en utilisant la méthode doubleToLongBits de la classe Double, et écrit alors la valeur long dans l'objet DataOutputStream sous-jacent sous la forme de huit octets.
void writeFloat(float v)
convertit un nombre float vers un int en utilisant la méthode floatToIntBits() de la classe Float, et écrit alors la valeur de type int dans l'objet DataOutputStream sous-jacent sous la forme de quatre octets.
void writeInt(int v)
écrit une valeur de type int dans l'objet DataOutputStream sous-jacent sous la forme de quatre octets.
void writeLong(long v)
écrit une valeur de type long dans l'objet DataOutputStream sous-jacent sous la forme de huit octets.
void writeShort(int v)
écrit une valeur de type short dans l'objet DataOutputStream sous-jacent sous la forme de deux octets.
void writeUTF(String str)
écrit une chaîne de caractères dans l'objet DataOutputStream sous-jacent en utilisant l'encodage UTF-8 d'une manière indépendante de la machine.
Les méthodes héritées de l'interface java.io.DataOutput
write
Les méthodes héritées de la classe java.io.FilterOutputStream
close, write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.11 / La classe File

L'objet File constitue une représentation abstraite d'un chemin ver un fichier ou un répertoire.

Le séparateur de chemin dépend de la plateforme. Sous Unix la valeur de ce séparateur est '/' alors que sous Windows sa valeur est égale à '\'.

/home/repertoire/fichier.ext

c:\repertoire\fichier.ext
Les champs
static String pathSeparator
Ce champ représente le caractère de séparation par défaut dépendant du système sous-jacent, sous la forme d'une chaîne de caractères pour des raisons de commodités.
static char pathSeparatorChar
Ce champ représente le caractère de séparation de chemin par défaut dépendant du système sous-jacent.
static String separator
Ce champ représente le caractère de séparation par défaut dépendant du système sous-jacent, sous la forme d'une chaîne de caractères pour des raisons de commodités.
static char separatorChar
Ce champ représente le caractère de séparation par défaut dépendant du système sous-jacent.

Les constructeurs
File(File parent, String child)
crée un nouvel objet File à partir d'un autre chemin abstrait désignant le parent d'une chaîne de caractères indiquant un chemin enfant.
File(String pathname)
crée un nouvel objet File à partir d'un chemin donné sous la forme d'une chaîne de caractères.
File(String parent, String child)
crée un nouvel objet File à partir de deux chaînes de caractères désignant respectivement un chemin parent et un autre enfant.
File(URI uri)
crée un nouvel objet File en convertissant l'URI fourni en chemin abstrait.

Les méthodes
boolean canRead()
teste si l'application peut lire le fichier désigné par l'objet File.
boolean canWrite()
teste si l'application peut modifier le fichier désigné par le chemin abstrait.
int compareTo(File pathname)
compare lexicographiquement deux objets File.
int compareTo(Object o)
compare l'objet File par rapport à un autre objet.
boolean createNewFile()
crée atomiquement un nouveau fichier vide désigné par le chemin abstrait si et seulement si un fichier de même nom n'existe pas encore.
static File createTempFile(String prefix, String suffix)
crée un nouvel objet File vide dans le répertoire temporaire par défaut en utilisant le préfixe et le suffixe donnés pour générer son nom.
static File createTempFile(String prefix, String suffix, File directory)
crée un nouvel objet File vide dans le répertoire spécifié en utilisant le préfixe et le suffixe donnés pour générer son nom.
boolean delete()
supprime le fichier ou le répertoire désigné par l'objet File.
void deleteOnExit()
demande que le fichier ou le répertoire désigné par le chemin abstrait soit supprimé lorsque la Machine Virtuelle Java s'arrête.
boolean equals(Object obj)
teste l'égalité de l'objet File par rapport à un autre objet.
boolean exists()
teste si le fichier désigné par le chemin abstrait existe.
File getAbsoluteFile()
retourne la forme absolue du chemin abstrait.
String getAbsolutePath()
retourne le chemin absolu sous la forme d'une chaîne de caractères de l'objet File.
File getCanonicalFile()
retourne la forme canonique de l'objet File.
String getCanonicalPath()
retourne le chemin canonique sous la forme d'une chaîne de caractères de l'objet File.
String getName()
retourne le nom du fichier ou du répertoire désigné par le chemin abstrait.
String getParent()
retourne le chemin parent, sous la forme d'une chaîne de caractères, de l'objet File, ou null si ce dernier n'a pas de parent.
File getParentFile()
retourne le chemin abstrait parent de l'objet File, ou null si ce dernier n'a pas de parent.
String getPath()
convertit l'objet File vers un chemin sous forme de chaîne de caractères.
int hashCode()
cacule un hash code pour l'objet File.
boolean isAbsolute()
teste si le chemin abstrait est absolu.
boolean isDirectory()
teste si le fichier désigné par le chemin abstrait est un répertoire.
boolean isFile()
teste si le fichier désigné par le chemin abstrait est un fichier normal.
boolean isHidden()
teste si le fichier désigné par le chemin abstrait est un fichier caché.
long lastModified()
retourne le temps de la dernière modification du fichier donné par le chemin abstrait.
long length()
Returns the length of the file denoted by this abstract pathname.
String[] list()
retourne un tableau de chaînes de caractères indiquant les fichiers et répertoires dans le répertoire spécifié par le chemin abstrait.
String[] list(FilenameFilter filter)
retourne un tableau de chaînes de caractères indiquant les fichiers et répertoires dans le répertoire spécifié par le chemin abstrait qui satisfait le filtre donné.
File[] listFiles()
retourne un tableau de chemins abstraits indiquant les fichiers et répertoires dans le répertoire spécifié par le chemin abstrait.
File[] listFiles(FileFilter filter)
retourne un tableau de chemins abstraits indiquant les fichiers et répertoires dans le répertoire spécifié par le chemin abstrait qui satisfait le filtre donné.
File[] listFiles(FilenameFilter filter)
retourne un tableau de chemins abstraits indiquant les fichiers et répertoires dans le répertoire spécifié par le chemin abstrait qui satisfait le filtre donné.
static File[] listRoots()
liste les racines disponibles du système de fichiers.
boolean mkdir()
crée le répertoire désigné par le chemin abstrait.
boolean mkdirs()
crée le répertoire et éventuellement ses répertoires parents désignés par le chemin abstrait.
boolean renameTo(File dest)
renomme le fichier défini par le chemin abstrait.
boolean setLastModified(long time)
fixe le temps de la dernière modification du fichier ou du répertoire désigné par le chemin abstrait.
boolean setReadOnly()
marque le fichier ou le répertoire nommé par le chemin abstrait de telle façon que des opérations en lecture seule sont autorisées.
String toString()
retourne le chemin sous la forme d'un objet String de l'objet File.
URI toURI()
construit un fichier URI qui représente le chemin abstrait.
URL toURL()
convertit le chemin abstrait en un fichier URL.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

40.12 / La classe FileDescriptor

Les instances de la classe FileDescriptor sont utilisées comme un gestionnaire non-transparent vers la structure des machines spécifiques sous-jacentes représentant un fichier ou une socket ouverte.

La manière principale d'utiliser un objet FileDescriptor est de créer un objet FileInputStream ou FileOutputStream afin de le contenir. Les applications ne doivent pas créer leurs propres descripteurs de fichiers

Les champs
static FileDescriptor err
Ce champ représente un gestionnaire pour le flux d'erreur standard.
static FileDescriptor in
Ce champ représente un gestionnaire pour le flux d'entrée standard.
static FileDescriptor out
Ce champ représente un gestionnaire pour le flux de sortie standard.

Les constructeurs
FileDescriptor()
construit un objet FileDescriptor invalide.

Les méthodes
void sync()
force toutes les mémoires tampons systèmes à se synchroniser avec le matériel sous-jacent.
boolean valid()
teste si l'objet FileDescriptor est valide.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.13 / La classe FileInputStream

Un objet FileInputStream obtient des octets en entrée à partir d'un système de fichiers. La disponibilité des fichiers dépendent de l'environnement hôte.

L'objet FileInputStream est indiqué pour la lecture des flux d'octets bruts tels que ceux des données graphiques (images). Pour la lecture des flux de caractères, il est préférable d'utiliser l'objet FileReader.

Les constructeurs
FileInputStream(File file)
crée un objet FileInputStream en ouvrant une connexion à un fichier courant, soit le fichier désigné par l'objet File.
FileInputStream(FileDescriptor fdObj)
crée un objet FileInputStream en utilisant un descripteur de fichier qui représente une connexion existante vers un fichier courant dans le système de fichiers.
FileInputStream(String name)
crée un objet FileInputStream en ouvrant une connexion à un fichier courant, soit le fichier désigné par le chemin fourni en argument.

Les méthodes
int available()
retourne le nombre d'octets qui peuvent être lus à partir du flux d'entrée sans entraîner de blocage.
void close()
ferme le flux d'entrée de fichiers et libère les ressources systèmes associées au flux.
protected void finalize()
assure que la méthode close() de l'objet FileInputStream, est appelée lorsqu'il n'y a plus de références vers lui.
FileChannel getChannel()
retourne un objet FileChannel unique associé à l'objet FileInputStream.
FileDescriptor getFD()
retourne l'objet FileDescriptor qui représente la connexion vers le fichier courant dans le système de fichiers étant utilisé par l'objet FileInputStream.
int read()
lit un octet de données dans l'objet FileInputStream.
int read(byte[] b)
lit dans le flux d'entrée, le même nombre d'octets que peut contenir le tableau passé en argument, et remplit toutes les cellules de ce dernier.
int read(byte[] b, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
long skip(long n)
saute et décharge un certain nombre d'octets de données du flux d'entrée de fichiers.
Les méthodes héritées de la classe java.io.InputStream
mark, markSupported, reset
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.14 / La classe FileOutputStream

Un objet FileOutputStream est un flux de sortie pour l'écriture de données vers un fichier ou vers un objet FileDescriptor. La disponibilité ou la création d'un fichier dépend de la plateforme sous-jacente.

Plusieurs plateformes permettent à un fichier d'être ouvert pour une écriture par seulement un objet FileOutputStream ou un autre objet d'écriture. Dans de telles situations, les constructeurs de cette classe devraient échoués si le fichier concerné est déjà ouvert.

Un objet FileOutputStream est indiqué pour la l'écriture des lux d'octets bruts comme des données graphiques (images, vidéos, etc.). Pour l'écriture des flux de caractères, il est préférable d'utiliser l'objet FileWriter.

Les constructeurs
FileOutputStream(File file)
crée un objet FileOutputStream pour écrire dans le fichier désigné par l'objet File.
FileOutputStream(File file, boolean append)
crée un objet FileOutputStream pour écrire dans le fichier désigné par l'objet File en précisant si le contenu doit écraser l'existant ou s'y ajouter.
FileOutputStream(FileDescriptor fdObj)
crée un objet FileOutputStream pour écrire dans le descripteur de fichier qui représente une connexion existante vers un fichier courant dans le système de fichiers.
FileOutputStream(String name)
crée un objet FileOutputStream pour écrire dans le fichier désigné par le chemin fourni en argument.
FileOutputStream(String name, boolean append)
crée un objet FileOutputStream pour écrire dans le fichier désigné par le chemin et en précisant si le contenu doit écraser l'existant ou s'y ajouter.

Les méthodes
void close()
ferme l'objet FileOutputStream et libère les ressources systèmes associées au flux.
protected void finalize()
supprime la connexion vers le fichier et assure que la méthode close() de l'objet FileOutputStream est appelée lorsqu'il n'y a plus de références vers le flux.
FileChannel getChannel()
retourne un unique objet FileChannel associé à l'objet FileOutputStream.
FileDescriptor getFD()
retourne un objet FileDescriptor associé au flux.
void write(byte[] b)
écrit les octets contenu dans le tableau vers l'objet FileOutputStream.
void write(byte[] b, int off, int len)
écrit une partie des octets du tableau, délimitée par une position de départ et une certaine longueur, vers l'objet FileOutputStream.
void write(int b)
écrit l'octet spécifié vers l'objet FileOutputStream.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.15 / La classe FileReader

La classe FileReader propose des commodits pour la lecture des fichiers caractères. Les constructeurs de cette classe vérifie que l'encodage de caractères et la taille de la mémoire tampon par défaut sont appropriés.

Pour spécifier les valeurs, il faut construire un objet InputStreamReader sur un FileInputStream.

L'objet FileReader est indiqué pour la lecture des flux de caractères.

Pour la lecture des flux d'octets bruts, il est préférable d'utiliser l'objet FileInputStream.

Les champs
Les champ de la classe java.io.Reader
lock

Les constructeurs
FileReader(File file)
crée un nouvel objet FileReader à partir de l'objet File donné pour lire à partir de ce dernier.
FileReader(FileDescriptor fd)
crée un nouvel objet FileReader à partir de l'objet FileDescriptor donné pour lire à partir de ce dernier.
FileReader(String fileName)
crée un nouvel objet FileReader à partir d'un chemin vers un fichier, pour lire à partir de ce dernier.

Les méthodes
Les méthodes héritées de la classe java.io.InputStreamReader
close, getEncoding, read, read, ready
Les méthodes héritées de la classe java.io.Reader
mark, markSupported, read, reset, skip
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.16 / La classe FileWriter

La classe FileWriter fournit des commoditiés pour l'écriture des fichiers caractères. Les constructeurs de cette classe vérifie que l'encodage de caractères et la taille de la mémoire tampon par défaut sont appropriés.

Pour spécifier les valeurs, il faut construire un objet OutputStreamReader sur un FileOutputStream.

L'objet FileReader est indiqué pour l'écriture des flux de caractères.

Plusieurs plateformes autorisent un fichier à être ouvert pour l'écriture seulement par un objet FileWriter ou un autre objet d'écriture sur les fichiers à un moment. Dans de telles situations les constructeurs de la classe FileWriter échoueraient si le fichier concerné est déjà ouvert.

Pour la lecture des flux d'octets bruts, il est préférable d'utiliser l'objet FileOutputStream.

Les champs
Les champ de la classe java.io.Writer
lock

Les constructeurs
FileWriter(File file)
construit un objet FileWriter à partir d'un objet File.
FileWriter(File file, boolean append)
construit un objet FileWriter à partir d'un objet File en indiquant si le fichier doit être écrasé par le nouveau contenu ou si ce dernier doit être ajouté.
FileWriter(FileDescriptor fd)
construit un objet FileWriter associé à un objet FileDescriptor.
FileWriter(String fileName)
construit un objet FileWriter à partir d'un chemin vers un fichier spécifié en argument.
FileWriter(String fileName, boolean append)
construit un objet FileWriter à partir d'un chemin vers un fichier en indiquant si le fichier doit être écrasé par le nouveau contenu ou si ce dernier doit être ajouté.

Les méthodes
Les méthodes héritées de la classe java.io.OutputStreamWriter
close, flush, getEncoding, write, write, write
Les méthodes héritées de la classe java.io.Writer
write, write
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.17 / La classe FilterInputStream

La classe FilterInputStream contient certains autres flux d'entrée, qu'elle utilise en tant que source de données basique, probablement en transformant les données d'après la méthode ou fournissant des fonctionnalités additionnelles.

Cette classe ele-même surcharge simplement toutes les méthodes de la classe InputStream avec les versions qui passe toutes les requêtes au flux d'entrée contenu. Les sous-classes de FilterInputStream peuvent de plus surcharger certaines de ces méthodes et peuvent aussi fournir des méthodes et des champs additionnels.

Les champs
protected InputStream in
Ce champ représente le flux d'entrée à filtrer.

Les constructeurs
protected FilterInputStream(InputStream in)
crée un objet FilterInputStream en assignant l'objet InputStream passé en argument au champ this.in afin de le conserver pour une utilisation ultérieure.

Les méthodes
int available()
retourne le nombre d'octets qui peuvent être lus à partir de l'objet FilterInputStream, sans blocage.
void close()
ferme l'objet FilterInputStream et libère toutes les ressources systèmes associées au flux d'entrée.
void mark(int readlimit)
marque la position courante dans le flux d'entrée.
boolean markSupported()
teste si le flux d'entrée supporte les méthodes mark() et reset().
int read()
lit le prochain octet de données à partir de ce flux d'entrée.
int read(byte[] b)
lit dans le flux d'entrée, le même nombre d'octets que peut contenir le tableau passé en argument, et remplit toutes les cellules de ce dernier.
int read(byte[] b, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
void reset()
réinitialise le flux d'entrée à la position où la méthode mark() a été appelée la dernière fois.
long skip(long n)
saute et abandonne un certain nombre d'octets de données à partir du flux d'entrée.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.18 / La classe FilterOutputStream

La classe FilterOutputStream est la superclasse de toutes les classes de flux de sortie de filtrage. Ces flux s'appuyent sur un flux de sortie sous-jacent dèjà existant qui l'utilise comme son réservoir de données de base, mais probablement en transformant les données d'après la méthode ou en fournissant des fonctionnalités additionnelles.

Cette classe elle-même surcharge simplement toutes les méthodes de la classe OutputStream avec les versions qui passent des requêtes au flux de sortie sous-jacent. Les sous-classe de FilterOutputStream peuvent de plus surcharger certaines de ces méthodes, ou bien fournir des méthodes et des champs additionnels.

Les champs
protected OutputStream out
Ce champ représente le flux d'entrée sous-jacent à filtrer.

Les constructeurs
FilterOutputStream(OutputStream out)
crée un objet FilterOutputStream à partir du flux d'entrée sous-jacent spécifié.

Les méthodes
void close()
ferme le flux de sortie et libère toutes les ressources systèmes associées au flux de sortie.
void flush()
vide le flux de sortie et oblige n'importe quels octets de sortie mis en mémoire tampon à être écrit vers le flux.
void write(byte[] b)
écrit tous les octets contenus dans le tableau passé en argument, dans le flux de sortie.
void write(byte[] b, int off, int len)
écrit un certain nombre d'octets du tableau passé en argument en commençant à une position spécifiée jusqu'à une certaine longueur, dans le flux de sortie.
void write(int b)
écrit l'octet spécifié vers le flux de sortie.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.19 / La classe FilterReader

La classe abstraite FilterReader est utilisée pour la lecture des flux de caractères filtrés. Cette classe elle-même contient des méthodes par défaut qui passent toutes les requêtes vers le flux contenu. Les sous-classes de FilterReader doivent surcharger certaines de ces méthodes et peuvent aussi fournir des méthodes et des champs additionnels.

Les champs
protected Reader in
Ce champ représente le flux d'entrée de caractères, ou la valeur null si le flux a été fermé.
Les champs hérités de la classe java.io.Reader
lock

Les constructeurs
protected FilterReader(Reader in)
crée un nouvel objet FilterReader à partir d'un objet Reader passé en argument.

Les méthodes
void close()
ferme le flux.
void mark(int readAheadLimit)
marque la position courante dans le flux.
boolean markSupported()
indique si le flux supporte la méthode mark().
int read()
lit un unique caractère.
int read(char[] cbuf, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
boolean ready()
indique si le flux est prêt à être écrit.
void reset()
réinitialise le flux.
long skip(long n)
saute un certain nombre de caractères.
Les méthodes héritées de la classe java.io.Reader
read
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.20 / La classe FilterWriter

La classe abstraite FilterWriter est utilisée pour l'écriture de flux de caractères filtrés. Cette classe elle-même fournit des méthodes par défaut qui passe toutes les requêtes vers le flux contenu. Les sous-classes de FilterWriter doivent surcharger certaines de ces méthodes et peuvent aussi fournir des méthodes et des champs additionnels.

Les champs
protected Writer out
Ce champ représente le flux de sortie de caractères sous-jacent.
Les champs hérités de la classe java.io.Writer
lock

Les constructeurs
protected FilterWriter(Writer out)
crée un nouvel objet FilterWriter à partir d'un objet Writer passé en argument.

Les méthodes
void close()
ferme le flux.
void flush()
vide le flux.
void write(char[] cbuf, int off, int len)
écrit une partie d'un tableau de caractères, délimitée par une position de départ jusqu'à une certaine longueur, dans un flux.
void write(int c)
écrit un unique caractère dans le flux.
void write(String str, int off, int len)
écrit dans le flux, une portion d'une chaîne de caractères, délimitée par une position de départ jusqu'à une certaine longueur.
Les méthodes héritées de la classe java.io.Writer
write, write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.21 / La classe InputStream

La classe abstraite InputStream est la superclasse de toutes les classes représentant un flux d'entrée d'octets.

Les applications qui ont besoin de définir une sous-classe de InputStream doivent toujours fournir une méthode qui retourne le prochain octet d'entrée.

Les méthodes
int available()
retourne le nombre d'octets disponibles, qui peuvent être lus à partir du flux d'entrée sans entraîner de blocage.
void close()
ferme le flux d'entrée et libère toutes les ressources systèmes associées à ce flux.
void mark(int readlimit)
marque la position courante dans le flux d'entrée.
boolean markSupported()
teste si le flux d'entrée supporte les méthodes mark() et reset().
abstract int read()
lit le prochaine octet de données à partir du flux d'entrée.
int read(byte[] b)
lit dans le flux d'entrée, le même nombre d'octets que peut contenir le tableau passé en argument, et remplit toutes les cellules de ce dernier.
int read(byte[] b, int off, int len)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
void reset()
réinitialise le flux à la position de la dernière marque posée par la méthgode mark().
long skip(long n)
saute et abandonne le nombre d'octets de données spécifié à partir du flux d'entrée.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.22 / La classe InputStreamReader

Un objet InputStreamReader est un pont entre les flux d'entrée d'octets et ceux de caractères. Il lit des octets et les décode en caractères d'un jeu de caractères spécifié. Ce dernier peut être spécifié par un nom ou peut être donné explicitement , ou le jeu de caractères de la plateforme par défaut peut être accepté.

Chaque invocation de l'une des méthodes read() de l'objet InputStreamReader peuvent provoquer la lecture d'un ou plusieurs octets à partir du flux d'entrée d'octets sous-jacent. Pour activer la conversion effective d'octets vers des caractères, plusieurs octets peuvent être lus en avance à partir du flux sous-jacent autant de fois que cela est nécessaire pour satisfaire l'opération courante de lecture.

Pour plus d'efficacité, il faut envisager d'envelopper des objets InputStreamReader à l'intérieur d'objets BufferedReader.

Les champs
Les champs hérités de la classe java.io.Reader
lock

Les constructeurs
InputStreamReader(InputStream in)
crée un objet InputStreamReader à partir de l'objet InputStream et qui utilise le jeu de caractères par défaut de la plateforme sous-jacente.
InputStreamReader(InputStream in, Charset cs)
crée un objet InputStreamReader à partir de l'objet InputStream et qui utilise le jeu de caractères désigné par un objet Charset.
InputStreamReader(InputStream in, CharsetDecoder dec)
crée un objet InputStreamReader à partir de l'objet InputStream et qui utilise le jeu de caractères désigné par un objet CharsetDecoder.
InputStreamReader(InputStream in, String charsetName)
crée un objet InputStreamReader à partir de l'objet InputStream et qui utilise le jeu de caractères désigné par son nom.

Les méthodes
void close()
ferme le flux.
String getEncoding()
retourne le nom de l'encodage de caractères utilisé par le flux.
int read()
lit un unique caractère du flux.
int read(char[] cbuf, int offset, int length)
lit dans le flux d'entrée, un certain nombre d'octets que peut contenir le tableau passé en argument, et remplit les cellules de ce dernier en commençant à une position de départ jusqu'à une certaine longueur.
boolean ready()
indique si le flux est prêt à être lu.
Les méthodes héritées de la classe java.io.Reader
mark, markSupported, read, reset, skip
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.23 / La classe LineNumberReader

La classe LineNumberReader représente un flux d'entrée de caractères qui conserve la piste des numéros de ligne.

La classe LineNumberReader définit les méthodes setLineNumber(int) et getLineNumber() pour respcetivement fixer ou obtenir le nombre de lignes courant. Par défaut ce nombre est égal à zéro.

Le terminateur d'une ligne peut prendre plusieurs formes selon la plateforme sous-jacente :

Les champs
Les champs hérités de la classe java.io.Reader
lock

Les constructeurs
LineNumberReader(Reader in)
crée un nouvel objet LineNumberReader en utilisant un objet Reader et une taille de mémoire tampon par défaut.
LineNumberReader(Reader in, int sz)
crée un nouvel objet LineNumberReader en utilisant un objet Reader et une taille de mémoire tampon spécifiée.

Les méthodes
int getLineNumber()
obtient le numéro de ligne courante.
void mark(int readAheadLimit)
marque la position courante dans le flux.
int read()
lit un unique caractère.
int read(char[] cbuf, int off, int len)
lit les caractères à partir du flux et remplit le tableau de caractères dans les limites spécifiées.
String readLine()
lit une ligne de texte.
void reset()
réinitialise le flux à la marque la plus récente.
void setLineNumber(int lineNumber)
fixe le numéro de ligne courante.
long skip(long n)
saute un certain nombre de caractères.
Les méthodes héritées de la classe java.io.BufferedReader
close, markSupported, ready
Les méthodes héritées de la classe java.io.Reader
read
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.24 / La classe ObjectInputStream

Une classe ObjectInputStream désérialise des données et des objets primitifs précédemment écrits en utilisant un objet ObjectOutputStream.

Les classes imbriquées
static class ObjectInputStream.GetField
fournit l'accès à des champs persistants lus à partir du flux d'entrée.

Les champs
Les champs hérités de l'interface java.io.ObjectStreamConstants
baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2,
SC_BLOCK_DATA, SC_EXTERNALIZABLE, SC_SERIALIZABLE,
SC_WRITE_METHOD, STREAM_MAGIC, STREAM_VERSION,
SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION,
TC_ARRAY, TC_BASE, TC_BLOCKDATA, TC_BLOCKDATALONG, TC_CLASS,
TC_CLASSDESC, TC_ENDBLOCKDATA, TC_EXCEPTION, TC_LONGSTRING,
TC_MAX, TC_NULL, TC_OBJECT, TC_PROXYCLASSDESC, TC_REFERENCE,
TC_RESET, TC_STRING

Les constructeurs
protected ObjectInputStream()
fournit une manière pour les sous-classes qui sont complétement réimplémentées à n'avoir pas allouer des données privées juste utilisées par l'implémentation de l'objet ObjectInputStream.
ObjectInputStream(InputStream in)
crée un objet ObjectInputStream qui lit à partir de l'objet InputStream passé en argument.

Les méthodes
int available()
retourne le nombre d'octets disponibles qui peuvent être lus sans entraîner de blocage.
void close()
ferme l'objet ObjectInputStream.
void defaultReadObject()
lit les champs non-static et non-transient de la classe courante de l'objet ObjectInputStream.
protected boolean enableResolveObject(boolean enable)
active le flux pour autoriser les objets à lire à partir du flux pour être remplacé.
int read()
lit un octet de données.
int read(byte[] buf, int off, int len)
lit un objet ObjectInputStream et remplit le tableau d'octets.
boolean readBoolean()
lit un booléen.
byte readByte()
lit un octet byte codé sur 8 bits.
char readChar()
lit un caractère char codé sur 16 bits.
protected ObjectStreamClass readClassDescriptor()
lit un descripteur de classe à partir d'un flux de désérialisation.
double readDouble()
lit un nombre réel double codé sur 64 bits.
ObjectInputStream.GetField readFields()
lit les champs persistants à partir du flux et les rend disponible par nom.
float readFloat()
lit un nombre réel float codé sur 32 bits.
void readFully(byte[] buf)
lit des octets, et bloque tant que tous les octets ne sont pas lus.
void readFully(byte[] buf, int off, int len)
lit des octets, et bloque tant que tous les octets ne sont pas lus.
int readInt()
lit un entier int codé sur 32 bits.
String readLine()
Dépréciée. Voir DataInputStream.
long readLong()
lit un entier long codé sur 64 bits.
Object readObject()
lit un objet à partir de l'objet ObjectInputStream.
protected Object readObjectOverride()
est appelée par des sous-classes fiables de l'objet ObjectOutputStream qui a été construit en utilisant le constructeur sans argument.
short readShort()
lit un entier short codé sur 16 bits.
protected void readStreamHeader()
fournit pour permettre aux sous-classes de lire et vérifier leurs propres entêtes de flux.
Object readUnshared()
lit un objet non-partagé à partir de l'objet ObjectInputStream.
int readUnsignedByte()
lit un entier byte codé sur 8 bits et non-signé.
int readUnsignedShort()
lit un entier short codé sur 16 bits et non-signé.
String readUTF()
lit une chaîne de caractères au format UTF.
void registerValidation(ObjectInputValidation obj, int prio)
recommande un objet pour une validation avant que le graphe soit retourné.
protected Class resolveClass(ObjectStreamClass desc)
charge l'équivalent de la classe locale de la description de classe de flux.
protected Object resolveObject(Object obj)
permet de se fier à des sous-classes de ObjectInputStream pour substituer un objet à un autre durant une désérialisation.
protected Class resolveProxyClass(String[] interfaces)
retourne une classe proxy qui implémente les interfaces désignées dans un descripteur de classe proxy. Les sous-classes peuvent implémenter cette méthode pour lire des données habituelles à partir du flux avec les decripteurs pour les classes proxy dynamiques, en les suivant pour utiliser un mécanisme de chargement alternatif pour les interfaces et la classe proxy.
int skipBytes(int len)
saute des octets et bloque jusqu'à ce que le nombre d'octets spécifié soit traité.
Les méthodes héritées de l'interface java.io.ObjectInput
read, skip
Les méthodes héritées de la classe java.io.InputStream
mark, markSupported, read, reset, skip
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.25 / La classe ObjectInputStream.GetField

La classe abstraite ObjectInputStream.GetField fournit un accès à des champs persistants lus à partir du flux d'entrée.

Les constructeurs
ObjectInputStream.GetField()
crée un nouvel objet ObjectInputStream.GetField.

Les méthodes
abstract boolean defaulted(String name)
retourne true si le champ désigné n'est pas présent et n'a pas de valeur dans le flux.
abstract boolean get(String name, boolean val)
obtient la valeur du champ de type boolean désigné à partir du champ persistant.
abstract byte get(String name, byte val)
obtient la valeur du champ de type byte désigné à partir du champ persistant.
abstract char get(String name, char val)
obtient la valeur du champ de type char désigné à partir du champ persistant.
abstract double get(String name, double val)
obtient la valeur du champ de type double désigné à partir du champ persistant.
abstract float get(String name, float val)
obtient la valeur du champ de type float désigné à partir du champ persistant.
abstract int get(String name, int val)
obtient la valeur du champ de type int désigné à partir du champ persistant.
abstract long get(String name, long val)
obtient la valeur du champ de type long désigné à partir du champ persistant.
abstract Object get(String name, Object val)
obtient la valeur du champ de type Object désigné à partir du champ persistant.
abstract short get(String name, short val)
obtient la valeur du champ de type short désigné à partir du champ persistant.
abstract ObjectStreamClass getObjectStreamClass()
obtient l'objet ObjectStreamClass qui décrit les champs dans le flux.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.26 / La classe ObjectOutputStream

Un objet ObjectOutputStream écrit des types de données primitives et des graphes d'objets Java dans un objet OutputStream. Les objets peuvent être lus en utilisant un objet ObjectInputStream. Les objets de stockage persistant peuvent petre réalisés en utilisant un fichier pour le flux. Si ce dernier est un flux de socket de réseau, les objets peuvent etre reconstitués sur un autre hôte ou un autre processus.

Seulement les objets qui supportent l'interface java.io.Serializable peuvent être écrits dans des flux. La classe de chaque objet sérialisable est encodée en incluant le nom et la signature de la classe, les valeurs des tableaux et champs de l'objet, et la fermeture de n'importe quels autres objets référencés à partir des objets initiaux.

Les classes imbriquées
static class ObjectOutputStream.PutField
fournit un accès programmatique aux champs persistants pour être écrit vers l'objet ObjectOutput.

Les champs
Les champs hérités de l'interface java.io.ObjectStreamConstants
baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2,
SC_BLOCK_DATA, SC_EXTERNALIZABLE, SC_SERIALIZABLE,
SC_WRITE_METHOD, STREAM_MAGIC, STREAM_VERSION,
SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION,
TC_ARRAY, TC_BASE, TC_BLOCKDATA, TC_BLOCKDATALONG, TC_CLASS,
TC_CLASSDESC, TC_ENDBLOCKDATA, TC_EXCEPTION, TC_LONGSTRING,
TC_MAX, TC_NULL, TC_OBJECT, TC_PROXYCLASSDESC, TC_REFERENCE,
TC_RESET, TC_STRING

Les constructeurs
protected ObjectOutputStream()
fournit une manière pour les sous-classes réimplémentant complètement l'objet ObjectOutputStream Provide a way for subclasses that are completely reimplementing ObjectOutputStream, pour ne pas allouer des données privées seulement utilisées par l'implémentation de l'objet ObjectOutputStream.
ObjectOutputStream(OutputStream out)
crée un objet ObjectOutputStream qui écrit dans l'objet OutputStream spécifié.

Les méthodes
protected void annotateClass(Class cl)
Les sous-classes peuvent implémenter la méthode annotateClass pour permettre aux données de la classe d'être stockées dans le flux.
protected void annotateProxyClass(Class cl)
Les sous-classes peuvent implémenter la méthode annotateProxyClass pour dtocker des données habituelles dans le flux avec des descripteurs de classes de proxy dynamiques.
void close()
ferme le flux.
void defaultWriteObject()
écrit des champs non-static et non-transient de la classe courante dans le flux.
protected void drain()
draine les données mises en mémoire tampon dans l'objet ObjectOutputStream.
protected boolean enableReplaceObject(boolean enable)
active le flux pour effectuer du remplacement d'objets dans le flux.
void flush()
vide le flux.
ObjectOutputStream.PutField putFields()
récupère l'objet utilisé pour mettre en mémoire tampon les champs persistants afin d'être écrit dans le flux..
protected Object replaceObject(Object obj)
La méthode replaceObject permet de se fier à des sous-classes de ObjectOutputStream pour substituer un objet à un autre durant un sérialisation.
void reset()
réinitialise sans tenir compte de l'état des objets déjà écrits dans le flux.
void useProtocolVersion(int version)
spécifie la version du protocole du flux à utiliser lors de l'écriture dans le flux.
void write(byte[] buf)
écrit un tableau d'octets dans le flux.
void write(byte[] buf, int off, int len)
écrit une partie d'un tableau d'octets dans le flux.
void write(int val)
écrit un octet.
void writeBoolean(boolean val)
écrit un valeur de type boolean.
void writeByte(int val)
écrit une valeur de type byte codée sur 8 bits.
void writeBytes(String str)
écrit une chaîne de caractères comme une séquence d'octets.
void writeChar(int val)
écrit une valeur de type char codée sur 16 bits.
void writeChars(String str)
écrit une chaîne de caractères comme une séquence de caractères.
protected void writeClassDescriptor(ObjectStreamClass desc)
écrit le descripteur de classe spécifiée dans le flux.
void writeDouble(double val)
écrit une valeur de type double codée sur 64 bits.
void writeFields()
écrit des champs mie en mémoire tampon dans le flux.
void writeFloat(float val)
écrit une valeur de type float codée sur 32 bits.
void writeInt(int val)
écrit une valeur de type int codée sur 32 bits.
void writeLong(long val)
écrit une valeur de type long codée sur 64 bits.
void writeObject(Object obj)
écrit l'objet spécifié dans le flux.
protected void writeObjectOverride(Object obj)
surcharge la méthode writeObject par défaut.
void writeShort(int val)
écrit une valeur de type short codée sur 16 bits.
protected void writeStreamHeader()
fournit des sous-classes pouvant ajouter à la fin ou au début leur propre entête dans le flux.
void writeUnshared(Object obj)
écrit un objet non-partagé dans le flux.
void writeUTF(String str)
écrit dans le flux, une chaîne de caractères au format UTF.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.27 / La classe ObjectOutputStream.PutField

La classe ObjectOutputStream.PutField fournit un accès programmatique aux champs persistants afin d'être écrits dans l'objet ObjectOutput.

Les constructeurs
ObjectOutputStream.PutField()
crée une nouvelle instance de la classe ObjectOutputStream.PutField.

Les méthodes
abstract void put(String name, boolean val)
place le valeur du champ de type boolean désigné à l'intérieur du champ persistant.
abstract void put(String name, byte val)
place le valeur du champ de type byte désigné à l'intérieur du champ persistant.
abstract void put(String name, char val)
place le valeur du champ de type char désigné à l'intérieur du champ persistant.
abstract void put(String name, double val)
place le valeur du champ de type double désigné à l'intérieur du champ persistant.
abstract void put(String name, float val)
place le valeur du champ de type float désigné à l'intérieur du champ persistant.
abstract void put(String name, int val)
place le valeur du champ de type int désigné à l'intérieur du champ persistant.
abstract void put(String name, long val)
place le valeur du champ de type long désigné à l'intérieur du champ persistant.
abstract void put(String name, Object val)
place le valeur du champ de type Object désigné à l'intérieur du champ persistant.
abstract void put(String name, short val)
place le valeur du champ de type short désigné à l'intérieur du champ persistant.
abstract void write(ObjectOutput out)
Dépréciée. Voir ObjectOutputStream.writeFields().
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.28 / La classe ObjectStreamClass

La classe ObjectStreamClass représente un descripteur de sérialisation pour les classes. Elle contient le nom et un identificateur unique de flux, serialVersionUID, de la classe. L'objet ObjectStreamClass pour une classe spécifique chargée dans la Machine Virtuelle peut être trouvé ou créé en utilisant la méthode lookup().

L'algorithme qui calcule la valeur de SerialVersionUID est décrit dans la spécification de la sérialisation d'objet, section 4.4, Identificateurs uniques de flux.

Les champs
static ObjectStreamField[] NO_FIELDS
Ce champ représente la valeur serialPersistentFields indiquant des champs non-sérialisable.

Les méthodes
Class forClass()
retourne la classe dans la Machine Virtuelle Java locale que cette version a organisé.
ObjectStreamField getField(String name)
obtient le champ de la classe ObjectStreamClass à l'aide de son nom.
ObjectStreamField[] getFields()
retourne un tableau de champs de la classe sérialisable.
String getName()
obtient le nom de la classe décrite par le descripteur.
long getSerialVersionUID()
retourne l'identificateur unique de flux pour la classe ObjectStreamClass.
static ObjectStreamClass lookup(Class cl)
trouve le descripteur d'une classe pouvant être sérialisée.
String toString()
retourne une chaîne de caractères représentant l'objet ObjectStreamClass.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

40.29 / La classe ObjectStreamField

La classe ObjectStreamField représente une description d'un champ Serializable à partir d'une classe Serializable. Un tableau de ObjectStreamFields est utilisé pour déclarer les champs sérialisables d'une classe.

Les constructeurs
ObjectStreamField(String name, Class type)
crée un objet ObjectStreamField à l'aide d'un nom et d'un objet Class.
ObjectStreamField(String name, Class type, boolean unshared)
crée un objet ObjectStreamField à l'aide d'un nom, d'un objet Class, et d'un booléen indiquant si l'objet peut être partagé lors d'opérations de lecture ou d'écriture.

Les méthodes
int compareTo(Object obj)
compare l'objet ObjectStreamField avec un autre objet.
String getName()
obtient le nom de l'objet.
int getOffset()
obtient la position du champ à l'intérieur des données d'instance.
Class getType()
obtient le type du champ.
char getTypeCode()
retourne l'encodage de caractères du type de champ.
String getTypeString()
retourne la signature type de la Machine Virtuelle Java.
boolean isPrimitive()
retourne true si le champ a un type primitif.
boolean isUnshared()
retourne une valeur booléenne indiquant si le champ sérialisable représenté par l'objet ObjectStreamField est ou n'est partagé.
protected void setOffset(int offset)
se positionne à l'index spécifié dans l'objet ObjectStreamField.
String toString()
retourne une chaîne de caractères décrivant l'objet ObjectStreamField.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

40.30 / La classe OutputStream

La classe abstraite OutputStream est la superclasse de toutes les classes représentant un flux de sortie d'octets. Un objet OutputStream accepte des octets de sortie et les envoie vers son propre réservoir.

Les applications nécessitant de définir un sous-classe de OutputStream doivent toujours fournir au moins une méthode qui écrit un octet de sortie.

Les constructeurs
OutputStream()
crée un nouvel objet OutputStream.

Les méthodes
void close()
ferme l'objet OutputStream et libère toutes les ressources systèmes associées au flux.
void flush()
vide l'objet OutputStream et oblige les octets de sortie placés en mémoire tampon à être écrit.
void write(byte[] b)
écrit tous les octets du tableau spécifié dans le flux de sortie.
void write(byte[] b, int off, int len)
écrit une portion des octets du tableau, délimitée par une certaine position de départ et jusqu'à une longueur spécifiés, dans le flux de sortie.
abstract void write(int b)
écrit l'octet spécifié dans le flux de sortie.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.31 / La classe OutputStreamWriter

La classe OutputStreamWriter est un pont entre les flux de caractères vers des flux d'octets. Les caractères écrits vers ce dernier sont encodés en octets utilisant un jeu de caractères spécifié. Le jeu de caractères qu'il utilise peut être spécifié par son nom, peut être donné explicitement, ou celui de la plateforme par défaut peut être accepté.

Chaque invocation de la méthode write() provoque l'invocation d'un convertisseur d'encodage sur les caractères données. Les octets résultants sont accumulés dans la mémoire tampon avant d'être écrits dans le flux de sortie sous-jacent. La taille de la mémoire tampon peut être spécifié, mais par défaut, elle est plus grande pour la plupart des objectifs. Il faut noter que les caractères passés à la méthode write() ne sont pas mis en mémoire tampon.

Pour plus d'efficacités, il est conseillé d'envelopper un ObjectStreamWriter à l'intérieur d'un objet BufferedWriter de telle manière à éviter de trop fréquentes invocation du convertisseur.

Les champs
Les champs hérités de la classe java.io.Writer
lock

Les constructeurs
OutputStreamWriter(OutputStream out)
crée un objet OutputStreamWriter à partir d'un objet OutputStream et qui utilise l'encodage de caractères par défaut.
OutputStreamWriter(OutputStream out, Charset cs)
crée un objet OutputStreamWriter à partir d'un objet OutputStream et qui utilise l'encodage de caractères fourni par un objet Charset.
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
crée un objet OutputStreamWriter à partir d'un objet OutputStream et qui utilise l'encodage de caractères fourni par un objet CharsetEncoder.
OutputStreamWriter(OutputStream out, String charsetName)
crée un objet OutputStreamWriter à partir d'un objet OutputStream et qui utilise l'encodage de caractères fourni par un objet String.

Les méthodes
void close()
ferme le flux.
void flush()
vide le flux.
String getEncoding()
retourne le nom de l'encodage de caractères utilisé par le flux.
void write(char[] cbuf, int off, int len)
écrit une portion d'un tableau d'octets, délimitée par une position de départ et jusqu'à une certaine longueur, dans le flux.
void write(int c)
écrit un seul caractère dans le flux.
void write(String str, int off, int len)
écrit une sous-chaîne d'un objet String, délimitée par une position de départ et jusqu'à une certaine longueur.
Les méthodes héritées de la classe java.io.Writer
write, write
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.32 / La classe PipedInputStream

Une instance de la classe PipedInputStream doit être connectée à un objet PipedOutputStream. Il fournit alors des octets de données qui sont écrits dans l'objet PipedOutputStream.

Typiquement, les données sont lues à partir d'un objet PipedInputStream par un thread et les données sont écrites dans l'objet PipedOutputStream correspondant par un autre thread. La tentative d'utiliser les deux objets à partir d'un seul thread, n'est pas recommandée à cause de risques de blocage du thread. L'objet PipedInputStream contient une mémoire tampon découplant les opérations de lecture à partir d'opération d'écriture dans certaines limites.

Les champs
protected byte[] buffer
Ce champ représente la mémoire tampon circulaire dans lequel les données entrantes sont placées.
protected int in
Ce champ représente l'index de la position dans la mémoire tampon circulaire où le prochaîn octet de données sera stocké à partir de l'objet PipedOutputStream connecté.
protected int out
Ce champ représente l'index de la position dans la mémoire tampon circulaire où le prochaîn octet de données sera lu par l'objet PipedInputStream.
protected static int PIPE_SIZE
Ce champ représente la mémoire tampon d'entrée circulaire du conduit.

Les constructeurs
PipedInputStream()
crée un PipedInputStream qui n'est pas encore connecté.
PipedInputStream(PipedOutputStream src)
crée un PipedInputStream qui est connecté à l'objet PipedOutputStream passé en argument.

Les méthodes
int available()
retourne le nombre d'octets qui peuvent être lus à partir de l'objet PipedInputStream sans entraîner de blocage.
void close()
ferme l'objet PipedInputStream et libère toutes les ressources qui lui sont associées.
void connect(PipedOutputStream src)
provoque la connection de l'objet PipedInputStream à un objet PipedOutputStream passé en argument.
int read()
lit le prochain octet de données à partir de l'objet PipedInputStream.
int read(byte[] b, int off, int len)
lit une certaine quantité d'octets dans le flux et les renvoie dans le tableau passé en argument.
protected void receive(int b)
reçoit un octet de données.
Les méthodes héritées de la classe java.io.InputStream
mark, markSupported, read, reset, skip
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.33 / La classe PipedOutputStream

Une instance de la classe PipedOutputStream peut être connectée à un objet PipedInputStream afin de créer un conduit de communication. L'objet PipedOutputStream est la fin d'envoi du conduit.

Typiquement, les données sont écrites dans un objet PipedOutputStream par un thread et les données sont lues à partir de l'objet PipedInputStream connecté par un autre thread. La tentative d'utiliser les deux objets à partir d'un seul thread, n'est pas recommandée à cause de risques de blocage du thread.

Les constructeurs
PipedOutputStream()
crée un PipedOutputStream qui n'est pas encore connecté à un objet PipedInputStream.
PipedOutputStream(PipedInputStream snk)
crée un PipedOutputStream connecté à un objet PipedInputStream passé en argument.

Les méthodes
void close()
ferme l'objet PipedOutputStream et libère toutes les ressources systèmes associées au flux.
void connect(PipedInputStream snk)
connecte l'objet PipedOutputStream à un autre objet receveur PipedInputStream.
void flush()
vide l'objet PipedOutputStream et force les octets de sortie placés en mémoire tampon à être écrit.
void write(byte[] b, int off, int len)
écrit une portion des octets du tableau spécifié, délimitée par une position de départ et jusqu'à une certaine longueur, dans le flux.
void write(int b)
écrit l'octet spécifié dans le flux.
Les méthodes héritées de la classe java.io.OutputStream
write
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.34 / La classe PipedReader

La classe PipedReader canalise les flux d'entrée de caractères.

Les champs
Les champs hérités de la classe java.io.Reader
lock

Les constructeurs
PipedReader()
crée un objet PipedReader qui n'est pas encore connecté.
PipedReader(PipedWriter src)
crée un objet PipedReader connecté à l'objet PipedWriter passé en argument.

Les méthodes
void close()
ferme l'objet PipedReader et libère toutes les ressources systèmes associées au flux.
void connect(PipedWriter src)
connecte l'objet PipedReader à un objet PipedWriter.
int read()
lit le prochain caractères de données à partir du flux.
int read(char[] cbuf, int off, int len)
lit une certaine longueur de caractères à partir d'une position spécifiée dans l'objet PipedReader et remplit le tableau de caractères avec le résultat de la lecture.
boolean ready()
indique si le flux est prêt à être lu.
Les méthodes héritées de la classe java.io.Reader
mark, markSupported, read, reset, skip
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.35 / La classe PipedWriter

La classe PipedWriter canalise les flux de sortie de caractères.

Les champs
Les champs hérités de la classe java.io.Writer
lock

Les constructeurs
PipedWriter()
crée un objet PipedWriter qui n'est pas encore connecté à un objet PipedReader.
PipedWriter(PipedReader snk)
crée un objet PipedWriter connecté à un objet PipedReader passé en argument.

Les méthodes
void close()
ferme l'objet PipedWriter et libère toutes les ressources systèmes associées au flux.
void connect(PipedReader snk)
connecte l'objet PipedWriter à un objet receveur PipedReader.
void flush()
vide l'objet PipedWriter et force les caractères de sortie mis en mémoires tampon à être écrits.
void write(char[] cbuf, int off, int len)
écrit dans l'objet PipedWriter, une portion du tableau de caractères délimitée par une position de départ et jusqu'à une certaine longueur.
void write(int c)
écrit le caractère spécifiée dans l'objet PipedWriter.
Les méthodes héritées de la classe java.io.Writer
write, write, write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.36 / La classe PrintStream

Un objet PrintStream ajoute des fonctionnalités à un autre flux de sortie, c'est-à-dire, la faculté d'imprimer des représentations de valeurs de données diverses commodément.

Les champs
Les champs hérités de la classe java.io.FilterOutputStream
out

Les constructeurs
PrintStream(OutputStream out)
crée un nouvel objet PrintStream sans vidage de ligne automatique à partir d'un objet OutputStream existant.
PrintStream(OutputStream out, boolean autoFlush)
crée un nouvel objet PrintStream en spécifiant si un vidage de ligne automatique doit être effectué et à partir d'un objet OutputStream existant.
PrintStream(OutputStream out, boolean autoFlush, String encoding)
crée à partir d'un objet OutputStream existant, un nouvel objet PrintStream en spécifiant si un vidage de ligne automatique doit être effectué et _un encodage de caractères.

Les méthodes
boolean checkError()
vide le flux et vérifie l'état d'erreur.
void close()
ferme le flux.
void flush()
vide le flux.
void print(boolean b)
imprime une valeur de type boolean.
imprime une valeur de type char.
Print a character.
void print(char[] s)
imprime un tableau de caractères.
void print(double d)
imprime une valeur de type double.
void print(float f)
imprime une valeur de type float.
void print(int i)
imprime une valeur de type int.
void print(long l)
imprime une valeur de type long.
void print(Object obj)
imprime un objet.
void print(String s)
imprime une chaîne de caractères.
void println()
termine la ligne courante en écrivant un terminateur de ligne.
void println(boolean x)
imprime une valeur de type boolean avec un terminateur de ligne.
void println(char x)
imprime une valeur de type char avec un terminateur de ligne.
void println(char[] x)
imprime un tableau de caractères avec un terminateur de ligne.
void println(double x)
imprime une valeur de type double avec un terminateur de ligne.
void println(float x)
imprime une valeur de type float avec un terminateur de ligne.
void println(int x)
imprime une valeur de type int avec un terminateur de ligne.
void println(long x)
imprime une valeur de type long avec un terminateur de ligne.
void println(Object x)
imprime un objet avec un terminateur de ligne.
void println(String x)
imprime une chaîne de caractères avec un terminateur de ligne.
protected void setError()
fixe l'état d'erreur du flux à true.
void write(byte[] buf, int off, int len)
écrit dans le flux, une portion d'un tableau d'octets, délimitée par une position de départ et jusqu'à une certaine longueur.
void write(int b)
écrit l'octet spécifié dans le flux.
Les méthodes héritées de la classe java.io.FilterOutputStream
write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.37 / La classe PrintWriter

La classe PrintWriter imprime des représentations formatées d'objets vers un flux de sortie textuel. Cette classe implémente toutes les méthodes d'impression trouvées dans la classe PrintStream. Il ne contient pas de méthodes pour l'écriture d'octets bruts, pour lequel un programme doit utiliser des flux d'octets décodés.

Les champs
protected Writer out
Ce champ représente le flux de sortie de caractères de l'objet PrintWriter.
Les champs hérités de la classe java.io.Writer
lock

Les constructeurs
PrintWriter(OutputStream out)
crée un nouvel objet PrintWriter sans vidage de ligne automatique à partir d'un objet OutputStream existant.
PrintWriter(OutputStream out, boolean autoFlush)
crée un nouvel objet PrintWriter à partir d'un objet OutputStream existant et en spécifiant si un vidage de ligne doit être effectué.
PrintWriter(Writer out)
crée un nouvel objet PrintWriter à partir d'un objet Writer sans vidage de ligne automatique.
PrintWriter(Writer out, boolean autoFlush)
crée un nouvel objet PrintWriter à partir d'un objet Writer existant et en spécifiant si un vidage de ligne doit être effectué.

Les méthodes
boolean checkError()
vide le flux s'il n'est pas fermé et vérifie son état d'erreur.
void close()
ferme le flux.
void flush()
vide le flux.
void print(boolean b)
imprime une valeur de type boolean.
void print(char c)
imprime une valeur de type char.
void print(char[] s)
imprime un tableau de caractères.
void print(double d)
imprime une valeur de type double.
void print(float f)
imprime une valeur de type float.
void print(int i)
imprime une valeur de type int.
void print(long l)
imprime une valeur de type long.
void print(Object obj)
imprime un objet.
void print(String s)
imprime une chaîne de caractères.
void println()
termine la ligne courante en écrivant le séparateur de ligne.
void println(boolean x)
imprime une valeur de type boolean avec une terminateur de ligne.
void println(char x)
imprime une valeur de type char avec une terminateur de ligne.
void println(char[] x)
imprime un tableau de caractères avec un terminateur de ligne.
void println(double x)
imprime une valeur de type double avec une terminateur de ligne.
void println(float x)
imprime une valeur de type float avec une terminateur de ligne.
void println(int x)
imprime une valeur de type int avec une terminateur de ligne.
void println(long x)
imprime une valeur de type long avec une terminateur de ligne.
void println(Object x)
imprime un objet avec une terminateur de ligne.
void println(String x)
imprime une chaîne de caractères avec une terminateur de ligne.
protected void setError()
indique qu'une erreur s'est produite.
void write(char[] buf)
écrit un tableau de caractères.
void write(char[] buf, int off, int len)
écrit une protion d'un tableau de caractères, délimitée par une position de départ et jusqu'à une certaine longueur.
void write(int c)
écrit un seul caractère.
void write(String s)
écrit une chaîne de caractères.
void write(String s, int off, int len)
écrit une sous-chaîne d'un objet String en commençant à une certaine position et jusqu'à une certaine longueur.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.38 / La classe PushbackReader

La classe PushbackReader est un lecteur de flux de caractères qui permet aux caractères d'être repoussé dans le flux.

Les champs hérités de la classe java.io.FilterReader
in
Les champs hérités de la classe java.io.Reader
lock

Les constructeurs
PushbackReader(Reader in)
crée un nouvel objet PushbackReader en se servant d'un objet Reader passé en argument.
PushbackReader(Reader in, int size)
crée un nouvel objet PushbackReader en se servant d'un objet Reader passé en argument et en spécifiant une taille pour la mémoire tampon.

Les méthodes
void close()
ferme le flux.
void mark(int readAheadLimit)
marque la position courante dans le flux.
boolean markSupported()
indique si le flux supporte la méthode mark().
int read()
lit un seul caractère.
int read(char[] cbuf, int off, int len)
lit une certaine longueur de caractères et à partir d'une position spécifiée et remplit le tableau avec le résultat de la lecture.
boolean ready()
indique si le flux est prêt à être lu.
void reset()
réinitialise le flux.
void unread(char[] cbuf)
repousse un tableau de caractères en le copiant vers le début de la mémoire tampon pushback.
void unread(char[] cbuf, int off, int len)
repousse une partie d'un tableau de caractères, délimitée par un position de départ et jusqu'à une certaine longueur en le copiant vers la mémoire tampon pushback.
void unread(int c)
repousse un seul caractère.
Les méthodes héritées de la classe java.io.FilterReader
skip
Les méthodes héritées de la classe java.io.Reader
read
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.39 / La classe RandomAccessFile

Les instances de la classe RandomAccessFile supporte la lecture et l'écriture vers un fichier à accès aléatoire. Ce dernier se comporte comme ugrand tableau d'octets stocké dans le système de fichiers.

Les constructeurs
RandomAccessFile(File file, String mode)
crée un objet RandomAccessFile pour lire et optionnelement écrire dans l'objet File spécifié en argument.
RandomAccessFile(String name, String mode)
crée un objet RandomAccessFile pour lire et optionnelement écrire dans le fichier spécifié en argument.

Les méthodes
void close()
ferme l'objet RandomAccessFile et libère toutes les ressources systèmes associées au flux.
FileChannel getChannel()
retourne l'objet unique FileChannel associé au fichier.
FileDescriptor getFD()
retourne un objet FileDescriptor non-transparent associé au flux.
long getFilePointer()
retourne la position courante dans le fichier.
long length()
retourne la longueur du fichier.
int read()
lit un octet de données à partir du fichier.
int read(byte[] b)
lit le nombre d'octets pouvant contenir le tableau, dans le flux et remplit le tableau avec le résultat de la lecture.
int read(byte[] b, int off, int len)
lit un nombre d'octets à partir d'une position de départ et jusqu'à une certaine longueur, dans le flux et remplit le tableau avec le résultat de la lecture.
boolean readBoolean()
lit une valeur booléenne à partir du fichier.
byte readByte()
lit la valeur d'un octet à partir du fichier.
char readChar()
lit un caractère Unicode à partir du fichier.
double readDouble()
lit une valeur de type double à partir du fichier.
float readFloat()
lit une valeur de type float à partir du fichier.
void readFully(byte[] b)
lit le nombre d'octets pouvant contenir le tableau à partir du fichier et en commençant au niveau du pointeur courant du fichier, et remplit le tableau avec le résultat de la lecture.
void readFully(byte[] b, int off, int len)
lit exactement une certaine longueur d'octets dans le fichier en commençant à une position de départ, et remplit le tableau avec le résultat de la lecture.
int readInt()
lit une valeur de type int à partir du fichier.
String readLine()
lit la prochaine ligne de texte à partir du fichier.
long readLong()
lit une valeur de type long à partir du fichier.
short readShort()
lit une valeur de type short à partir du fichier.
int readUnsignedByte()
lit un nombre non-signé de 8 bits, à partir du fichier.
int readUnsignedShort()
lit un nombre non-signé de 16 bits, à partir du fichier.
String readUTF()
lit une chaîne de caractères au format UTF-8 à partir du fichier.
void seek(long pos)
fixe le pointeur de fichier à la position spécifiée.
void setLength(long newLength)
fixe la longueur du fichier.
int skipBytes(int n)
tente de sauter un certain nombre d'octets d'entrée en abandonnant les octets sautés.
void write(byte[] b)
écrit tous les octets du tableau dans le fichier en démarrant à la position du pointeur de fichier.
void write(byte[] b, int off, int len)
écrit tous les octets du tableau dans le fichier en démarrant à la position spécifiée et jusqu'à une certaine longueur.
void write(int b)
écrit l'octet spécifié dans le fichier.
void writeBoolean(boolean v)
écrit une valeur de type boolean sous la forme d'un octet dans le fichier.
void writeByte(int v)
écrit une valeur de type byte sous la forme d'un octet dans le fichier.
void writeBytes(String s)
écrit un objet String dans le fichier comme une séquence d'octets.
void writeChar(int v)
écrit une valeur de type char sous la forme de deux octets dans le fichier.
void writeChars(String s)
écrit un objet String dans le fichier comme un séquence de caractères.
void writeDouble(double v)
convertit l'argument de type double en un long en utilisant la méthode doubleToLongBits() de la classe Double, et écrit alors cette valeur long dans le fichier sous la forme de quatre octets.
void writeFloat(float v)
convertit l'argument de type float en un int en utilisant la méthode floatToIntBits() de la classe Float, et écrit alors cette valeur int dans le fichier sous la forme de quatre octets.
void writeInt(int v)
écrit une valeur de type int sous la forme de quatre octets dans le fichier.
void writeLong(long v)
écrit une valeur de type long sous la forme de huit octets dans le fichier.
void writeShort(int v)
écrit une valeur de type short sous la forme de deux octets dans le fichier.
void writeUTF(String str)
écrit une chaîne de caractères dans le fichier encodé en UTF-8 d'une manière indépendante de la machine.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.40 / La classe Reader

La classe abstraite Reader est utilisée pour la lecture des flux de caractères. Les seules méthodes qu'une sous-classe doit implémenter sont read(char[], int, int) et close().

Toutefois, la plupart des sous-classes surchargeraient certaines des méthodes définies dans cette classe, afin de fournir une plus haute efficacité ou/et des fonctionnalités supplémentaires.

Les champs
protected Object lock
Ce champ représente l'objet utilisé pour les opérations de synchronisation sur le flux.

Les constructeurs
protected Reader()
crée un nouvel objet Reader duquel les parties critiques se synchroniseraient sur le lecteur lui-même.
protected Reader(Object lock)
crée un nouvel objet Reader duquel les parties critiques se synchroniseraient sur l'objet fourni.

Les méthodes
abstract void close()
ferme le flux.
void mark(int readAheadLimit)
marque la position courante dans le flux.
boolean markSupported()
indique si le flux supporte la méthode mark().
int read()
lit un seul caractère.
int read(char[] cbuf)
lit les caractères à partir du flux et les place dans le tableau passé en argument.
abstract int read(char[] cbuf, int off, int len)
lit les caractères à partir du flux en suivant une position de départ et jusqu'à une certaine longueur et les place dans le tableau passé en argument.
boolean ready()
indique si le flux est prêt à être lu.
void reset()
réinitialise le flux.
long skip(long n)
saute un certain nombre de caractères.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.41 / La classe SequenceInputStream

Un objet SequenceInputStream représente la concaténation logique d'autres flux d'entrée. Il commence avec un collection ordonnée de flux d'entrée et lit à partir du premier et jusqu'à ce que la fin du fichier soit atteinte, puis il recommence l'opération jusqu'au dernier des flux.

Les constructeurs
SequenceInputStream(Enumeration e)
crée un nouvel objet SequenceInputStream en mémorisant l'argument, lequel doit être un objet Enumeration qui produit des objets dont le type d'exécution est InputStream.
SequenceInputStream(InputStream s1, InputStream s2)
crée un nouvel objet SequenceInputStream en mémorisant les deux arguments InputStream qui sont lus l'un après l'autre pour fournir des octets destinés à être lus à partir de l'objet SequenceInputStream.

Les méthodes
int available()
retourne le nombre d'octets disponibles dans le flux courant.
void close()
ferme l'objet SequenceInputStream et libère toutes les ressources systèmes associées au flux.
int read()
lit le prochain octet de données à partir du flux.
int read(byte[] b, int off, int len)
lit une certaine longueur d'octets de données et à partir d'une position de départ, dans le flux d'entrée, et remplit le tableau avec le résultat de la lecture.
Les méthodes héritées de la classe java.io.InputStream
mark, markSupported, read, reset, skip
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.42 / La classe SerializablePermission

La classe SerializablePermission est utilisée pour les permissions sur les objets Serializable. Il contient un nom, appelé également un "nom cible", mais n'a pas de liste d'actions. Il est possible d'avoir ou de ne pas avoir la permission désignée.

Le nom cible est le nom de la permission de l'objet Serializable.

Les permissions
Nom cibleDescription
enableSubclassImplementation Cette permission permet l'implémentation de la sous-classe de ObjectOutputStream ou ObjectInputStream pour surcharger respectivement la sérialisation ou la désérialisation des objets.
enableSubstitution Cette permission permet la substitution d'un objet par un autre durant la sérialisation ou la désérialisation des objets.

Les constructeurs
SerializablePermission(String name)
crée un nouvel objet SerializablePermission avec le nom spécifié.
SerializablePermission(String name, String actions)
crée un nouvel objet SerializablePermission avec le nom et des actions spécifiés.

Les méthodes
Les méthodes héritées de la classe java.security.BasicPermission
equals, getActions, hashCode, implies, newPermissionCollection
Les méthodes héritées de la classe java.security.Permission
checkGuard, getName, toString
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

40.43 / La classe StreamTokenizer

La classe StreamTokenizer prend un flux d'entrée et l'analyse en jetons ("tokens"), autorisant les jetons à être lus à un moment.

Le processus d'analyse est contrôlé par une table et un nombre de drapeaux qui peuvent être fixés à des états variés. L'objet StreamTokenizer peut reconnaître des identificateurs, des nombres, des chaînes de caractères mises entre guillemets et des styles de commentaires différents.

Les champs
double nval
Si le jeton (token) courant est un nombre, ce champ contient la valeur de ce nombre.
String sval
Si le jeton (token) courant est un mot, ce champ contient une chaîne de caractères représentant ce mot.
static int TT_EOF
Ce champ représente une constante indiquant que la fin du flux a été lue.
static int TT_EOL
Ce champ représente une constante indiquant que la fin de la ligne a été lue.
static int TT_NUMBER
Ce champ représente une constante indiquant qu'un nombre a été lu.
static int TT_WORD
Ce champ représente une constante indiquant qu'un mot a été lu.
int ttype
Après un appel à la méthode nextToken, ce champ contien le type du jeton venant d'être lu.

Les constructeurs
StreamTokenizer(InputStream is)
Dépréciée. Voir l'objet StreamTokenizer(Reader r).
StreamTokenizer(Reader r)
crée un objet StreamTokenizer qui analyse le flux de caractères passé en argument.

Les méthodes
void commentChar(int ch)
spécifie que l'argument de type char démarre un commentaire de ligne unique.
void eolIsSignificant(boolean flag)
détermine si les fins de ligne doivent être traitées comme des jetons.
int lineno()
retourne le numéro de ligne courante.
void lowerCaseMode(boolean fl)
détermine si le mot doit être automatiquement converti en casse minuscule.
int nextToken()
analyse le prochain jeton à partir du flux d'entrée de l'objet StreamTokenizer.
void ordinaryChar(int ch)
spécifie que l'argument de type char est "ordinaire" dans l'objet StreamTokenizer.
void ordinaryChars(int low, int hi)
spécifie que tout les caractères dans l'intervalle [low-hi] sont ordinaires dans l'objet StreamTokenizer.
void parseNumbers()
spécifie que les nombres doivent être analysés par l'objet StreamTokenizer.
void pushBack()
entraîne le prochain appel de la méthode nextToken() de l'objet StreamTokenizer pour retourner la valeur courante dans le champ ttype et non pour modifier la valeur dans le champ nval ou sval.
void quoteChar(int ch)
spécifie que les paires correspondantes du caractère spécifié délimitent les constantes de chaînes de caractères dans l'objet StreamTokenizer.
void resetSyntax()
réinitialise la table de syntaxe de l'objet StreamTokenizer afin que tous les caractères soient "ordinaires". Voir ordinaryChar().
void slashSlashComments(boolean flag)
détermine si l'objet StreamTokenizer doit reconnaître les commentaires C++.
void slashStarComments(boolean flag)
détermine si l'objet StreamTokenizer doit reconnaître les commentaires C.
String toString()
retourne un objet String représentant l'objet StreamTokenizer courant.
void whitespaceChars(int low, int hi)
spécifie que tout les caractères dans l'intervalle [low-hi] sont des caractères d'espaces blancs.
void wordChars(int low, int hi)
spécifie que tout les caractères dans l'intervalle [low-hi] sont des composants de mots.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

40.44 / La classe StringReader

La classe StringReader représente un flux de caractères dont la sourceest une chaîne de caractères.

Les champs
Les champs hérités de la classe java.io.Reader
lock

Les constructeurs
StringReader(String s)
crée un nouvel objet StringReader.
Les méthodes
void close()
ferme le flux.
void mark(int readAheadLimit)
marque la position courante dans le flux.
boolean markSupported()
indique si le flux supporte la méthode mark().
int read()
lit un seul caractère.
int read(char[] cbuf, int off, int len)
lit une certaine longueur de caractères dans le flux et les ajoute dans une partie du tableau passé en argument, délimitée par une position de pépart et jusqu'à une certaine longueur.
boolean ready()
indique si le flux est prêt à être lu.
void reset()
réinitialise le flux à la marque la plus récente ou au commencement de la chaîne de caractères s'il n'a pas été marqué.
long skip(long ns)
saute des caractères.
Les méthodes héritées de la classe java.io.Reader
read
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

40.45 / La classe StringWriter

La classe StringWriter représente un flux de caractères qui recueille sa sortie dans un objet StringBuffer, lequel peut alors être utilisé pour construire une chaîne de caractères.

La fermeture d'un objet StringWriter n'a aucun effet. Les méthodes de cette classe peuvent être appelées après que le flux ait été fermé sans génération d'une exception IOException

Les champs
Les champs hérités de la classe java.io.Writer
lock

Les constructeurs
StringWriter()
crée un nouvel objet StringWriter utilisant la taille initiale par défaut de l'objet StringBuffer.
StringWriter(int initialSize)
crée un nouvel objet StringWriter utilisant la taille initiale de l'objet StringBuffer passée en argument.

Les méthodes
void close()
Ferme un objet StringWriter (aucun effet).
void flush()
vide le flux.
StringBuffer getBuffer()
retourne l'objet StringBuffer lui-même.
String toString()
retourne la valeur de la mémoire tampon courante comme une chaîne de caractères.
void write(char[] cbuf, int off, int len)
écrit une partie d'un tableau de caractères, délimitée par une position de départ et jusqu'à une certaine longueur, dans le flux.
void write(int c)
écrit un seul caractère.
void write(String str)
écrit une chaîne de caractères.
void write(String str, int off, int len)
écrit une portion de chaîne de caractères, délimitée par une position de départ et jusqu'à une certaine longueur, dans le flux.
Les méthodes héritées de la classe java.io.Writer
write
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

40.46 / La classe Writer

La classe abstraite Writer est utilisée pour l'écriture des flux de caractères.

Les seules méthodes qu'une sous-classe doit implémenter sont write(char[], int, int), flush(), et close(). Toutefois, la plupart de sous-classes surchargeront certaines des méthodes définies dans cette classe, afin de fournir une plus haute efficacité ou/et des fonctionnalités additionnelles.

Les champs
protected Object lock
Ce champ représente l'objet utilisé pour les opérations de synchronisation sur le flux.

Les constructeurs
protected Writer()
crée un nouvel objet Writer dont les parties critiques se synchroniseront sur l'objet Writer lui-même.
protected Writer(Object lock)
crée un nouvel objet Writer dont les parties critiques se synchroniseront sur l'objet passé en argument.

Les méthodes
abstract void close()
ferme le flux après l'avoir vidé.
abstract void flush()
vide le flux.
void write(char[] cbuf)
écrit un tableau de caractères dans le flux.
abstract void write(char[] cbuf, int off, int len)
écrit une partie d'un tableau de caractères, délimitée par une position de départ et jusqu'à une certaine longueur, dans le flux.
void write(int c)
écrit un seul caractère.
void write(String str)
écrit une chaîne de caractères.
void write(String str, int off, int len)
écrit une portion de chaîne de caractères, délimitée par une position de départ et jusqu'à une certaine longueur, dans le flux.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41 / Le paquetage java.net

Le paquetage java.net fournit les classes pour l'implémentation des applications réseaux. En utilisant les classes socket, il est possible de communiquer avec n'importe quel serveur sur Internet ou sur un réseau Intranet.

Des classes sont founies pour construire des applications utilisant des adresses URL (Universal Resource Locators) et récupérant des données sur des documents distants présents sur Internet ou un intranet.

Les interfaces
ContentHandlerFactory définit une fabrique pour des gestionnaires de contenu.
DatagramSocketImplFactory définit une fabrique pour les implémentations de socket de datagramme.
FileNameMap fournit un mécanisme pour déterminer à partir d'un nom de fichier, un type MIME.
SocketImplFactory définit une fabrique pour les implémentations de socket.
SocketOptions contient des méthodes d'interface pour obtenir et fixer les options de socket.
URLStreamHandlerFactory définit une fabrique pour les gestionnaires de protocole de flux d'URL.

Les classes
Authenticator represente un objet qui sait comment obtenir l'authentification pour une connexion réseau.
ContentHandler constitue la superclasse de toutes les classe qui lisent un objet à partir d'un URLConnection.
DatagramPacket représente un paquet de datagrammes.
DatagramSocket représente un socket pour l'envoi et la réception de paquets de datagrammes.
DatagramSocketImpl représente un dataramme abstrait et une classe de base pour l'implémentation de sockets multicast.
HttpURLConnection représente un objet URLConnection avec un support pour les caractéristiques HTTP spécifiques.
Inet4Address représente une adresse de protocole Internet (IP) version 4 (IPv4).
Inet6Address représente une adresse de protocole Internet (IP) version 6 (IPv6).
InetAddress représente une adresse de protocole Internet (IP).
InetSocketAddress implémente une adresse de socket IP : adresse IP et numéro de port ou nom d'hôte et numéro de port, dans le dernier cas une tentative est faite pour résoudre le nom d'hôte.
JarURLConnection représente un objet URLConnection pour une fichier d'archive Java (JAR) ou une entrée dans un fichier JAR.
MulticastSocket constitue un utilitaire pour l'envoi et la réception de paquets multi-distributions IP.
NetPermission est utilisée pour les permissions de réseau diverses.
NetworkInterface représente une interface réseau composée d'un nom et une liste d'adresses IP assignées à cette intefaface.
PasswordAuthentication représente un détenteur de données qui est utilisé par l'objet Authenticator.
ServerSocket implémente les sockets côté serveur.
Socket implémente les sockets côté client.
SocketAddress représente une adresse de socket sans adjonction de protocole.
SocketImpl constitue la superclasse commune de toutes les classes qui implémentent effectivement les sockets.
SocketPermission représente l'accès à un réseau via des sockets.
URI représente une référence URI (Uniform Resource Identifier).
URL représente une adresse URL (Uniform Resource Locator) pointant une ressource sur Internet ou un Intranet.
URLClassLoader est utilisée pour charger les classes et les ressources à partir d'un chemin de recherche d'adresses URL référant les répertoires et fichiers JAR.
URLConnection constitue la superclasse de toutes les classes qui représente un lien de communications entre l'application et l'adresse URL.
URLDecoder représente un utilitaire pour le décodage de formulaire HTML.
URLEncoder représente un utilitaire pour l'encodage de formulaire HTML.
URLStreamHandler constitue la superclasse commune de tous les gestionnaires de protocole de flux.

Les exceptions
BindException indiququ'une erreur s'est produite lors de la tentative de relier un socket à une adresse locale et un port.
ConnectException indique qu'une erreur s'est produite lors de la tentative de connecter un socket à une addresse distante et un port.
MalformedURLException indique qu'une URL mal formée a été trouvée.
NoRouteToHostException indique qu'une erreur s'est produite lors de la tentative de connecter un socket à une addresse distante et un port.
PortUnreachableException indique qu'un message inaccessibilité de port ICMP a été reçu sur un datagramme connecté.
ProtocolException indique qu'une erreur s'est produite dans le protocole sous-jacent, tel qu'une erreur TCP.
SocketException indique qu'une erreur s'est produite dans le protocole sous-jacent, tel qu'une erreur TCP.
SocketTimeoutException indique qu'une pause s'est produite sur un socket.
UnknownHostException indique que l'adresse IP d'un hôte a pu ne pas être déterminé.
UnknownServiceException indique qu'une exception de service inconnu s'est produite.
URISyntaxException indique qu'une chaîne de caractères n'a pu être analysé comme une référence URI.

41.1 / La classe Authenticator

La classe Authenticator représente un objet qui sait comment obtenir l'authentification pour une connexion réseau. Habituellement, cela est effectué par l'intermédaire d'un prompt invitant à saisir un login et un mot de passe.

Les applications utilisent cette classe en créant une sous-classe, et en enregistrant une instance de cette sous-classe avec le système et la méthode setDefault(). Lorsque l'authentification est requise, le système invoquerait une méthode sur la sous-classe (comme getPasswordAuthentication) La méthode de sous-classe peut poser une question à propos de l'authentification requise avec un nombre de méthodes héritées (getRequestingXXX()) et forme un messsage approprié pour l'utilisateur.

Toutes les méthodes qui requièrent l'authentification a une implémentation par défaut qui échoue.

Les constructeurs
Authenticator()
crée une nouvelle instance de la classe Authenticator.

Les méthodes
protected PasswordAuthentication getPasswordAuthentication()
est appelée lorsque le mot de passe est nécessaire.
protected String getRequestingHost()
obtient le nom de l'hôte du site ou du proxy requérant l'authentification ou null en cas d'indisponibilité.
protected int getRequestingPort()
obtient le numéro de port pour la connexion requise.
protected String getRequestingPrompt()
obtient la chaîne représentant le prompt, donnée par le demandeur.
protected String getRequestingProtocol()
obtient le protocole qui est requis par la connexion.
protected String getRequestingScheme()
obtient le schéma du demandeurcomme le HTTP scheme pour un firewall HTTP.
protected InetAddress getRequestingSite()
obtient l'objet InetAddress du site requérant l'autorisation, ou null en cas d'indisponibilité.
static PasswordAuthentication requestPasswordAuthentication(
InetAddress addr, int port, String protocol, String prompt, String scheme)
demande l'authentifiant qui a été enregistré par le système pour un mot de passe.
static PasswordAuthentication requestPasswordAuthenticationString host, (
InetAddress addr, int port, String protocol, String prompt, String scheme)
demande l'authentifiant qui a été enregistré par le système pour un mot de passe.
static void setDefault(Authenticator a)
fixe l'authentifiant qui serait utilisé par le code de gestion de réseau lorsqu'un proxy ou un serveur HTTP demande une authentification.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.2 / La classe ContentHandler

La classe abstraite ContentHandler est la superclasse de toutes les classes qui lisent un objet à partir d'un URLConnection.

Les constructeurs
ContentHandler()
crée une nouvelle instance de la classe ContentHandler.

Les méthodes
abstract Object getContent(URLConnection urlc)
lit le flux créé par la connexion d'un objet URL, et retourne un objet Object à partir de cela.
Object getContent(URLConnection urlc, Class[] classes)
lit le flux créé par la connexion d'un objet URL, et retourne un objet Object qui correspond à l'un des types références spécifiés.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.3 / La classe DatagramPacket

La classe DatagramPacket représente un paquet de datagrammes. Les paquets de datagrammes sont utilisés pour implémenter un service de livraison de paquets sans connexion.

Chaque message est routé à partir d'une machine vers une autre basée exclusivement sur l'information contenu à l'intérieur d'un paquet. Les paquets multiples envoyés à partir d'une machine vers une autre peuvent être routés différemment, et peuvent arriver dans n'importe quel ordre. La livraison de paquets n'est pas garantie.

Les constructeurs
DatagramPacket(byte[] buf, int length)
crée un objet DatagramPacket pour la réception de paquets d'une longueur spécifiée.
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
crée un objet DatagramPacket pour l'envoi de paquets d'une longueur spécifiée, vers le numéro de port de l'hôte indiqué par l'objet InetAddress.
DatagramPacket(byte[] buf, int offset, int length)
crée un objet DatagramPacket pour la réception de paquets d'une certaine longueur et en spécifiant une position dans la mémoire tampon représentée par le tableau d'octets.
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
crée un objet DatagramPacket pour l'envoi de paquets d'une certaine longueur et à partir d'une position dans le tableau d'octets, vers le numéro de port de l'hôte indiqué par l'objet InetAddress.
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
crée un objet DatagramPacket pour l'envoi de paquets d'une certaine longueur et à partir d'une position dans le tableau d'octets, vers l'hôte indiqué par l'objet SocketAddress.
DatagramPacket(byte[] buf, int length, SocketAddress address)
crée un objet DatagramPacket pour l'envoi de paquets d'une certaine longueur, vers l'hôte indiqué par l'objet SocketAddress.

Les méthodes
InetAddress getAddress()
retourne l'adresse IP de la machine vers laquelle ce datagramme a été envoyé ou à partir duquel le datagramme a été reçu.
byte[] getData()
retourne les données contenues dans la mémoire tampon.
int getLength()
retourne la longueur des données à envoyer ou de celles reçues.
int getOffset()
retourne la position des données à envoyer ou de celles reçues.
int getPort()
retourne le numéro de port de l'hôte distant vers lequel le datagramme a été envoyé ou à partir duquel le datagramme a été reçu.
SocketAddress getSocketAddress()
obtient l'objet SocketAddress, soit l'adresse IP et le numéro de port, de l'hôte distant qui a reçu ou envoyé le paquet.
void setAddress(InetAddress iaddr)
fixe l'adresse IP de la machine vers laquelle le datagramme est envoyé.
void setData(byte[] buf)
fixe les données de la mémoire tampon de l'objet.
void setData(byte[] buf, int offset, int length)
fixe les données de la mémoire tampon de l'objet, en spécifiant une position de départ et une certaine longueur.
void setLength(int length)
fixe la longueur du paquet.
void setPort(int iport)
fixe le numéro de port sur l'hôte distant vers lequel le datagramme est envoyé.
void setSocketAddress(SocketAddress address)
fixe l'objet SocketAddress, soit l'adresse IP et le numéro de port de l'hôte distant vers lequel le datagramme est envoyé.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.4 / La classe DatagramSocket

La classe DatagramSocket représente un socket pour l'envoi et la réception de paquets de datagrammes. Un socket de datagrammes est le point d'envoi et de réception pour le service de livraison de paquets.

Chaque paquet envoyé ou reçu sur un socket de datagrammes est individuellement adressé et routé. Les paquets multiples envoyés à partir d'une machine vers une autre peuvent être routés différemment et peuvent arriver dans n'importe quel ordre.

Les constructeurs
DatagramSocket()
crée un objet DatagramSocket et le relie à n'importe quel port disponible sur la machine locale hôte.
protected DatagramSocket(DatagramSocketImpl impl)
crée un objet DatagramSocket sans limite avec l'objet DatagramSocketImpl spécifié.
DatagramSocket(int port)
crée un objet DatagramSocket et le relie au port spécifié de la machine locale hôte.
DatagramSocket(int port, InetAddress laddr)
crée un objet DatagramSocket limité au numéro de port et à l'adresse indiqués.
DatagramSocket(SocketAddress bindaddr)
crée un objet DatagramSocket limité à l'adresse de socket locale spécifiée.
Les méthodes
void bind(SocketAddress addr)
relie l'objet DatagramSocket à l'adresse et au numéro de port spécifié par l'objet Socket Address.
void close()
ferme l'objet DatagramSocket.
void connect(InetAddress address, int port)
connecte le socket à une adresse distante pour ce socket.
void connect(SocketAddress addr)
connecte le socket à une adresse de socket distante (adresse IP et le numéro de port).
void disconnect()
déconnecte le socket.
boolean getBroadcast()
indique si l'option SO_BROADCAST est activé.
DatagramChannel getChannel()
retourne l'objet DatagramChannel unique associé à l'objet DatagramSocket.
InetAddress getInetAddress()
retourne l'adresse vers laquelle la socket est connectée.
InetAddress getLocalAddress()
retourne l'adresse locale vers laquelle le socket est limité.
int getLocalPort()
retourne le numéro de port de l'hôte local vers lequel le socket est limité.
SocketAddress getLocalSocketAddress()
retourne l'adresse du point d'arrivée auquel le socket est lié ou null s'il n'est pas encore relié.
int getPort()
retourne le numéro de port pour le socket.
int getReceiveBufferSize()
obtient la valeur de l'option SO_RCVBUF pour l'objet DatagramSocket, qui correspond à la taille de la mémoire tampon utilisée par la plateforme pour l'entrée sur ce socket de datagrammes.
SocketAddress getRemoteSocketAddress()
retourne l'adresse du point d'arrivée auquel le socket est connecté, ou null s'il n'est pas encore connecté.
boolean getReuseAddress()
indique si l'option SO_REUSEADDR est activée.
int getSendBufferSize()
obtient la valeur de l'option SO_SNDBUF pour l'objet DatagramSocket, qui représente la taille de la mémoire tampon utilisée par la plateforme pour la sortie sur ce socket de dtatagrammes.
int getSoTimeout()
récupère le paramètrage de l'option SO_TIMEOUT.
int getTrafficClass()
obtient la classe de trafic ou le type de service dans l'entête de datagrammes IP pour les paquets envoyés à partir de l'objet DatagramSocket.
boolean isBound()
retourne l'état de la liaison du socket.
boolean isClosed()
indique si le socket est ou n'est pas fermé.
boolean isConnected()
retourne l'état de connexion du socket.
void receive(DatagramPacket p)
reçoit un paquet de datagramme à partir du socket.
void send(DatagramPacket p)
envoie un paquets de datagrammes à partir du socket.
void setBroadcast(boolean on)
active ou désactive l'option SO_BROADCAST.
static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
fixe la fabrique (factory) d'implémentation de l'objet DatagramSocket pour l'application.
void setReceiveBufferSize(int size)
Sfixe l'option SO_RCVBUF à la valeur spécifiée pour l'objet DatagramSocket.
void setReuseAddress(boolean on)
active ou désactive l'option SO_REUSEADDR du socket.
void setSendBufferSize(int size)
fixe l'option SO_SNDBUF à la valeur spécifiée pour l'objet DatagramSocket.
void setSoTimeout(int timeout)
active ou désactive l'option SO_TIMEOUT avec un temps de pause exprimé en millisecondes.
void setTrafficClass(int tc)
fixe la classe de trafic ou l'octet de type de service dans l'entête de datagrammes IP pour les datagrammes envoyés à partir de l'objet DatagramSocket.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.5 / La classe DatagramSocketImpl

La classe DatagramSocketImpl représente un datagramme abstrait et une classe de base d'implémentation de socket multi-distribué.

Les champs
protected FileDescriptor fd
Ce champ représente le descripteur de fichier.
protected int localPort
Ce champ représente le numéro de port local.
Les champs hérités de l'interface java.net.SocketOptions
IP_MULTICAST_IF, IP_MULTICAST_IF2, IP_MULTICAST_LOOP, IP_TOS,
SO_BINDADDR, SO_BROADCAST, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE,
SO_RCVBUF, SO_REUSEADDR, SO_SNDBUF, SO_TIMEOUT, TCP_NODELAY

Les constructeurs
DatagramSocketImpl()
crée une nouvelle instance de la classe DatagramSocketImpl.

Les méthodes
protected abstract void bind(int lport, InetAddress laddr)
relie un objet DatagramSocket à une adresse et un port locaux.
protected abstract void close()
ferme le socket.
protected void connect(InetAddress address, int port)
connecte un objet DatagramSocket à une destination distante.
protected abstract void create()
crée un objet DatagramSocket.
protected void disconnect()
déconnecte un objet DatagramSocket à partir de sa destination distante.
protected FileDescriptor getFileDescriptor()
obtient le descripteur de fichier de l'objet DatagramSocket.
protected int getLocalPort()
obtient le numéro de port local.
protected abstract int getTimeToLive()
récupère l'option TTL (time-to-live).
protected abstract byte getTTL()
Dépréciée. Voir getTimeToLive().
protected abstract void join(InetAddress inetaddr)
joint le groupe multi-distribué en spécifiant un objet .
protected abstract void joinGroup(SocketAddress mcastaddr,
NetworkInterface netIf)
joint le groupe multi-distribué en spécifiant une interface de réseau et une adresse de socket.
protected abstract void leave(InetAddress inetaddr)
Leave the multicast group.
protected abstract void leaveGroup(SocketAddress mcastaddr,
NetworkInterface netIf)
quitte le groupe multi-distribué.
protected abstract int peek(InetAddress i)
examine le paquet pour savoir de quelle adresse il est parti.
protected abstract int peekData(DatagramPacket p)
examine le paquet pour savoir de quelle adresse il est parti.
protected abstract void receive(DatagramPacket p)
reçoit l'objet DatagramPacket.
protected abstract void send(DatagramPacket p)
envoie un objet DatagramPacket.
protected abstract void setTimeToLive(int ttl)
fixe l'option TTL (time-to-live).
protected abstract void setTTL(byte ttl)
Dépréciée. Voir setTimeToLive().
Les méthodes héritées de l'interface java.net.SocketOptions
getOption, setOption
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.6 / La classe HttpURLConnection

La classe HttpURLConnection est semblable à une classe URLConnection avec un support particulier pour les caractéristiques HTTP spécifique.

Chaque instance de la classe HttpURLConnection est utilisé pour fabriquer une seule requête mais la connexion du réseau sous-jacent vers le serveur HTTP peut être de toute évidence partagée par d'autres instances.

En appelant les méthodes close() sur les objets et d'un objet HttpURLConnection après une requête peut libérer les ressources réseau associées à cette instance mais n'a aucun effet sur n'importe quelle connexion persistante partagée. L'appel de la méthode disconnect() peut fermer le socket sous-jacent si une connexion persistante est autrement inoccupé à ce moment.

Les champs
static int HTTP_ACCEPTED
HTTP Status-Code 202: Accepté
static int HTTP_BAD_GATEWAY
HTTP Status-Code 502: Mauvaise passerelle
static int HTTP_BAD_METHOD
HTTP Status-Code 405: Méthode non-autorisée
static int HTTP_BAD_REQUEST
HTTP Status-Code 400: Mauvaise requête
static int HTTP_CLIENT_TIMEOUT
HTTP Status-Code 408: Arrêt de requête
static int HTTP_CONFLICT
HTTP Status-Code 409: Conflit
static int HTTP_CREATED
HTTP Status-Code 201: Créé
static int HTTP_ENTITY_TOO_LARGE
HTTP Status-Code 413: Entité de la requête trop grande
static int HTTP_FORBIDDEN
HTTP Status-Code 403: Interdit
static int HTTP_GATEWAY_TIMEOUT
HTTP Status-Code 504: Arrêt de la passerelle
static int HTTP_GONE
HTTP Status-Code 410: Parti
static int HTTP_INTERNAL_ERROR
HTTP Status-Code 500: Erreur interne du serveur
static int HTTP_LENGTH_REQUIRED
HTTP Status-Code 411: Longueur requise
static int HTTP_MOVED_PERM
HTTP Status-Code 301: Déplacé d'une façon permanente
static int HTTP_MOVED_TEMP
HTTP Status-Code 302: Redirigé temporairement
static int HTTP_MULT_CHOICE
HTTP Status-Code 300: Choix multiples
static int HTTP_NO_CONTENT
HTTP Status-Code 204: Aucun contenu
static int HTTP_NOT_ACCEPTABLE
HTTP Status-Code 406: Non-acceptable
static int HTTP_NOT_AUTHORITATIVE
HTTP Status-Code 203: Information non-autoritaire
static int HTTP_NOT_FOUND
HTTP Status-Code 404: Non-trouvé
static int HTTP_NOT_IMPLEMENTED
HTTP Status-Code 501: Non-implémenté
static int HTTP_NOT_MODIFIED
HTTP Status-Code 304: Non-modifié
static int HTTP_OK
HTTP Status-Code 200: OK
static int HTTP_PARTIAL
HTTP Status-Code 206: Contenu partiel
static int HTTP_PAYMENT_REQUIRED
HTTP Status-Code 402: Paiement requis
static int HTTP_PRECON_FAILED
HTTP Status-Code 412: Echec des conditions préalables
static int HTTP_PROXY_AUTH
HTTP Status-Code 407: Authentification Proxy requise
static int HTTP_REQ_TOO_LONG
HTTP Status-Code 414: Requête URI trop grande
static int HTTP_RESET
HTTP Status-Code 205: Contenu réinitialisé
static int HTTP_SEE_OTHER
HTTP Status-Code 303: Voir autre
static int HTTP_SERVER_ERROR
Déprécié
static int HTTP_UNAUTHORIZED
HTTP Status-Code 401: Non-autorisé
static int HTTP_UNAVAILABLE
HTTP Status-Code 503: Service indisponible
static int HTTP_UNSUPPORTED_TYPE
HTTP Status-Code 415: Type de média non-supporté
static int HTTP_USE_PROXY
HTTP Status-Code 305: Utilisation du Proxy
static int HTTP_VERSION
HTTP Status-Code 505: HTTP Version non-supportée
protected boolean instanceFollowRedirects
Si la valeur est true, le protocole suivra automatiquement la redirection.
protected String method
Ce champ représente la méthode HTTP : GET, POST, PUT, etc..
protected int responseCode
Ce champ représente un entier représentant les trois chiffres du code de statut HTTP.
protected String responseMessage
Ce champ représente le message de réponse HTTP.
Les champs héritées de le classe java.net.URLConnection
allowUserInteraction, connected, doInput, doOutput,
ifModifiedSince, url, useCaches
Les constructeurs
protected HttpURLConnection(URL u)
crée un nouvel objet HttpURLConnection.

Les méthodes
abstract void disconnect()
indique que d'autres requêtes vers le serveur sont improbables dans le futur prôche.
InputStream getErrorStream()
retourne le flux d'erreur si la connexion a échouée mais le serveur a envoyé néanmoins, des données utiles.
static boolean getFollowRedirects()
retourne une valeur booléenne indiquant si les redirections HTTP (3XX) doivent ou ne doivent pas être automatiquement suivies.
long getHeaderFieldDate(String name, long Default)
retourne la valeur du champ désigné analysé comme une date.
boolean getInstanceFollowRedirects()
retourne la valeur du champ instanceFollowRedirects de l'objet HttpURLConnection.
Permission getPermission()
retourne un objet Permission représentant la permission nécessaire pour fabriquer la connexion représentée par l'objet HttpURLConnection.
String getRequestMethod()
obtient la méthode de la requête.
int getResponseCode()
obtient le code de statut d'un message de réponse HTTP.
String getResponseMessage()
obtient le message de réponse HTTP, le cas échéant, retourné avec le code de réponse du serveur.
static void setFollowRedirects(boolean set)
indique si les redirections HTTP doivent être automatiquement suivies par cette classe.
void setInstanceFollowRedirects(boolean followRedirects)
indique si les redirections HTTP doivent être automatiquement suivies par l'objet HttpURLConnection.
void setRequestMethod(String method)
fixe la méthode pour la requête URL. Les mots-clés suivants GET POST HEAD OPTIONS PUT DELETE TRACE sont valides, sujet aux restrictions du protocole.
abstract boolean usingProxy()
indique si le connexion a été effectuée en traversant un proxy.
Les méthodes héritées de la classe java.net.URLConnection
addRequestProperty, connect, getAllowUserInteraction, getContent, getContent, getContentEncoding, getContentLength, getContentType, getDate, getDefaultAllowUserInteraction, getDefaultRequestProperty, getDefaultUseCaches, getDoInput, getDoOutput, getExpiration, getFileNameMap, getHeaderField, getHeaderField, getHeaderFieldInt, getHeaderFieldKey, getHeaderFields, getIfModifiedSince, getInputStream, getLastModified, getOutputStream, getRequestProperties, getRequestProperty, getURL, getUseCaches, guessContentTypeFromName, guessContentTypeFromStream, setAllowUserInteraction, setContentHandlerFactory, setDefaultAllowUserInteraction, setDefaultRequestProperty, setDefaultUseCaches, setDoInput, setDoOutput, setFileNameMap, setIfModifiedSince, setRequestProperty, setUseCaches, toString
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

41.7 / La classe Inet4Address

La classe Inet4Address représente une adresse IPv4 (Internet Protocol version 4).

Les adresses IPv4 sont définies par les RFC 790 (Numéros assignés : Assigned Numbers), RFC 1918 (Allocation d'adresses pour les internet privés : Address Allocation for Private Internets) et RFC 2365 (Multipoint IP étendue administrativement : Administratively Scoped IP Multicast).

Les méthodes
boolean equals(Object obj)
compare l'objet Inet4Address à un autre objet.
byte[] getAddress()
retourne l'adresse IP brute de l'objet InetAddress.
String getHostAddress()
retourne une chaîne de caractères représentant l'adresse IP.
int hashCode()
retourne un hashcode pour l'adresse IP.
boolean isAnyLocalAddress()
vérifie si l'objet InetAddress est dans une adresse joker (wildcard).
boolean isLinkLocalAddress()
vérifie si l'objet InetAddress est un adresse locale de liaison.
boolean isLoopbackAddress()
vérifie si l'objet InetAddress est une adresse qui fait une boucle.
boolean isMCGlobal()
vérifie si l'adresse multi-points a une portée globale.
boolean isMCLinkLocal()
vérifie si l'adresse multi-points a une portée de lien.
boolean isMCNodeLocal()
vérifie si l'adresse multi-points a une portée de noeud.
boolean isMCOrgLocal()
vérifie si l'adresse multi-points a une portée d'organisation.
boolean isMCSiteLocal()
vérifie si l'adresse multi-points a une portée de site.
boolean isMulticastAddress()
vérifie si l'objet InetAddress est une adresse IP multi-points.
boolean isSiteLocalAddress()
vérifie si l'objet InetAddress est une adresse locale de site.
Les méthodes héritées de la classe java.net.InetAddress
getAllByName, getByAddress, getByAddress, getByName,
getCanonicalHostName, getHostName, getLocalHost, toString
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.8 / La classe Inet6Address

La classe Inet6Address représente une adresse IPv6 (Internet Protocol version 6) définit par la RFC 2373 (Architecture d'adressage IP version 6 : IP Version 6 Addressing Architecture).

Les méthodes
boolean equals(Object obj)
compare l'objet Inet6Address par rapport à l'objet spécifié.
byte[] getAddress()
retourne l'adresse IP brute de l'objet Inet6Address.
String getHostAddress()
retourne une chaîne de caractères représentant l'adresse IP de l'objet Inet6Address.
int hashCode()
retourne un hashcode pour l'adresse IP.
boolean isAnyLocalAddress()
vérifie si l'objet InetAddress est dans une adresse joker (wildcard).
boolean isIPv4CompatibleAddress()
vérifie si l'objet InetAddress est une adresse IPv6 compatible IPv4.
boolean isLinkLocalAddress()
vérifie si l'objet InetAddress est un adresse locale de lien.
boolean isLoopbackAddress()
vérifie si l'objet InetAddress est une adresse qui fait une boucle.
boolean isMCGlobal()
vérifie si l'adresse multi-points a une portée globale.
boolean isMCLinkLocal()
vérifie si l'adresse multi-points a une portée de lien.
boolean isMCNodeLocal()
vérifie si l'adresse multi-points a une portée de noeud.
boolean isMCOrgLocal()
vérifie si l'adresse multi-points a une portée d'organisation.
boolean isMCSiteLocal()
vérifie si l'adresse multi-points a une portée de site.
boolean isMulticastAddress()
vérifie si l'objet InetAddress est une adresse IP multi-points.
boolean isSiteLocalAddress()
vérifie si l'objet InetAddress est une adresse locale de site.
Les méthodes héritées de la classe java.net.InetAddress
getAllByName, getByAddress, getByAddress, getByName,
getCanonicalHostName, getHostName, getLocalHost, toString
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.9 / La classe InetAddress

La classe InetAddress représente une adresse IP (Internet Protocol).

Une adresse IP est un nombre non-signé de 32 bits ou de 128 bits utilisé par IP (Internet Protocol), un protocole de bas niveau sur lequel les protocoles tels que UDP et TCP sont construits. L'architecture d'adresse IP est définie par les RFC 790 (Numéros assignés : Assigned Numbers), RFC 1918 (Allocation d'adresses pour les internet privés : Address Allocation for Private Internets), RFC 2365 (Multipoint IP étendue administrativement : Administratively Scoped IP Multicast) et RFC 2373 (Architecture d'adressage IP version 6 : IP Version 6 Addressing Architecture).

Une instance d'une classe InetAddress consiste en une adresse IP et si possible son nom d'hôte correspondant selon si l'objet est construit avec un nom d'hôte ou s'il a déjà fait la resolution de nom d'hôte inversé.

Les méthodes
boolean equals(Object obj)
compare l'objet InetAddress à un autre objet.
byte[] getAddress()
retourne l'adresse IP brute de l'objet InetAddress.
static InetAddress[] getAllByName(String host)
retourne un tableau d'adresses IP déterminées à partir du nom d'hôte et basées sur le service de nom configuré sur le système.
static InetAddress getByAddress(byte[] addr)
retourne un objet InetAddress à partir d'une adresse IP brut.
static InetAddress getByAddress(String host, byte[] addr)
crée un objet InetAddress basée sur le nom d'hôte fourni et le service de nom non adresse IP est vérifié pour la validité de l'adresse.
static InetAddress getByName(String host)
détermine si l'adresse IP address d'un nom hôte.
String getCanonicalHostName()
obtient le nom de domaine qualifié complet pour l'adresse IP.
String getHostAddress()
retourne une représentation sous forme d'une chaîne de caractères de l'objet InetAddress.
String getHostName()
obtient le nom d'hôte pour l'objet InetAddress.
static InetAddress getLocalHost()
retourne l'hôte local.
int hashCode()
retourne un hashcode pour l'objet InetAddress.
boolean isAnyLocalAddress()
vérifie si l'objet InetAddress est une adresse joker (wildcard).
boolean isLinkLocalAddress()
vérifie si l'objet InetAddress est un adresse locale de lien.
boolean isLoopbackAddress()
vérifie si l'objet InetAddress est une adresse qui fait une boucle.
boolean isMCGlobal()
vérifie si l'adresse multi-points a une portée globale.
boolean isMCLinkLocal()
vérifie si l'adresse multi-points a une portée de lien.
boolean isMCNodeLocal()
vérifie si l'adresse multi-points a une portée de noeud.
boolean isMCOrgLocal()
vérifie si l'adresse multi-points a une portée d'organisation.
boolean isMCSiteLocal()
vérifie si l'adresse multi-points a une portée de site.
boolean isMulticastAddress()
vérifie si l'objet InetAddress est une adresse IP multi-points.
boolean isSiteLocalAddress()
vérifie si l'objet InetAddress est une adresse locale de site.
String toString()
convertit l'objet InetAddress en une chaîne de caractères.
Les méthodes de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.10 / La classe InetSocketAddress

La classe InetSocketAddress implémente une adresse IP de socket, c'est-à-dire, une adresse IP et un numéro de port ou nom d'hôte et numéro de port. Dans ce dernier cas, une tentative de résolution de nom d'hôte est effectuée. Si cette résolution échoue, alors l'adresse est dite non-résolue mais peut être encore utilisée pour une connexion à travers un proxy.

Le joker (wilcard) est une adresse locale spéciale. Il signifie habituellement any et peut seulement être utilisé pour des opérations de liaisons.

Les constructeurs
InetSocketAddress(InetAddress addr, int port)
crée une adresse socket à partir de l'adresse IP et d'un numéro de port.
InetSocketAddress(int port)
crée une adresse socket où l'adresse IP est l'adresse joker (wildcard) et le numéro de port est spécifié.
InetSocketAddress(String hostname, int port)
crée une adresse socket à partir d'un nom d'hôte et un numéro de port.

Les méthodes
boolean equals(Object obj)
compare l'objet InetAddress à un autre objet.
InetAddress getAddress()
obtient l'objet InetAddress.
String getHostName()
obtient le nom d'hôte.
int getPort()
obtient le numéro de port.
int hashCode()
retourne un hashcode pour l'adresse socket.
boolean isUnresolved()
vérifie si l'adresse a été ou n'a pas été résolue.
String toString()
retourne une chaîne de caractères représentant l'objet InetSocketAddress.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.11 / La classe JarURLConnection

L'objet JarURLConnection constitue une connexion d'une adresse URL vers un fichier JAR (Java ARchive) ou une entrée d'un fichier JAR.

La syntaxe d'une adresse URL d'un fichier JAR est :

jar:<adresse_URL>!/{entrée}

jar:http://www.unsite.com/rep/fichier.jar!/racine/sscl/classe.class
Les champs
protected URLConnection jarFileURLConnection
La champ représente la connexion à l'adresse URL d'un fichier JAR si la connexion a été initialisée.
Les champs hérités de la classe java.net.URLConnection
allowUserInteraction, connected, doInput, doOutput,
ifModifiedSince, url, useCaches

Les constructeurs
protected JarURLConnection(URL url)
crée un nouvel objet JarURLConnection pour l'objet URL spécifiée.

Les méthodes
Attributes getAttributes()
retourne les objets Attributes pour la connexion si l'adresse URL pointe une entrée du fichier JAR, ou null si ce n'est pas le cas.
Certificate[] getCertificates()
Retourne les objets Certificate pour la connexion si l'adresse URL pointe une entrée d'un fichier JAR, ou null si ce n'est pas le cas.
String getEntryName()
retourne un nom d'entrée pour la connexion.
JarEntry getJarEntry()
retourne un objet représentant une entrée d'un fichier JAR pour la connexion.
abstract JarFile getJarFile()
retourne un fichier JAR pour la connexion.
URL getJarFileURL()
retourne l'adresse URL du fichier JAR pour cette connexion.
Attributes getMainAttributes()
retourne les attributs principaux du fichier JAR pour la connexion.
Manifest getManifest()
retourne l'objet Manifest pour la connexion, ou null s'il n'y en a pas.
Les méthodes héritées de la classe java.net.URLConnection
addRequestProperty, connect, getAllowUserInteraction, getContent, getContent, getContentEncoding, getContentLength, getContentType, getDate, getDefaultAllowUserInteraction, getDefaultRequestProperty, getDefaultUseCaches, getDoInput, getDoOutput, getExpiration, getFileNameMap, getHeaderField, getHeaderField, getHeaderFieldDate, getHeaderFieldInt, getHeaderFieldKey, getHeaderFields, getIfModifiedSince, getInputStream, getLastModified, getOutputStream, getPermission, getRequestProperties, getRequestProperty, getURL, getUseCaches, guessContentTypeFromName, guessContentTypeFromStream, setAllowUserInteraction, setContentHandlerFactory, setDefaultAllowUserInteraction, setDefaultRequestProperty, setDefaultUseCaches, setDoInput, setDoOutput, setFileNameMap, setIfModifiedSince, setRequestProperty, setUseCaches, toString
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

41.12 / La classe MulticastSocket

Le socket de datagrammes multi-points est utile pour envoyer et recevoir des paquets IP multi-points. Un objet MulticastSocket est un objet DatagramSocket (UDP), avec des capacités additionnelles pour joindre des groupes d'autres hôtes multi-points sur Internet.

Un groupe multi-points est spécifié par une classe d'adresse IP D et par un standard de numéro de port UDP. La classe d'adresses IP D sont dans l'intervalle 224.0.0.0 à 239.255.255.255, dont les bornes sont incluses.L'adresse 224.0.0.0 est réservée et devrait ne pas être utilisée.

Les constructeurs
MulticastSocket()
crée un nouvel objet MulticastSocket.
MulticastSocket(int port)
crée un nouvel objet MulticastSocket et le relie à un port spécifié
MulticastSocket(SocketAddress bindaddr)
crée un nouvel objet MulticastSocket limité à l'adresse socket spécifié.

Les méthodes
InetAddress getInterface()
récupère l'adresse de l'interface réseau utilisée pour des paquets multi-points.
boolean getLoopbackMode()
obtient le paramétrage pour la boucle locale des datagrammes multi-points.
NetworkInterface getNetworkInterface()
obtient l'objet NetworkInterface pour l'objet courant.
int getTimeToLive()
obtient le temps d'existence alloué aux paquets multi-points envoyés sur le socket.
byte getTTL()
Dépréciée. Voir getTimeToLive().
void joinGroup(InetAddress mcastaddr)
rejoint un groupe multi-points.
void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
rejoint le groupe multi-points à l'interface réseau spécifiée.
void leaveGroup(InetAddress mcastaddr)
quitte un groupe multi-points.
void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
quitte un groupe multi-points sur une interface locale spécifiée.
void send(DatagramPacket p, byte ttl)
Dépréciée. Code équivalent :
int ttl = mcastSocket.getTimeToLive();
mcastSocket.setTimeToLive(newttl);
mcastSocket.send(p);
mcastSocket.setTimeToLive(ttl);
void setInterface(InetAddress inf)
fixe l'interface réseau multi-points utilisée par les méthodes dont le comportement serait affecté par la valeur de l'interface réseau.
void setLoopbackMode(boolean disable)
active ou désactive la bouble locale de datagrammes multi-points. L'option est utilisée le code de gestion de réseau de la plateforme comme une indication pour le paramétrage si les données multi-points serait bouclée vers le socket local.
void setNetworkInterface(NetworkInterface netIf)
spécifie l'interface réseau pour des datagrammes multi-points sortants envoyés sur le socket.
void setTimeToLive(int ttl)
fixe le temps d'existence par défaut pour les paquets multi-points envoyés sur l'objet MulticastSocket afin de contrôler la portée des multi-points.
void setTTL(byte ttl)
Dépréciée. Voir setTimeToLive().
Les méthodes héritées de la classe java.net.DatagramSocket
bind, close, connect, connect, disconnect, getBroadcast, getChannel, getInetAddress, getLocalAddress, getLocalPort, getLocalSocketAddress, getPort, getReceiveBufferSize, getRemoteSocketAddress, getReuseAddress, getSendBufferSize, getSoTimeout, getTrafficClass, isBound, isClosed, isConnected, receive, send, setBroadcast, setDatagramSocketImplFactory, setReceiveBufferSize, setReuseAddress, setSendBufferSize, setSoTimeout, setTrafficClass
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.13 / La classe NetPermission

La classe NetPermission est utilisée pour les diverses permissions réseaux. Un objet NetPermission contient un nom (ou un nom cible) mais aucune liste d'actions dépendant de la détention de la permission désignée.

Les permissions
Nom cible Description
setDefaultAuthenticator représente la capacité de déterminer la manière don l'information d'authentification est récupérée lorsqu'un proxy ou un serveur HTTP demande une authentification.
requestPasswordAuthentication représente la capacité de spécifier un gestionnaire de flux lors de la construction d'une adresse URL.
setDefaultAuthenticator représente la capacité de déterminer la manière don l'information d'authentification est récupérée lorsqu'un proxy ou un serveur HTTP demande uen authentification.
Les constructeurs
NetPermission(String name)
crée un nouvel objet NetPermission avec le nom spécifié.
NetPermission(String name, String actions)
crée un nouvel objet NetPermission avec le nom et des actions spécifiés.

Les méthodes
Les méthodes héritées de la classe java.security.BasicPermission
equals, getActions, hashCode, implies, newPermissionCollection
Les méthodes héritées de la classe java.security.Permission
checkGuard, getName, toString
Les méthodes héritées de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.14 / La classe NetworkInterface

La classe NetworkInterface représente une interface réseau composée d'un nom et d'une liste d'adresses IP assignées à cette interface.

Elle est utilisée pour identifier l'interface locale sur laquelle un groupe multi-points est joint. Les interfaces sont normalement connues par des noms tel que le0.

Les méthodes
boolean equals(Object obj)
compare l'objet NetworkInterface à un autre objet spécifié en argument.
static NetworkInterface getByInetAddress(InetAddress addr)
recherche une interface réseau reliant l'adresse IP spécifiée.
static NetworkInterface getByName(String name)
recherche l'interface réseau ayant le nom spécifié.
String getDisplayName()
obtient le nom d'affichage de l'interface réseau.
Enumeration getInetAddresses()
retourne un objet Enumeration avec toutes ou un sous-ensemble des objets InetAddresses reliés à l'interface de réseau.
String getName()
obtient le nom de l'interface réseau.
static Enumeration getNetworkInterfaces()
retourne toutes les interfaces sur la machine courante.
int hashCode()
retourne une valeur hashcode pour l'interface réseau.
String toString()
retourne une chaîne de caractères représentant l'interface réseau.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.15 / La classe PasswordAuthentication

La classe PasswordAuthentication est un détenteur de données qui est utilisée par l'objet Authenticator. Elle constitue simplement un réceptacle pour un nom d'utilisateur et un mot de passe.

Les constructeurs
PasswordAuthentication(String userName, char[] password)
crée un nouvel objet PasswordAuthentication avec un nom d'utilisateur et un mot de passe fournis.

Les méthodes
char[] getPassword()
retourne le mot de passe.
String getUserName()
retourne le nom d'utilisateur.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.16 / La classe ServerSocket

La classe ServerSocket implémente les sockets du côté du serveur. Un socket du côté serveur attend les requêtes venant du réseau. Il exécute certaines opérations basées sur ces requêtes et retourne probablement un résultat au demandeur.

Le travail courant d'un socket côté serveur est exécuté par une instance de la classe SocketImpl. Une application peut modifier la fabrique de socket qui crée l'implémentation du socket pour se configurer afin de créer les sockets appropriés au firewall local.

Les constructeurs
ServerSocket()
crée un objet ServerSocket sans lien.
ServerSocket(int port)
crée un objet ServerSocket lié à un numéro de port.
ServerSocket(int port, int backlog)
crée un objet ServerSocket et le lie à un numéro de port local avec une réserve spécifiée.
ServerSocket(int port, int backlog, InetAddress bindAddr)
crée un objet ServerSocket avec un numéro de port, une réserve et un objet InetAddress.

Les méthodes
Socket accept()
écoute une connexion à faire sur le socket et l'accepte.
void bind(SocketAddress endpoint)
relie l'objet ServerSocket à une adresse de socket (adresse IP et numéro de port).
void bind(SocketAddress endpoint, int backlog)
relie l'objet ServerSocket à une adresse de socket (adresse IP et un numéro de port) avec une réserve.
void close()
ferme le socket
ServerSocketChannel getChannel()
retourne l'objet unique ServerSocketChannel associé au socket.
InetAddress getInetAddress()
retourne l'adresse locale de l'objet ServerSocket.
int getLocalPort()
retourne le numéro de port local sur lequel le socket est écouté.
SocketAddress getLocalSocketAddress()
retourne l'adresse de socket du point d'arrivée sur lequel l'objet ServerSocket est relié, ou null s'il n'est pas encore relié.
int getReceiveBufferSize()
obtient le valeur de l'option SO_RCVBUF pour l'objet ServerSocket, qui est la taille de la mémoire tampon proposée qui sera utilisée par les sockets acceptés à partir de l'objet ServerSocket.
boolean getReuseAddress()
indique si l'option SO_REUSEADDR est activée.
int getSoTimeout()
récupère le paramétrage de pause spécifié par l'option SO_TIMEOUT.
protected void implAccept(Socket s)
utilisée par les sous-classe de ServerSocket pour retourner leur propre sous-classe de socket.
boolean isBound()
retourne l'état de la liaison de l'objet ServerSocket.
boolean isClosed()
indique si l'objet ServerSocket est fermé.
void setReceiveBufferSize(int size)
fixe l'option SO_RCVBUF, soit la taille de la mémoire tampon pour les sockets acceptés à partir de l'objet ServerSocket.
void setReuseAddress(boolean on)
active ou désactive l'option de socket SO_REUSEADDR.
static void setSocketFactory(SocketImplFactory fac)
fixe la fabrique d'implémentation d'objet ServerSocket pour l'application.
void setSoTimeout(int timeout)
active ou désactive l'option SO_TIMEOUT en spécifia,t un temps de pause en millisecondes.
String toString()
retourne une chaîne de caractères représentant l'objet ServerSocket.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

41.17 / La classe Socket

La classe Socket implémente des sockets du côté du client. Un socket est un point d'arrivée pour les communications entre les machines.

Le travail courant d'un socket côté client est exécuté par une instance de la classe SocketImpl. Une application peut modifier la fabrique de socket qui crée l'implémentation du socket pour se configurer afin de créer les sockets appropriés au firewall local.

Les constructeurs
Socket()
crée un socket client non-connecté avec le type du système par défaut de la classe SocketImpl.
Socket(InetAddress address, int port)
crée un socket client et le connecte au numéro de port et à l'adresse IP spécifiés.
Socket(InetAddress host, int port, boolean stream)
Déprécié.Voir DatagramSocket pour le transport UDP.
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
crée un socket client et le connecte au numéro de port et à l'adresse IP ditants indiqués, à partir d'un numéro de port et d'une adresse IP locaux.
protected Socket(SocketImpl impl)
crée un socket non-connecté avec un objet SocketImpl utilisateur spécifié.
Socket(String host, int port)
crée un socket et le connecte au numéro de port et au nom d'hôte spécifié.
Socket(String host, int port, boolean stream)
Déprécié.Voir DatagramSocket pour le transport UDP.
Socket(String host, int port, InetAddress localAddr, int localPort)
crée un socket client et le connecte au numéro de port et au nom d'hôte ditants indiqués, à partir d'un numéro de port et d'une adresse IP locaux.

Les méthodes
void bind(SocketAddress bindpoint)
relie le socket à l'adresse locale.
void close()
ferme le socket
void connect(SocketAddress endpoint)
connecte le socket au serveur.
void connect(SocketAddress endpoint, int timeout)
connecte le socket au serveur avec une valeur d'expiration spécifié en millisecondes.
SocketChannel getChannel()
retourne l'objet unique SocketChannel associé au socket.
InetAddress getInetAddress()
retourne l'adresse auquelle le socket est connecté.
InputStream getInputStream()
retourne un flux d'entrée pour le socket.
boolean getKeepAlive()
indique si l'option SO_KEEPALIVE est activée.
InetAddress getLocalAddress()
obtient l'adresse locale auquelle le socket est relié.
int getLocalPort()
obtient le numéro de port local auquel le socket est relié.
SocketAddress getLocalSocketAddress()
retourne l'adresse du point d'arrivée auquelle le socket est relié, ou null s'il n'est pas encore relié.
boolean getOOBInline()
indique si l'option OOBINLINE est activée.
OutputStream getOutputStream()
retourne un flux de sortie pour le socket.
int getPort()
retourne le numéro de port distant auquel le socket est connecté.
int getReceiveBufferSize()
obtient la valeur de l'option SO_RCVBUF pour le socket, qui est la taille de la mémoire tampon utilisée par la plateforme pour l'entrée du socket.
SocketAddress getRemoteSocketAddress()
retourne l'adresse du point d'arrivée sur lequel le socket est connecté, ou null s'il n'est pas encore connecté.
boolean getReuseAddress()
indique si l'option SO_REUSEADDR est activée.
int getSendBufferSize()
obtient la valeur de l'option SO_SNDBUF pour le socket, qui est la taille de la mémoire tampon utilisée par la plateforme pour la sortie du socket.
int getSoLinger()
retourne le paramètrage de l'option SO_LINGER.
int getSoTimeout()
retourne le paramètrage de l'option SO_TIMEOUT.
boolean getTcpNoDelay()
indique si l'option TCP_NODELAY est activée.
int getTrafficClass()
obtient la classe de trafic ou le type de service dans l'entête IP pour les paquets envoyés à partir du socket.
boolean isBound()
retourne l'état de la liaison du socket.
boolean isClosed()
indique si le socket est fermé.
boolean isConnected()
retourne l'état de la connexion du socket.
boolean isInputShutdown()
retourne le résultat d'une lecture partielle lorsque la connexion du socket est fermée.
boolean isOutputShutdown()
retourne le résultat d'une écriture partielle lorsque la connexion du socket est fermée.
void sendUrgentData(int data)
envoie un octet de données urgentes sur le socket.
void setKeepAlive(boolean on)
active ou désactive l'option SO_KEEPALIVE.
void setOOBInline(boolean on)
active ou désactive l'option OOBINLINE (réception de données urgentes TCP). Par défaut, cette option est désactivée et les données urgentes reçues sur un socket sont silencieusement mises de côté.
void setReceiveBufferSize(int size)
fixe l'option SO_RCVBUF à la valeur spécifiée pour le socket.
void setReuseAddress(boolean on)
active ou désactive l'option SO_REUSEADDR.
void setSendBufferSize(int size)
fixe l'option SO_SNDBUF à la valeur spécifiée pour le socket.
static void setSocketImplFactory(SocketImplFactory fac)
fixe la fabrique d'implémentation de socket client pour l'application.
void setSoLinger(boolean on, int linger)
active ou désactive l'option SO_LINGER avec un temps de prolongement spécifié en secondes.
void setSoTimeout(int timeout)
active ou désactive l'option SO_TIMEOUT avce un temps spécifié en millisecondes.
void setTcpNoDelay(boolean on)
active ou désactive l'option TCP_NODELAY.
void setTrafficClass(int tc)
fixe la classe de trafic ou l'octet de type de service dans l'entête IP pour les paquets envoyés à partir du socket.
void shutdownInput()
place le flux d'entrée pour le socket à la fin du flux.
void shutdownOutput()
désactive le flux de sortie pour le socket.
String toString()
convertit le socket en une chaîne de caractères.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

41.18 / La classe SocketAddress

La classe SocketAddress représente une adresse de socket avec aucun protocole associé. Comme une classe abstraite, elle indique qu'elle est sous-classée avec une implémentation dépendant d'un protocole spécifique.

Elle fournit un objet non-mutable utilisé par les sockets pour des liaisons et des connexions ou comme des valeurs retournées.

Les constructeurs
SocketAddress()
crée une nouvelle instance de la classe SocketAddress.
Les méthodes
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.19 / La classe SocketImpl

La classe abstraite SocketImpl est une superclasse commune à toutes les classe qui implémentent des sockets. Elle est utilisée pour créer des sockets clients et serveurs.

Les champs
protected InetAddress address
représente l'adresse IP de l'arrivée distante du socket.
protected FileDescriptor fd
représente le descripteur de fichier pour le socket.
protected int localport
représente le numéro de port local sur lequel le soccket est connecté.
protected int port
représente le numéro de port de l'hôte distant sur lequel le socket est connecté.
Les champs hérités de l'interface java.net.SocketOptions
IP_MULTICAST_IF, IP_MULTICAST_IF2, IP_MULTICAST_LOOP, IP_TOS, SO_BINDADDR, SO_BROADCAST, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_RCVBUF, SO_REUSEADDR, SO_SNDBUF, SO_TIMEOUT, TCP_NODELAY

Les constructeurs
SocketImpl()
crée un nouvel objet SocketImpl.

Les méthodes
protected abstract void accept(SocketImpl s)
accepte une connexion.
protected abstract int available()
retourne le nombre d'octets qui peuvent être lus à partir du socket sans entraîner de blocage.
protected abstract void bind(InetAddress host, int port)
relie le socket à l'adresse et au numéro de port spécifiés.
protected abstract void close()
ferme le socket.
protected abstract void connect(InetAddress address, int port)
connecte le socket à l'hôte et le numéro de port spécifiés.
protected abstract void connect(SocketAddress address, int timeout)
connecte le socket à l'adresse et au numéro de port spécifiés.
protected abstract void connect(String host, int port)
connecte le socket au nom d'hôte et au numéro de port spécifiés.
protected abstract void create(boolean stream)
crée soit un socket de datagrammes soit un flux.
protected FileDescriptor getFileDescriptor()
retourne la valeur du champ fd du socket.
protected InetAddress getInetAddress()
retourne la valeur du champ address du socket.
protected abstract InputStream getInputStream()
retourne un flux d'entrée pour le socket.
protected int getLocalPort()
retourne la valeur du champ localport du socket.
protected abstract OutputStream getOutputStream()
retourne un flux de sortie pour le socket.
protected int getPort()
retourne la valeur du champ port du socket.
protected abstract void listen(int backlog)
fixe la longueur de queue maximum pour les indications de connexion entrantes vers l'argument count.
protected abstract void sendUrgentData(int data)
envoie un octet de données urgentes sur le socket.
protected void shutdownInput()
place le flux d'entrée pourle socket à la fin du flux.
protected void shutdownOutput()
désactive le flux de sortie pour le socket.
protected boolean supportsUrgentData()
indique si l'objet SocketImpl supporte l'envoi de données urgentes.
String toString()
retourne l'adresse et le numéro de port du socket sous la forme d'une chaîne de caractères.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.net.SocketOptions
getOption, setOption

41.20 / La classe SocketPermission

La classe SocketPermission reprsente un accès au réseau via des sockets. Un objet SocketPermission est composée d'une spécification d'hôte et un jeu d'actions spécifiant les manières de se connecter à cet hôte.

Les constructeurs
SocketPermission(String host, String action)
crée un nouvel objet SocketPermission en spécifiant un hôte et une liste d'actions.

Les méthodes
boolean equals(Object obj)
vérifie l'égalité entre l'objet SocketPermission et un autre objet.
String getActions()
retourne une représentation textuelle canonique des actions.
int hashCode()
retourne la valeur hashcode pour l'objet.
boolean implies(Permission p)
vérifie si l'objet SocketPermission "implique" la permission spécifiée.
PermissionCollection newPermissionCollection()
retourne un nouvel objet PermissionCollection pour stocker des objets SocketPermission.
Les méthodes héritées de la classe java.security.Permission
checkGuard, getName, toString
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.21 / La classe URI

La classe URI représente une référence URI (Uniform Resource Identifier). Une référence URI est définie dans la RFC 2396 (Request For Comments 2396 : Syntaxe générique pour les URI ou Uniform Resource Identifiers (URI): Generic Syntax), améliorée par la RFC 2732 (Format pour les adresses IPv6 littérales dans les URLou Format for Literal IPv6 Addresses in URL's).

Cette classe fournit les constructeurs pour la création d'instances URI à partir de leurs composants ou en analysant leurs formes de chaîne de caractères, les méthodes pour l'accès à divers composants d'une instance, les méthodes de normalisation et de résolution, ainsi que de relativisation des instances URI. Les instances de cette classe sont non-mutables.

Les constructeurs
URI(String str)
crée un nouvel objet URI en analysant la chaîne de caractères spécifiée.
URI(String scheme, String ssp, String fragment)
crée un objet URI à partir des composants spécifiés.
URI(String scheme, String userInfo, String host, int port,
String path, String query, String fragment)
crée un objet URI hiérarchique à partir des composants fournis.
URI(String scheme, String host, String path, String fragment)
crée un objet URI hiérarchique à partir des composants fournis.
URI(String scheme, String authority, String path, String query, String fragment)
crée un objet URI hiérarchique à partir des composants fournis.

Les méthodes
int compareTo(Object ob)
compare l'objet URI par rapport à un autre objet de même type.
static URI create(String str)
crée un objet URI en analysant la chaîne de caractères passée en argument.
boolean equals(Object ob)
vérifie l'égalité entre l'objet URI et un autre objet.
String getAuthority()
retourne le composant autorité décodé de l'URI.
String getFragment()
retourne le composant fragment décodé de l'URI.
String getHost()
retourne le composant hôte de l'URI.
String getPath()
retourne le composant chemin de l'URI.
int getPort()
retourne le numéro de port de l'URI.
String getQuery()
retourne le composant requête de l'URI.
String getRawAuthority()
retourne le composant autorité brut de l'URI.
String getRawFragment()
retourne le composant fragment brut de l'URI.
String getRawPath()
retourne le composant chemin brut de l'URI.
String getRawQuery()
retourne le composant requête brut de l'URI.
String getRawSchemeSpecificPart()
retourne le composant schéma spécifique brut de l'URI.
String getRawUserInfo()
retourne le composant information utilisateur brut de l'URI.
String getScheme()
retourne le composant schéma de l'URI.
String getSchemeSpecificPart()
retourne le composant partie du schéma spécifique décodé de l'URI.
String getUserInfo()
retourne le composant information utilisateur décodé de l'URI.
int hashCode()
retourne la valeur hash-code de l'URI.
boolean isAbsolute()
indique si l'URI est absolue.
boolean isOpaque()
indique si l'URI est non-transparente.
URI normalize()
normalise le chemin de l'objet URI.
URI parseServerAuthority()
tente d'analyser le composant autorité de l'URI, si défini, à l'intérieur des composants information utilisateur, hôte et port.
URI relativize(URI uri)
relativise l'objet URI passé en argument par rapport à l'objet URI courant.
URI resolve(String str)
crée un nouvel objet URI en analysant la chaîne de caractères donnée et en le résolvant par rapport à cet objet URI.
URI resolve(URI uri)
résoud l'objet URI spécifié par rapport à l'objet URI courant.
String toASCIIString()
retourne le contenu de l'objet URI sous la forme d'une chaîne de caractères au format US-ASCII.
String toString()
retourne une représentation textuelle de l'objet URI.
URL toURL()
crée un objet URL à partir de l'objet URI.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.22 / La classe URL

La classe URL représente un localiseur de ressource uniforme (URL : Uniform Resource Locator), soit un pointeur vers une ressource sur l'internet ou un intranet.

Une ressource peut être un fichier ou un répertoire, ou encore une référence vers un objet complexe telle qu'une requête vers une base de données ou un moteur de recherche.

La syntaxe d'une adresse URL est définie par la RFC 2396 (Request For Comments 2396 : Syntaxe générique pour les URI ou Uniform Resource Identifiers (URI): Generic Syntax), améliorée par la RFC 2732 (Format pour les adresses IPv6 littérales dans les URLou Format for Literal IPv6 Addresses in URL's).

Une adresse URL est décomposable en plusieurs parties :

Les constructeurs
URL(String spec)
crée un objet URL à partir d'une chaîne de caractères.
URL(String protocol, String host, int port, String file)
crée un objet URL à partir d'un protocole, d'un hôte, d'un numéro de port et d'un fichier.
URL(String protocol, String host, int port, String file, URLStreamHandler handler)
crée un objet URL à partir d'un protocole, d'un hôte, d'un numéro de port, d'un fichier et d'un gestionnaire.
URL(String protocol, String host, String file)
crée un objet URL à partir d'un protocole, d'un hôte, et d'un fichier.
URL(URL context, String spec)
crée un objet URL en analysant la chaîne de caractères à l'intérieur d'une adresse URL contextuelle.
URL(URL context, String spec, URLStreamHandler handler)
crée un objet URL en analysant la chaîne de caractères à l'intérieur d'une adresse URL contextuelle, et en spécifiant un gestionnaire.

Les méthodes
boolean equals(Object obj)
vérifie l'égalité de l'objet URL par rapport à un autre objet.
String getAuthority()
obtient la partie autorité de l'URL.
Object getContent()
obtient le contenu de l'URL.
Object getContent(Class[] classes)
obtient le contenu de l'URL par rapport à un tableau de classes.
int getDefaultPort()
obtient le numéro de port du protocole associé à l'objet URL.
String getFile()
obtient le nom de fichier de l'URL.
String getHost()
obtient le nom d'hôte de l'URL, si cela est possible.
String getPath()
obtient la partie chemin de l'URL.
int getPort()
obtient la partie numéro de port de l'URL.
String getProtocol()
obient le nom du protocole de l'URL.
String getQuery()
obtient la partie requête de l'URL.
String getRef()
obtient l'ancre de l'URL.
String getUserInfo()
obtient la partie information utilisateur de l'URL.
int hashCode()
crée une valeur hash-code pour l'objet URL.
URLConnection openConnection()
retourne un objet URLConnection qui représente une connexion vers un objet distant référencé par l'objet URL.
InputStream openStream()
ouvre une connexion pour l'objet URL et retourne un objet InputStream pour la lecture à partir de cette connexion.
boolean sameFile(URL other)
compare deux objets URL en excluant leur composant fragment.
protected void set(String protocol, String host, int port, String file, String ref)
fixe les champs de l'objet URL.
protected void set(String protocol, String host, int port, String authority,
String userInfo, String path, String query, String ref)
fixe les huit champs de l'objet URL.
static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
fixe un objet URLStreamHandlerFactory d'application.
String toExternalForm()
retourne une chaîne de caractères représentant l'objet URL.
String toString()
retourne une chaîne de caractères représentant l'objet URL.
Les méthodes héritées de la classe racine java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

41.23 / La classe URLClassLoader

La classe URLClassLoader est utilisée pour charger les classes et les ressources à partir du chemin des URL référant à des fichiers JAR et des répertoires.

Toutes les adresses URL qui se terminent par un slash '/' se référent à un répertoire. Autrement, l'adresse URL pointe vers un fichier JAR lequel est ouvert si nécessaire.

Les constructeurs
URLClassLoader(URL[] urls)
crée un nouvel objet URLClassLoader pour les adresses spécifiées en utilisant l'objet ClassLoader parent de délégation par défaut.
URLClassLoader(URL[] urls, ClassLoader parent)
crée un nouvel objet URLClassLoader à partir des adresses URL spécifiées en utilisant l'objet ClassLoader fourni.
URLClassLoader(URL[] urls, ClassLoader parent,
URLStreamHandlerFactory factory)
crée un nouvel objet URLClassLoader à partir des adresses URL spécifiées en utilisant l'objet ClassLoader et un objet URLStreamHandlerFactory.

Les méthodes
protected void addURL(URL url)
ajoute l'adresse URL spécifié à la liste des URL pour rechercher les classes et les ressources.
protected Package definePackage(String name, Manifest man, URL url)
définit un nouveau paquetage par l'intermédiaire de son nom dans l'objet ClassLoader.
protected Class findClass(String name)
trouve et charge la classe possédant le nom spécifié à partir d'une adresse URL de recherche.
URL findResource(String name)
trouve la ressource dont le nom est spécifiée à partir de l'URL de recherche.
Enumeration findResources(String name)
retourne un objet Enumeration contenant des adresses URL représentant toutes les ressources sur l'URL de recherche ayant le nom spécifié.
protected PermissionCollection getPermissions(CodeSource codesource)
retourne les permissions pour l'objet CodeSource donné.
URL[] getURLs()
retourne l'adresse URL de recherche pour charger les classes et les ressources.
static URLClassLoader newInstance(URL[] urls)
crée une nouvelle instance de la classe URLClassLoader pour les adresses URL spécifiées et le chargeur de classe parent par défaut.
static URLClassLoader newInstance(URL[] urls, ClassLoader parent)
crée une nouvelle instance de la classe URLClassLoader pour les adresses URL spécifiées et l'objet ClassLoader spécifié.
Les méthodes héritées de la classe java.security.SecureClassLoader
defineClass
Les méthodes héritées de la classe java.lang.ClassLoader
clearAssertionStatus, defineClass, defineClass, defineClass, definePackage, findLibrary, findLoadedClass, findSystemClass, getPackage, getPackages, getParent, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, loadClass, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.24 / La classe URLConnection

La classe abstraite URLConnection est la superclasse de toutes les classes qui représentent une liaison de communication entre l'application et une adresse URL.

Les instances de cette classe peuvent être utilisées pour lire et écrire sur la ressource référencée par l'objet URL.

En général, la création d'une connexion vers un objet URL est un processus à plusieurs étapes.

Les champs
protected boolean allowUserInteraction
Si le champ est égal à true, l'URL est examinée dans un contexte dans lequel il crée une raison de permettre les interactions utilisateurs.
protected boolean connected
Si le champ est égal à false, l'objet URLConnection n'a pas créé un lien de communication vers l'URL spécifié.
protected boolean doInput
Ce champ indique que l'application à l'intention de lire des données vers l'objet URLConnection s'il est à true.
protected boolean doOutput
Ce champ indique que l'application à l'intention d'écrire des données vers l'objet URLConnection s'il est à true.
protected long ifModifiedSince
Certains protocoles supportent skipping the fetching de l'objet à moins que l'objet ait été modifié plus récemment par rapport à un certain temps.
protected URL url
Ce champ représente l'objet distant sur Internet ou un intranet vers lequel la connexion est ouverte.
protected boolean useCaches
Si le champ est égal à true, le protocole est autorisé à utiliser le cachage tant qu'il le peut.

Les constructeurs
protected URLConnection(URL url)
crée un objet URLConnection vers l'adresse URL spécifiée.

Les méthodes
void addRequestProperty(String key, String value)
ajoute une propriété de requête générale spécifiée par une paire clé-valeur.
abstract void connect()
ouvre un lien de communication vers la ressource référencée par l'objet URL, si une connexion n'a pas déjà été établie.
boolean getAllowUserInteraction()
retourne la valeur du champ allowUserInteraction de l'objet URLConnection.
Object getContent()
récupère le contenu de l'objet URLConnection.
Object getContent(Class[] classes)
récupère le contenu de l'objet URLConnection correspondant aux types spécifiés dans le tableau de classes.
String getContentEncoding()
retourne la valeur du champ d'entête content-encoding.
int getContentLength()
retourne la valeur du champ d'entête content-length.
String getContentType()
retourne la valeur du champ d'entête content-type.
long getDate()
retourne la valeur du champ d'entête date.
static boolean getDefaultAllowUserInteraction()
retourne la valeur par défaut du champ allowUserInteraction.
static String getDefaultRequestProperty(String key)
Dépréciée. Voir getRequestProperty().
boolean getDefaultUseCaches()
retourne la valeur par défaut du champ useCaches de l'objet URLConnection.
boolean getDoInput()
retourne la valeur du champ doInput de l'objet URLConnection.
boolean getDoOutput()
retourne la valeur du champ doOutput de l'objet URLConnection.
long getExpiration()
retourne la valeur du champ d'entête expires.
static FileNameMap getFileNameMap()
charge la description de nom de fichier à partir des données du fichier.
String getHeaderField(int n)
retourne la clé pour le champ d'entête nth.
String getHeaderField(String name)
retourne la valeur du champ d'entête header.
long getHeaderFieldDate(String name, long Default)
retourne la valeur du champ désigné analysé comme une date.
int getHeaderFieldInt(String name, int Default)
retourne la valeur du champ désigné analysé comme un nombre.
String getHeaderFieldKey(int n)
retourne la clé pour le champ d'entête nth.
Map getHeaderFields()
retourne une description non-modifiable des champs d'entête.
long getIfModifiedSince()
retourne la valeur du champ ifModifiedSince de l'objet URLConnection.
InputStream getInputStream()
retourne un flux d'entrée qui lit à partir de la connexion ouverte.
long getLastModified()
retourne la valeur du champ d'entête last-modified.
OutputStream getOutputStream()
retourne un flux de sortie qui écrit vers la connexion ouverte.
Permission getPermission()
retourne un objet Permission représentant la permission nécessaire pour créer la connexion représentée par l'objet URLConnection.
Map getRequestProperties()
retourne une description non-modifiable des propriétés de requêtes générales pour l'objet URLConnection.
String getRequestProperty(String key)
retourne la valeur de la propriété de requête générale désignée pour l'objet URLConnection.
URL getURL()
retourne la valeur du champ URL de l'objet URLConnection.
boolean getUseCaches()
retourne la valeur du champ useCaches de l'objet URLConnection.
static String guessContentTypeFromName(String fname)
essaie de déterminer le type de contenu d'un objet, basé sur le composant de fichier spécifié d'une adresse URL.
static String guessContentTypeFromStream(InputStream is)
essaie de déterminer le type d'un flux d'entrée basé sur les caractères au commencement du flux d'entrée.
void setAllowUserInteraction(boolean allowuserinteraction)
fixe la valeur du champ allowUserInteraction de l'objet URLConnection.
static void setContentHandlerFactory(ContentHandlerFactory fac)
fixe l'objet ContentHandlerFactory d'une application.
static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)
fixe la valeur par défaut du champ allowUserInteraction pour les futures objets URLConnection, à la valeur spécifiée.
static void setDefaultRequestProperty(String key, String value)
Dépréciée. Voir setRequestProperty().
void setDefaultUseCaches(boolean defaultusecaches)
fixe la valeur par défaut du champ useCaches à la valeur spécifiée.
void setDoInput(boolean doinput)
fixe la valeur par défaut du champ doInput à la valeur spécifiée.
void setDoOutput(boolean dooutput)
fixe la valeur par défaut du champ doOutput à la valeur spécifiée.
static void setFileNameMap(FileNameMap map)
fixe l'objet FileNameMap pour l'objet URLConnection.
void setIfModifiedSince(long ifmodifiedsince)
fixe la valeur du champ ifModifiedSince de l'objet URLConnection, à la valeur spécifiée.
void setRequestProperty(String key, String value)
fixe la propriété de requête générale.
void setUseCaches(boolean usecaches)
fixe la valeur du champ useCaches de l'objet URLConnection à la valeur spécifiée.
String toString()
retourne une représentation textuelle de l'objet URLConnection.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, wait, wait, wait

41.25 / La classe URLDecoder

La classe URLDecoder constitue une classe utilitaire pour le décodage de formulaire HTML. Cette classe contient des méthodes statiques pour le décodage de chaînes de caractères à partir du format MIME application/x-www-form-urlencoded.

Les constructeurs
URLDecoder()
crée un nouvel objet URLDecoder.

Les méthodes
static String decode(String s)
Dépréciée. Voir decode(String,String) pour spécifier l'encodage.
static String decode(String s, String enc)
décode une chaîne de caractères application/x-www-form-urlencoded utilisant un schéma d'encodage spécifique.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.26 / La classe URLEncoder

La classe URLEncoder constitue une classe utilitaire pour l'encodage de formulaire HTML. Cette classe contient des méthodes statiques pour l'encodage de chaînes de caractères à partir du format MIME application/x-www-form-urlencoded.

Les méthodes
static String encode(String s)
Dépréciée.Voir encode(String,String) pour spécifier un encodage.
static String encode(String s, String enc)
traduit une chaîne de caractères au format application/x-www-form-urlencoded utilisant un schéma d'encodage spécifique.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

41.27 / La classe URLStreamHandler

La classe abstraite URLStreamHandler est la superclasse commune pour tous les gestionnaires de protocole de flux. Un gestionnaire de protocole de flux sait comment faire une connexion pour un type de protocole particulier tel que http, ftp, mailto, etc..

Dans la plupart des cas, une instance d'une sous-classe de URLStreamHandler n'est pas créée directement par une application. Un nom de protocole est rencontré la première fois lors de la construction d'un objet URL, alors le gestionnaire de protocole de flux est automatiquement chargé.

Les constructeurs
URLStreamHandler()
crée un nouvel objet URLStreamHandler.

Les méthodes
protected boolean equals(URL u1, URL u2)
vérifie l'égalité entre les objets URL.
protected int getDefaultPort()
retourne le numéro de port par défaut d'une adresse URL analysée par le gestionnaire courant.
protected InetAddress getHostAddress(URL u)
obtient l'adresse IP à partir de l'objet URL.
protected int hashCode(URL u)
retourne la valuer hash-code de l'objet URL fourni.
protected boolean hostsEqual(URL u1, URL u2)
vérifie l'égalité des composants hôtes des objets URL passés en argument.
protected abstract URLConnection openConnection(URL u)
ouvre une connexion vers l'objet référencé par l'objet URL passé en argument.
protected void parseURL(URL u, String spec, int start, int limit)
analyse la représentation textuelle d'une adresse URL à l'intérieur d'un objet URL.
protected boolean sameFile(URL u1, URL u2)
vérifie si les deux objets URL se référent au même fichier en ayant les mêmes protocole, hôte, numéro de port, et chemin.
protected void setURL(URL u, String protocol,
String host, int port, String file, String ref)
Déprécié. Voir setURL().
protected void setURL(URL u, String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref)
fixe les champs de l'objet URL passé en argument aux valeurs indiquées.
protected String toExternalForm(URL u)
convertit un objet URL d'un protocole spécifique en une chaîne de caractères.
Les méthodes héritées de la classe racine java.lang.Object
clone, equals, finalize, getClass, hashCode,
notify, notifyAll, toString, wait, wait, wait

42 / Le paquetage java.util

Le paquetage java.util contient des classes utilitaires gérant collections, les modèles événementielles, etc.

Les interfaces
Collection représente l'interface racine de toutes les classes de collections.
Comparator représente une fonction de comparaison qui impose un ordonnancement total sur plusieurs collections d'objets
Enumeration représente un objet qui implémente l'interface Enumeration qui génère une série d'éléments.
EventListener représente une interface de balisage que toutes les interfaces chargées de capter les événements doivent étendre.
Iterator représente un itérateur sur une collection.
List représente une collection ordonnée.
ListIterator représente un itérateur pour les listes qui permet de parcourir la liste dans toutes les directions, de modifier la liste pendant l'itération, et d'obtenir la position courante de l'itérateur dans la liste.
Map représente un objet qui répertorie des paires clé-valeur.
Map.Entry représente une entrée Map (paire clé-valeur).
Observer Une classe peut implémenter l'interface Observer lorsqu'elle veut être informée des changements dans des objets observables.
RandomAccess représente une interface de marquage utilisée par les implémentation de listes pour indiquer qu'elles supportent l'accès aléatoire rapide.
Set représente une collection qui contient des éléments sans doublons.
SortedMap Un objet Map que d'autres garanties qu'il sera dans l'ordre de clef croissante, trié selon l'ordonnancement normal de ses clefs (voient l'interface comparable), ou par un comparateur ont fourni au temps assorti de création de carte.
SortedSet garantit que les éléments de cet ensemble seront stockés et triés par l'intermédiaire d'un comparateur.

Les classes
AbstractCollection fournit une exécution squelettique de l'interface Collection afin de minimiser les tentatives requises pour implémenter cette interface.
AbstractList fournit une exécution squelettique de l'interface List afin de réduire au minimum l'effort exigé pour mettre en application cette interface soutenue par un conteneur de données "d'accès aléatoire" (tel que dans un tableau).
AbstractMap fournit une exécution squelettique de l'interface Map afin de minimiser l'effot exigé pour implémenter cette interface.
AbstractSequentialList fournit une exécution squelettique de l'interface List afin de minimiser l'effot exigé pour implémenter cette interface renforcée par un conteneur de données à "accès séquentiel" (tel qu'une liste chaînée).
AbstractSet fournit une exécution squelettique de l'interface Set afin de minimiser l'effot exigé pour implémenter cette interface.
ArrayList représente un tableau redimensionnable implémentant l'interface List.
Arrays contient des méthodes pour la manipulation des tableaux.
BitSet implémente un vecteur de bits qui croît si nécessaire.
Calendar représente une classe de base abstraite pour la conversion d'objet Date et d'un ensemble de champs entiers tels que YEAR, MONTH, DAY, HOUR, etc..
Collections est composée de méthodes statiques qui manipule ou crée des objets Collections.
Currency représente une monnaie.
Date représente une date avec une précision jusqu'au millième de seconde.
Dictionary est le parent abstrait de n'importe quelle classe tel qu'un objet Hashtable.
EventListenerProxy constitue une classe abstraite d'emballage (wrapper) pour une classe EventListener qui associe un jeu de paramètres additionnels avec l'écouteur.
EventObject constitue la classe racine à partir duquel tous les objets d'états d'événements seraient dérivés.
GregorianCalendar représente une sous-classe concrète de la classe Calendar et fournit le calendrier standard utilisé par la plupart des pays.
HashMap est une table de hachage implémentant l'interface Map.
HashSet implémente l'interface Set et est renforcée par une table de hachage.
Hashtable implémente l'interface Map et est destinée à contenir des paires d'objets non-nulles clé/valeur.
IdentityHashMap implémente l'interface Map avec une table de hachage en utilisant une égalité de référence à la place d'une égalité d'objet lors de la comparaison des clés et valeurs.
LinkedHashMap constitue à la fois une table de hachage Map et une liste chaînée avec un ordre d'itération prévisible.
LinkedHashSet constitue à la fois une table de hachage Set et une liste chaînée avec un ordre d'itération prévisible.
LinkedList représente un liste chaînée implémentant l'interface List.
ListResourceBundle représente une sous-classe abstraite de la classe ResourceBundle qui gère les ressources locales dans une utilisation convenable et facile de liste.
Locale représente une région culturel, politique ou géographique.
Observable représente un objet observable ou "data" dans le paradigme vus-modèle.
Properties représente un ensemble persistant de propriétés.
PropertyPermission représente les permissions de propriété.
PropertyResourceBundle représente une sous-classe concrète de la classe ResourceBundle qui gère les ressources locales pour une utilisation d'un ensemble de chaînes de caractères statiques à partir du fichier de propriétés.
Random est utilisée pour générer un flux de nombres pseudo-aléatoires.
ResourceBundle contient des objets spécifiques représentant des ressources locales.
SimpleTimeZone est une sous-classe concrète d'un objet TimeZone qui représente un fuseau horaire à utiliser avec un objet GregorianCalendar.
Stack représente une pile LIFO (Last-In-First-Out) d'objets.
StringTokenizer permet à une application de décomposer une chaîne de caractères en jetons.
Timer représente une facilité pour les threads afin de planifier des tâches pour une exécution future dans un thread en arrière plan.
TimerTask représente une tâche qui peut être programmée pour un unique moment précis ou pour une exécution répétitive par rapport à un objet Timer.
TimeZone représente un fuseau horaire a time zone offset, and also figures out daylight savings.
TreeMap représente une implémentation de l'interface SortedMap.
TreeSet implémente l'interface Set renforcée par une instance de TreeMap.
Vector implémente un tableau d'objets susceptibles de s'expandre.
WeakHashMap représente une implémentation d'un objet Map basé sur une table de hachage avec des clès faibles.

Le exceptions
ConcurrentModificationException peut être lancée par des méthodes qui ont détecté une modification concurrente d'un objet lorsque de telles modifications ne sont pas autorisées.
EmptyStackException est lancée par des méthodes dans la classe Stack pour indiquer que la pile est vide.
MissingResourceException signale qu'une ressource est manquante.
NoSuchElementException est lancée par la méthode nextElement d'un objet Enumeration pour indiquer qu'il n'y a pas plus d'éléments dans l'énumeration.
TooManyListenersException est utilisée comme une partie du modèle Event pour remarquer et implémenter un cas spécial d'unicast d'une source Event multicast.

42.1 / La classe AbstractCollection

La classe AbstractCollection fournit une exécution squelettique de l'interface Collection afin de minimiser les tentatives requises pour implémenter cette interface.

Pour implémenter une collection non-modifiable, le programmeur a seulement besoin d'étendre la classe AbstractCollection et fournir les implémentations pour les méthodes iterator() et size().

Les constructeurs
protected AbstractCollection()
permet d'instancier un objet AbstractCollection.

Les méthodes
boolean add(Object o)
ajoute à la collection l'élément spécifié.
boolean addAll(Collection c)
ajoute tous les éléments de la collection passée en argument.
void clear()
supprime tous les éléments de la collection abstraite.
boolean contains(Object o)
retourne true si cette collection contient l'élément spécifié.
boolean containsAll(Collection c)
retourne true si l'objet AbstractCollection contient tous les éléments de la collection spécifiée.
boolean isEmpty()
retourne true si cette collection ne contient pas d'éléments.
abstract Iterator iterator()
retourne un itérateur sur les éléments contenus dans cette collection.
boolean remove(Object o)
supprime une instance unique de l'élément spécifié s'il est présent, dans la collection.
boolean removeAll(Collection c)
supprime tous les éléments contenus dans la collection spécifiée, dans l'objet AbstractCollection courant.
boolean retainAll(Collection c)
maintient seulement les éléments dans l'objet AbstractCollection, qui sont contenus dans la collection spécifiée.
abstract int size()
retourne le nombre d'éléments de cette collection.
Object[] toArray()
retourne un tableau contenant tous les éléments de cette collection.
Object[] toArray(Object[] a)
retourne un tableau contenant tous les éléments de cette collection. Le type d'exécution du tableau retourné est celui du tableau spécifié.
String toString()
retourne une chaîne de caractères représentant cette collection.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Les méthodes héritées à partir de l'interface java.util.Collection
equals, hashCode

42.2 / La classe AbstractList

La classe AbstractList fournit une exécution squelettique de l'interface List afin de réduire au minimum l'effort exigé pour mettre en application cette interface soutenue par un conteneur de données "d'accès aléatoire" (tel que dans un tableau).

Pour implémenter la liste non-modifiable, il faut seulement étendre la classe AbstractList et fournir les implémentations pour les méthodes get(int index) et size().

Les champs
protected int modCount
représente le nombre de fois que cette liste a été modifiée structurellement.

Les constructeurs
protected AbstractList()
permet d'instancier un objet AbstractList.

Les méthodes
void add(int index, Object element)
insère l'élément spécifié à la position donnée dans la liste.
boolean add(Object o)
ajoute l'élément spécifié à la fin de la liste.
boolean addAll(int index, Collection c)
insère à la position donnée, tous les éléments de la collection spécifiée dans la liste courante.
void clear()
supprime tous les éléments de la liste.
boolean equals(Object o)
teste l'égalité entre l'objet spécifié et la liste courante.
abstract Object get(int index)
retourne l'élément à la position spécifiée dans la liste.
int hashCode()
retourne le code de hachage pour cette liste.
int indexOf(Object o)
retourne l'index de la première occurrence de l'élément spécifié ou -1 s'il ne le trouve pas.
Iterator iterator()
retourne un itérateur sur les éléments de cette liste dans une séquence appropriée.
int lastIndexOf(Object o)
retourne l'index de la dernière occurrence de l'élément spécifié ou -1 s'il ne le trouve pas.
ListIterator listIterator()
retourne un itérateur des éléments de la liste courante dans une séquence appropriée.
ListIterator listIterator(int index)
retourne un itérateur de liste des éléments dans l'objet AbstractList en démarrant à la position spécifiée.
Object remove(int index)
supprime les éléments à la position spécifiée dans la liste.
protected void removeRange(int fromIndex, int toIndex)
supprime de la liste tous les éléments desquels l'index est entre la valeur fromIndex inclus et toIndex exclus.
Object set(int index, Object element)
remplace l'élément à la position spécifiée par le nouvel élément fourni.
List subList(int fromIndex, int toIndex)
retourne une vue d'une partie de la liste entre la valeur de fromIndex inclus et toIndex exclus.
Les méthodes héritées de la classe java.util.AbstractCollection
addAll, contains, containsAll, isEmpty, remove, removeAll, retainAll, size, toArray, toArray, toString
Les méthodes héritées de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.List
addAll, contains, containsAll, isEmpty, remove, removeAll, retainAll, size, toArray, toArray

42.3 / La classe AbstractMap

La classe AbstractMap fournit une exécution squelettique de l'interface Map afin de minimiser l'effot exigé pour implémenter cette interface.

Pour implémenter un objet Map non-modifiable, il faut seulement étendre la classe AbstractMap et fournir une implementation pour la méthode entrySet().

Les classes imbriquées
Les classes imbriquées héritées de la classe java.util.Map
Map.Entry

Les constructeurs
protected AbstractMap()
permet d'instancier un objet AbstractMap.

Les méthodes
void clear()
supprime tous les paires clé/valeur de l'objet AbstractMap.
protected Object clone()
retourne une copie de référence de l'objet AbstractMap. Les clés et les valeurs ne sont pas recopiées.
boolean containsKey(Object key)
retourne true si l'objet contient une paire clé/valeur correspondant à la clé spécifiée.
boolean containsValue(Object value)
retourne true si l'objet contient une ou plusieurs clés vers la valeur spécifiée.
abstract Set entrySet()
retourne une vue d'ensemble des paires clé/valeur contenu dans l'objet AbstractMap.
boolean equals(Object o)
teste l'égalité entre l'objet spécifié et l'instance de la classe AbstractMap.
Object get(Object key)
retourne la valeur qui correspond à la clé passée en argument.
int hashCode()
retourne la valeur du code de hachage pour l'objet AbstractMap.
boolean isEmpty()
retourne true si l'objet ne contient aucune paire clé/valeur.
Set keySet()
retourne une vus d'ensemble des clés contenues dans l'objet AbstractMap.
Object put(Object key, Object value)
associe la valeur spécifiée à la clé donnée et insère la paire au sein de l'objet AbstractMap.
void putAll(Map t)
copie toutes les paires clé/valeur de l'objet Map spécifié dans l'instance de la classe AbstractMap.
Object remove(Object key)
supprime la paire clé/valeur correspondant à la clé passé en argument.
int size()
retourne le nombre de paires clé/valeur contenues dans l'objet AbstractMap.
String toString()
retourne une chaîne de caractères représentant l'objet AbsstractMap.
Collection values()
retourne une collection reflétant les valeurs contenues dans l'objet AbstractMap.
Les méthodes héritées de la class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.4 / La classe AbstractSequentialList

La classe AbstractSequentialList fournit une exécution squelettique de l'interface List afin de minimiser l'effot exigé pour implémenter cette interface renforcée par un conteneur de données à "accès séquentiel" (tel qu'une liste chaînée).

Pour implémenter une liste séquentielle, il faut seulement étendre la classe AbstractSequentialList et frounir les implémentations des méthodes listIterator() et size(), pour la liste séquentielle non-modifiable, ce sera les méthodes hasNext(), next(), hasPrevious(), previous() et index().

Les champs
Les champs hérités de la classe java.util.AbstractList
modCount

Les constructeurs
protected AbstractSequentialList()
permet d'instancier un objet AbstractSequentialList.

Les méthodes
void add(int index, Object element)
insère l'élément spécifié à la position donnée dans la liste séquentielle.
boolean addAll(int index, Collection c)
insère tous les élément de la collection spécifiée à partir de la position spécifiée au sein de la liste séuqentielle courante.
Object get(int index)
retourne l'élément à la position spécifiée au sein de la liste.
Iterator iterator()
retourne un itérateur sur les éléments de cette liste dans une séquence appropriée.
abstract ListIterator listIterator(int index)
retourne un objet ListIterator sur les éléments de cette liste.
Object remove(int index)
supprime l'élément à la position spécifiée dans cette liste.
Object set(int index, Object element)
remplace l'élément à la position spécifiée par l'objet passé en argument.
Les méthodes héritées de la classe java.util.AbstractList
add, clear, equals, hashCode, indexOf, lastIndexOf, listIterator, removeRange, subList
Les méthodes héritées de la classe java.util.AbstractCollection
addAll, contains, containsAll, isEmpty, remove, removeAll, retainAll, size, toArray, toArray, toString
Les méthodes héritées de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.List
addAll, contains, containsAll, isEmpty, remove, removeAll, retainAll, size, toArray, toArray

42.5 / La classe AbstractSet

La classe AbstractSet fournit une exécution squelettique de l'interface Set afin de minimiser l'effot exigé pour implémenter cette interface.

Le processus d'implémentation d'un ensemble par extension de la classe AbstractSet est identique à l'implémentation d'une collection par extension de la classe AbstractCollection, à l'exception que toutes les méthodes et constructeurs dans les sous-classes de la classe AbstractSet doivent obéir aux contraintes supplémentaires imposées par l'interface set.

Les constructeurs
protected AbstractSet()
permet d'instancier un objet AbstractSet.

Les méthodes
boolean equals(Object o)
teste l'égalité de l'objet spécifié par rapport à l'objet AbstractSet courant.
int hashCode()
retourne la valeur du code de hachage pour cet ensemble.
boolean removeAll(Collection c)
supprime de l'objet AbstractSet, tous les éléments de la collection spécifiée s'ils sont trouvés.
Les méthodes héritées de la classe java.util.AbstractCollection
add, addAll, clear, contains, containsAll, isEmpty, iterator, remove, retainAll, size, toArray, toArray, toString
Les méthodes héritées de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Set
add, addAll, clear, contains, containsAll, isEmpty, iterator, remove, retainAll, size, toArray, toArray

42.6 / La classe ArrayList

La classe ArrayList représente un tableau redimensionnable implémentant l'interface List.

La classe ArrayList implémente toutes les opérations de liste optionnelles et autorise tous les élément en incluant également la valeur null. En plus de l'implémentation de l'interface List, cette classe fournit les méthodes pour manipuler la taille du tableau qui est utilisée intérieurement pour stocker la liste.

La classe ArrayList quasiment identique à la classe Vector, à l'exception qu'elle n'est pas synchronisée.

Les champs
Les champs hérités de la classe java.util.AbstractList
modCount

Les constructeurs
ArrayList()
permet d'instancier un objet ArrayList vide avec une capacité intiale de dix éléments.
ArrayList(Collection c)
permet d'instancier un objet ArrayList contenant la liste des éléments fournis par la collection spécifiée.
ArrayList(int initialCapacity)
permet d'instancier une liste vide avec une capacité initiale spécifiée.

Les méthodes
void add(int index, Object element)
insère l'élément spécifiée à la position donnée au sein de la liste.
boolean add(Object o)
ajoute un élément spécifié à la fin de la liste.
boolean addAll(Collection c)
ajoute tous les éléments de la collection spécifiée à la fin de la liste.
boolean addAll(int index, Collection c)
insère tous les éléments de la collection spécifiée à partir de la position donnée.
void clear()
supprime tous les éléments de la liste.
Object clone()
retourne une copie de référence de l'objet ArrayList. Les valeurs ne sont pas recopiées.
boolean contains(Object elem)
retourne true si la liste contient l'élément spécifié.
void ensureCapacity(int minCapacity)
augmente la capacité minimum de l'objet ArrayList si cela est nécessaire.
Object get(int index)
retourne l'élément à la position spécifiée dans la liste.
int indexOf(Object elem)
recherche la première occurrence de l'élément spécifié en utilisant la méthode equals().
boolean isEmpty()
vérifie si la liste n'a aucun élément.
int lastIndexOf(Object elem)
retourne l'index de la dernière occurrence de l'objet spécifié dans le liste.
Object remove(int index)
supprime les éléments à la position spécifiée dans la liste.
protected void removeRange(int fromIndex, int toIndex)
supprime de la liste tous les éléments compris entre les valeurs de fromIndex inclus et toIndex exclus.
Object set(int index, Object element)
remplace l'élément à la position spécifiée par l'élément spécifié.
int size()
retourne le nombre d'éléments contenus dans la liste.
Object[] toArray()
retourne un tableau contenant tous les éléments de la liste dans l'ordre exact.
Object[] toArray(Object[] a)
retourne un tableau contenant tous les éléments de la liste dans un ordre exact. Le type d'exécution du tableau retourné est celui du tableau entré en argument.
void trimToSize()
réinitialise la capacité de la liste au nombre effectif d'éléments contenus par cette liste.
Les méthodes héritées de la class java.util.AbstractList
equals, hashCode, iterator, listIterator, listIterator, subList
Les méthodes héritées de la class java.util.AbstractCollection
containsAll, remove, removeAll, retainAll, toString
Les méthodes héritées de la class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de la interface java.util.List
containsAll, equals, hashCode, iterator, listIterator, listIterator, remove, removeAll, retainAll, subList

42.7 / La classe Arrays

La classe Arrays contient des méthodes permettant une manipulation des tableaux, telle que la recherche, le trie ou le remplissage.

Cette classe ne peut être instanciée. C'est-pourquoi, la classe Arrays ne contient que des méthodes statiques.

Les méthodes
static List asList(Object[] a)
retourne une liste de taille fixée renforcée par le tableau spécifié.
static int binarySearch(byte[] a, byte key)
recherche les octets du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static int binarySearch(char[] a, char key)
recherche les caractères du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static int binarySearch(double[] a, double key)
recherche les valeurs de type double du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static int binarySearch(float[] a, float key)
recherche les valeurs de type float du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static int binarySearch(int[] a, int key)
recherche les valeurs de type int du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static int binarySearch(long[] a, long key)
recherche les valeurs de type long du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static int binarySearch(Object[] a, Object key)
recherche les objets du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static int binarySearch(Object[] a, Object key, Comparator c)
recherche les caractères du tableau spécifié en fonction de la valeur fournie et d'un comparateur passé en argument ainsi qu'en utilisant un algorithme de recherche binaire.
static int binarySearch(short[] a, short key)
recherche les valeurs de type short du tableau spécifié en fonction de la valeur fournie et en utilisant un algorithme de recherche binaire.
static boolean equals(boolean[] a, boolean[] a2)
retourne true si les deux tableaux de booléens spécifiés sont égaux à un autre.
static boolean equals(byte[] a, byte[] a2)
retourne true si les deux tableaux d'octets spécifiés sont égaux à un autre.
static boolean equals(char[] a, char[] a2)
retourne true si les deux tableaux de caractères spécifiés sont égaux à un autre.
static boolean equals(double[] a, double[] a2)
retourne true si les deux tableaux de valeurs de type double spécifiés sont égaux à un autre.
static boolean equals(float[] a, float[] a2)
retourne true si les deux tableaux de valeurs de type float spécifiés sont égaux à un autre.
static boolean equals(int[] a, int[] a2)
retourne true si les deux tableaux de valeurs de type int spécifiés sont égaux à un autre.
static boolean equals(long[] a, long[] a2)
retourne true si les deux tableaux de valeurs de type long spécifiés sont égaux à un autre.
static boolean equals(Object[] a, Object[] a2)
retourne true si les deux tableaux d'objets spécifiés sont égaux à un autre.
static boolean equals(short[] a, short[] a2)
retourne true si les deux tableaux de valeurs de type short spécifiés sont égaux à un autre.
static void fill(boolean[] a, boolean val)
affecte la valeur booléenne spécifiée à chaque élément du tableau de booléens passé en argument.
static void fill(boolean[] a, int fromIndex, int toIndex, boolean val)
affecte la valeur booléenne spécifiée à chaque élément du tableau de booléen fourni et au sein de l'intervalle donnée.
static void fill(byte[] a, byte val)
affecte la valeur de type byte spécifiée à chaque élément du tableau de bytes.
static void fill(byte[] a, int fromIndex, int toIndex, byte val)
affecte la valeur de type byte spécifiée à chaque élément du tableau de bytes fourni et au sein de l'intervalle donnée.
static void fill(char[] a, char val)
affecte la valeur de type char spécifiée à chaque élément du tableau de caractères.
static void fill(char[] a, int fromIndex, int toIndex, char val)
affecte la valeur de type char spécifiée à chaque élément du tableau de caractères fourni et au sein de l'intervalle donnée.
static void fill(double[] a, double val)
affecte la valeur de type double spécifiée à chaque élément du tableau de doubles.
static void fill(double[] a, int fromIndex, int toIndex, double val)
affecte la valeur de type double spécifiée à chaque élément du tableau de doubles fourni et au sein de l'intervalle donnée.
static void fill(float[] a, float val)
affecte la valeur de type float spécifiée à chaque élément du tableau de floats.
static void fill(float[] a, int fromIndex, int toIndex, float val)
affecte la valeur de type float spécifiée à chaque élément du tableau de floats fourni et au sein de l'intervalle donnée.
static void fill(int[] a, int val)
affecte la valeur de type int spécifiée à chaque élément du tableau d'entiers.
static void fill(int[] a, int fromIndex, int toIndex, int val)
affecte la valeur de type int spécifiée à chaque élément du tableau d'entiers fourni et au sein de l'intervalle donnée.
static void fill(long[] a, int fromIndex, int toIndex, long val)
affecte la valeur de type long spécifiée à chaque élément du tableau d'entiers longs fourni et au sein de l'intervalle donnée.
static void fill(long[] a, long val)
affecte la valeur de type long spécifiée à chaque élément du tableau de longs.
static void fill(Object[] a, int fromIndex, int toIndex, Object val)
affecte l'objet spécifié à chaque élément du tableau d'objets fourni et au sein de l'intervalle donnée.
static void fill(Object[] a, Object val)
affecte l'objet spécifié à chaque élément du tableau d'objets.
static void fill(short[] a, int fromIndex, int toIndex, short val)
affecte la valeur de type short spécifiée à chaque élément du tableau de shorts fourni et au sein de l'intervalle donnée.
static void fill(short[] a, short val)
affecte la valeur de type short spécifiée à chaque élément du tableau de shorts.
static void sort(byte[] a)
trie le tableau d'octets spécifié, dans un ordre numérique ascendant.
static void sort(byte[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau d'octets spécifié, dans un ordre numérique ascendant.
static void sort(char[] a)
trie le tableau de caractères spécifié, dans un ordre numérique ascendant.
static void sort(char[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau de caractères spécifié, dans un ordre numérique ascendant.
static void sort(double[] a)
trie le tableau de valeurs type double spécifié, dans un ordre numérique ascendant.
static void sort(double[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau de valeurs de type double spécifié, dans un ordre numérique ascendant.
static void sort(float[] a)
trie le tableau de valeurs de type float spécifié, dans un ordre numérique ascendant.
static void sort(float[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau de valeurs de type float spécifié, dans un ordre numérique ascendant.
static void sort(int[] a)
trie le tableau de valeurs de type int spécifié, dans un ordre numérique ascendant.
static void sort(int[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau de valeurs de type int spécifié, dans un ordre numérique ascendant.
static void sort(long[] a)
trie le tableau de valeurs de type long spécifié, dans un ordre numérique ascendant.
static void sort(long[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau de valeurs de type long spécifié, dans un ordre numérique ascendant.
static void sort(Object[] a)
trie le tableau d'objets spécifié, dans un ordre ascendant selon un ordonnancement naturel de ses éléments.
static void sort(Object[] a, Comparator c)
trie le tableau d'objets spécifié en fonction d'un ordonnancement induit par l'objet Comparator spécifié.
static void sort(Object[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau d'objets spécifié, dans un ordre numérique ascendant en fonction de l'ordre naturel de ses éléments.
static void sort(Object[] a, int fromIndex, int toIndex, Comparator c)
trie un intervalle (formIndex-toIndex) du tableau d'objets spécifié, dans un ordre numérique ascendant en fonction de l'ordre induit par l'objet Comparator spécifié.
static void sort(short[] a)
trie le tableau de valeurs de type short spécifié, dans un ordre numérique ascendant.
static void sort(short[] a, int fromIndex, int toIndex)
trie un intervalle (formIndex-toIndex) du tableau de valeurs de type short spécifié, dans un ordre numérique ascendant.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.8 / La classe BitSet

La classe BitSet implément un vecteur de bits qui peut croître si cela est nécessaire/ Chaque composant de l'objet BitSet possède une valeur booléenne. Par défaut, tous les bits de cet ensemble sont intialement égaux à false.

Les constructeurs
BitSet()
crée un nouvel ensemble de bits.
BitSet(int nbits)
crée un ensemble de bits qui possède une taille initiale passée en argument.

Les méthodes
void and(BitSet set)
exécute un ET logique sur l'objet BitSet par rapport à l'argument donné.
void andNot(BitSet set)
efface tous les bits de l'objet BitSet dont le bit correspondant est fixé dans l'objet set passé en argument.
int cardinality()
retourne le nombre de bits fixé à true dans l'objet BitSet.
void clear()
fixe tous les bits de l'ensemble courant à false.
void clear(int bitIndex)
fixe le bit spécifié par l'indes à false.
void clear(int fromIndex, int toIndex)
fixe les bits entre les valeurs de fromIndex inclus et toIndex exclus à false.
Object clone()
recopie l'objet BitSet en un nouveau qui lui est égal.
boolean equals(Object obj)
teste l'égalité de l'objet spécifié par rapport à l'objet BitSet courant.
void flip(int bitIndex)
fixe le bit à l'index spécifié au complément de sa valeur courante.
void flip(int fromIndex, int toIndex)
fixe les bits entre les valeurs fromIndex inclus et toIndex exclus au complément de leur valeur courante.
boolean get(int bitIndex)
retourne la valeur du bit par rapport à l'index spécifié.
BitSet get(int fromIndex, int toIndex)
retourne un nouvel objet BitSet composé des bits extraits de l'objet BitSet courant entre les valeurs fromIndex inclus et toIndex exclus.
int hashCode()
retourne le code de hachage pour l'objet BitSet.
boolean intersects(BitSet set)
retourne true si l'objet BitSet spécifié possède des bits fixés à true qui sont également fixé à true dans l'objet BitSet courant.
boolean isEmpty()
retourne true si l'objet BitSet ne contient aucun bit fixé à true.
int length()
retourne la taille logique de l'objet BitSet.
int nextClearBit(int fromIndex)
retourne l'index du premier bit qui est fixé à false à partir de l'index de départ spécifié.
int nextSetBit(int fromIndex)
retourne l'index du premier bit qui est fixé à true à partir de l'index de départ spécifié.
void or(BitSet set)
exécute un OU logique de l'objet BitSet courant par rapport à l'objet passé en argument.
void set(int bitIndex)
fixe le bit trouvé à l'index spécifié, à true.
void set(int bitIndex, boolean value)
fixe le bit trouvé à l'index spécifié, à la valeur spécifiée.
void set(int fromIndex, int toIndex)
fixe les bits positionnés entre les valeurs fromIndex inclus et toIndex exclus à true.
void set(int fromIndex, int toIndex, boolean value)
fixe les bits positionnés entre les valeurs fromIndex inclus et toIndex exclus à la valeur spécifiée.
int size()
retourne le nombre de bits utilisés actuellement par l'objet BitSet.
String toString()
retourne une chaîne de caractères représentant l'objet BitSet.
void xor(BitSet set)
exécute un XOR logique de l'objet BitSet courant par rapport à l'argument fourni.
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.9 / La classe Calendar

La classe Calendar est une classe abstraite pour la conversion entre un objet Date et un ensemble de champs entiers tels que YEAR, MONTH, DAY, etc..

Les champs
static int AM
indique la partie d'un jour AM (After Meridian), soit à partir de minuit et jusqu'à midi exclus ou PM (Post Meridian).
static int AM_PM
représente un champ numérique accessible en lecture et écriture indiquant la partie d'un jour, soit avan midi (AM) ou après midi (PM).
static int APRIL
indique le quatrième mois de l'année.
protected boolean areFieldsSet
contient true si le tableau fields[] est synchronisé avec le temps fixé actuellement.
static int AUGUST
indique le huitième mois de l'année.
static int DATE
représente un champ numérique accessible en lecture et écriture indiquant le jour du mois.
static int DAY_OF_MONTH
représente un champ numérique accessible en lecture et écriture indiquant le jour du mois.
static int DAY_OF_WEEK
représente un champ numérique accessible en lecture et écriture indiquant le jour de la semaine.
static int DAY_OF_WEEK_IN_MONTH
représente un champ numérique accessible en lecture et écriture indiquant le nombre ordinal de jour de la semaine à partir du mois courant.
static int DAY_OF_YEAR
représente un champ numérique accessible en lecture et écriture indiquant le nombre de jour à partir de l'année courante.
static int DECEMBER
indique le douzième mois de l'année.
static int DST_OFFSET
représente un champ numérique accessible en lecture et écriture indiquant le nombre de millisecondes du jour.
static int ERA
représente un champ numérique accessible en lecture et écriture indiquant l'ère telle que AD ou BC dans le calendrier Julien.
static int FEBRUARY
indique le deuxième mois de l'année.
static int FIELD_COUNT
indique le nombre de champs distincts reconnus par les accesseurs et les mutateurs.
protected int[] fields
représente les valeurs du temps courant par rapport au calendrier.
static int FRIDAY
représente une valeur de la semaine, soit vendredi.
static int HOUR
représente un champ numérique accessible en lecture et écriture indiquant l'heure du matin ou de l'après-midi.
static int HOUR_OF_DAY
représente un champ numérique accessible en lecture et écriture indiquant l'heure du jour.
protected boolean[] isSet
représente un drapeau qui indique si le temps pour le calendrier est fixé.
protected boolean isTimeSet
contient true si la valeur du temps est valide.
static int JANUARY
indique le premier mois de l'année.
static int JULY
indique le septième mois de l'année.
static int JUNE
indique le sixième mois de l'année.
static int MARCH
indique le troisième mois de l'année.
static int MAY
indique le cinquième mois de l'année.
static int MILLISECOND
représente un champ numérique accessible en lecture et écriture indiquant les millisecondes d'une seconde.
static int MINUTE
représente un champ numérique accessible en lecture et écriture indiquant les minutes d'une heure.
static int MONDAY
représente une valeur de la semaine, soit lundi.
static int MONTH
représente un champ numérique accessible en lecture et écriture indiquant le mois.
static int NOVEMBER
indique le onzième mois de l'année.
static int OCTOBER
indique le dixième mois de l'année.
static int PM
indique la partie d'un jour PM (Post Meridian), soit à partir de midi et jusqu'à minuit exclus
static int SATURDAY
représente une valeur de la semaine, soit samedi.
static int SECOND
représente un champ numérique accessible en lecture et écriture indiquant les secondes dans une minute.
static int SEPTEMBER
indique le neuvième mois de l'année.
static int SUNDAY
représente une valeur de la semaine, soit dimanche.
static int THURSDAY
représente une valeur de la semaine, soit jeudi.
protected long time
indique le temps courant exprimé en millisecondes depuis le 1er janvier 1970 à 00:00:00 GMT.
static int TUESDAY
représente une valeur de la semaine, soit mardi.
static int UNDECIMBER
représente la valeur du champ MONTH indiquant le treizième mois de l'année.
static int WEDNESDAY
représente une valeur de la semaine, soit mercredi.
static int WEEK_OF_MONTH
représente un champ numérique accessible en lecture et écriture indiquant le nombre de semaine dans le mois courant.
static int WEEK_OF_YEAR
représente un champ numérique accessible en lecture et écriture indiquant le nombre de semaines dans l'année courante.
static int YEAR
représente un champ numérique accessible en lecture et écriture indiquant l'année sous forme d'un entier.
static int ZONE_OFFSET
représente un champ numérique accessible en lecture et écriture indiquant la compensation (offset) brute en millisecondes à partir de l'heure du méridien de Greenwich.

Les constructeurs
protected Calendar()
crée un objet Calendar avec le fuseau horaire local par défaut.
protected Calendar(TimeZone zone, Locale aLocale)
crée un objet Calendar avec un fuseau horaire et des ressources locales spécifiés.

Les méthodes
abstract void add(int field, int amount)
ajoute la valeur temporelle amount au champ passé en argument.
boolean after(Object when)
vérifie si l'état du champ time est après le temps l'objet when.
boolean before(Object when)
vérifie si l'état du champ time est avant le temps l'objet when.
void clear()
efface les valeurs de tous les champs de l'objet Calendar.
void clear(int field)
efface la valeur dans le champ passé en argument.
Object clone()
retourne un clone de l'instance de la classe Calendar.
protected void complete()
remplit les champs non-fixés dans la liste du champ temporel.
protected abstract void computeFields()
convertit la valeur du temps courant exprimé en millisecondes en valeurs de champs rangés dans un tableau fields[].
protected abstract void computeTime()
convertit les valeurs dans le tableau fields[] vers un temps exprimé en millisecondes.
boolean equals(Object obj)
teste l'égalité entre l'objet Calendar et l'objet spécifié.
int get(int field)
retourne la valeur du champ passé en argument.
int getActualMaximum(int field)
retourne la valeur maximum que le champ spécifié pourraient avoir, étant donné la date courante.
int getActualMinimum(int field)
retourne la valeur minimum que le champ spécifié pourraient avoir, étant donné la date courante.
static Locale[] getAvailableLocales()
retourne la liste de ressources locales pour les calendriers qui sont installés.
int getFirstDayOfWeek()
retourne un entier représentant le premier jour de la semaine tel que Sunday pour les anglais et Monday pour la France.
abstract int getGreatestMinimum(int field)
retourne la plus haute valeur minimum pour le champ donné.
static Calendar getInstance()
retourne un objet Calendar en se fondant sur le fuseau horaire et les ressources locales sous-jacentes de la machine.
static Calendar getInstance(Locale aLocale)
retourne un objet Calendar en se fondant sur le fuseau horaire et les ressources locales passées en argument.
static Calendar getInstance(TimeZone zone)
retourne un objet Calendar en se fondant sur le fuseau horaire passé en argument et les ressources locales.
static Calendar getInstance(TimeZone zone, Locale aLocale)
retourne un objet Calendar en se fondant sur le fuseau horaire et les ressources locales passés en argument.
abstract int getLeastMaximum(int field)
retourne la plus petite valeur maximum pour le champ donné.
abstract int getMaximum(int field)
retourne la valeur maximum pour le champ donné.
int getMinimalDaysInFirstWeek()
retourne les jours minimaux requis dans la première semaine de l'année.
abstract int getMinimum(int field)
retourne la valeur miniimum pour le champ donné.
Date getTime()
retourne le temps courant de l'objet Calendar dans un objet Date.
long getTimeInMillis()
retourne le temps courant de l'objet Calendar dans un entier.
TimeZone getTimeZone()
retourne le fuseau horaire.
int hashCode()
retourne le code de hachage de l'objet Calendar.
protected int internalGet(int field)
retourne la valeur entière pour un champ donné.
boolean isLenient()
indique si l'interprétation date/time est délicate.
boolean isSet(int field)
détermine si le champ donné a une valeur fixée.
abstract void roll(int field, boolean up)
ajoute (up=true) ou soustrait (up=false) une unique unité de temps à un champ donné.
void roll(int field, int amount)
ajoute au champ une valeur signée amount sans changer la largeur du champ.
void set(int field, int value)
fixe le champ spécifié avec la valeur donnée.
void set(int year, int month, int date)
fixe les valeurs pour les champs year, month, et date.
void set(int year, int month, int date, int hour, int minute)
fixe les valeurs pour les champs year, month, date, hour, et minute.
void set(int year, int month, int date, int hour, int minute, int second)
fixe les valeurs pour les champs year, month, date, hour, minute, et second.
void setFirstDayOfWeek(int value)
fixe le premier jour de la semaine.
void setLenient(boolean lenient)
spécifie si l'interprétation de la date/time peut être délicate.
void setMinimalDaysInFirstWeek(int value)
détermine quels sont les premiers jours minimaux requis dans de la première semaine de l'année.
void setTime(Date date)
fixe le temps courant de l'objet Calendar à la date donnée.
void setTimeInMillis(long millis)
fixe le temps courant de l'objet Calendar à partir de la valeur temporelle exprimée en millisecondes passée en argument.
void setTimeZone(TimeZone value)
fixe le fuseau horaire avec l'objet TimeZone passé en argument.
String toString()
retourne une chaîne de caractères représentant l'objet Calendar courant.
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.10 / La classe Collections

La classe Collections est composée exclusivement de méthodes statiques. Elle contient des méthodes qui permettent de manipuler des collections ou qui construisent des collections.

Les méthodes de cette classe sont susceptibles de lancer une exception du type NullPointerException.

Les champs
static List EMPTY_LIST
représente une liste vide immuable.
static Map EMPTY_MAP
représente un objet Map vide immuable.
static Set EMPTY_SET
représente un ensemble vide immuable.

Les méthodes
static int binarySearch(List list, Object key)
recherche la liste sépcifiée pour la clé donnée en utilisant un algorithme de recherche binaire.
static int binarySearch(List list, Object key, Comparator c)
recherche la liste sépcifiée pour la clé et le comparateur donnés en utilisant un algorithme de recherche binaire.
static void copy(List dest, List src)
copie tous les éléments de la liste source vers la liste destinatrice.
static Enumeration enumeration(Collection c)
retourne un objet Enumeration à partir de la collection spécifiée.
static void fill(List list, Object obj)
remplace tous les éléments de la liste spécifiée par l'élément passé en argument.
static int indexOfSubList(List source, List target)
retourne la position de départ de la première occurrence de la liste cible spécifiée à l'intérieur de la liste source. Si aucune occurrence n'a été trouvé, le résultat est égal à -1
static int lastIndexOfSubList(List source, List target)
retourne la position de départ de la dernière occurrence de la liste cible spécifiée à l'intérieur de la liste source. Si aucune occurrence n'a été trouvé, le résultat est égal à -1
static ArrayList list(Enumeration e)
retourne un objet ArrayList contenant les éléments retournés par l'objet Enumeration passé en argument.
static Object max(Collection coll)
retourne l'élément maximum de la collection donnée par rapport à l'ordonnancement naturel de ses éléments.
static Object max(Collection coll, Comparator comp)
retourne l'élément maximum de la collection donnée par rapport à l'ordre induit par le comparateur spécifié.
static Object min(Collection coll)
retourne l'élément minimum de la collection donnée par rapport à l'ordonnancement naturel de ses éléments.
static Object min(Collection coll, Comparator comp)
retourne l'élément minimum de la collection donnée par rapport à l'ordre induit par le comparateur spécifié.
static List nCopies(int n, Object o)
retourne une liste immuable composée de n copies de l'objet spécifié.
static boolean replaceAll(List list, Object oldVal, Object newVal)
remplace toutes les occurrences d'une ancienne valeur par une nouvelle au sein de la liste spécifiée.
static void reverse(List list)
inverse l'ordre des éléments de la liste spécifiée.
static Comparator reverseOrder()
retourne un comparateur qui impose l'inversion de l'ordonnacement naturel sur une collection d'objets qui impléménte l'interface Comparable.
static void rotate(List list, int distance)
effectue une rotation des éléments de la liste spécifiée par rapport à la distance donnée.
static void shuffle(List list)
permute aléatoirement la liste spécifiée en utilisant une source par défaut d'aspect aléatoire.
static void shuffle(List list, Random rnd)
permute aléatoirement la liste spécifiée en utilisant une source d'aspect aléatoire donnée..
static Set singleton(Object o)
retourne un ensemble immuable contenant seulement l'objet fourni.
static List singletonList(Object o)
retourne une liste immuable contenant seulement l'objet fourni.
static Map singletonMap(Object key, Object value)
retourne un objet Map immuable contenant seulement la paire clé/valeur fournie.
static void sort(List list)
trie la liste spécifiée dans un ordre ascendant en accord avec l'ordonnancement naturel de ses éléments.
static void sort(List list, Comparator c)
trie la liste spécifiée dans un ordre ascendant par rapport au comparateur donné.
static void swap(List list, int i, int j)
échange les éléments aux positions spécifiées dans la liste passée en argument.
static Collection synchronizedCollection(Collection c)
retourne une collection synchronisée (thread-safe) renforcée par la collection spécifiée.
static List synchronizedList(List list)
retourne une liste synchronisée (thread-safe) renforcée par la liste spécifiée.
static Map synchronizedMap(Map m)
retourne un objet Map synchronisé (thread-safe) renforcé par la l'objet spécifié.
static Set synchronizedSet(Set s)
retourne un ensemble synchronisé (thread-safe) renforcé par l'objet Set spécifié.
static SortedMap synchronizedSortedMap(SortedMap m)
retourne un objet SortedMap synchronisé (thread-safe) renforcé par la l'objet spécifié.
static SortedSet synchronizedSortedSet(SortedSet s)
retourne un objet SortedSet synchronisé (thread-safe) renforcé par la l'objet spécifié.
static Collection unmodifiableCollection(Collection c)
retourne une vue non-modifiable de la collection spécifiée.
static List unmodifiableList(List list)
retourne une vue non-modifiable de la liste spécifiée.
static Map unmodifiableMap(Map m)
retourne une vue non-modifiable de l'objet Map spécifié.
static Set unmodifiableSet(Set s)
retourne une vue non-modifiable de l'ensemble spécifié.
static SortedMap unmodifiableSortedMap(SortedMap m)
retourne une vue non-modifiable de l'objet SortedMap spécifié.
static SortedSet unmodifiableSortedSet(SortedSet s)
retourne une vue non-modifiable de l'objet SortedSet spécifié.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.11 / La classe Currency

La classe Currency représente une monnaie. Elle ne possède pas de constructeur capable d'instancier un objet qui pourra utiliser les méthodes de cette classe.

L'obtention d'une instance de Currency est possible par l'intermédiaire d'une de ses méthodes statiques. En effet, les méthode getInstance() fournissent une instance de la classe Currency.

Currency monnaie = Currency.getInstance([codeMonnaie | zoneLocale]);
Les méthodes
String getCurrencyCode()
retourne un code monétaire conforme à l'ISO 4217 de l'objet Currency.
int getDefaultFractionDigits()
retourne le nombre de chiffres après la virgule, utilisé par l'objet Currency.
static Currency getInstance(Locale locale)
retourne une instance de classe Currency de la région désignées par l'objet Locale.
static Currency getInstance(String currencyCode)
retourne une instance de classe Currency en fonction du code monétaire donné.
String getSymbol()
retourne le symbole monétaire par rapport à la zone géographique par défaut.
String getSymbol(Locale locale)
retourne le symbole monétaire par rapport à la zone géographique spécifiée.
String toString()
retourne le code monétaire conforme à l'ISO 4217 pour l'objet Currency courant.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

42.12 / La classe Date

La classe Date représente une date avec une précision jusqu'au millième de seconde.

La classe Date permet l'interprétation des dates en année, mois, jours, heure, minute et seconde, ainsi que le formatage et l'analyse de dates exprimées sous la forme de chaînes de caractères.

Les constructeurs
Date()
crée un objet Date et l'initialise au temps courant.
Date(int year, int month, int date)
Déprécié, remplacé par Calendar.set(year + 1900, month, date) ou GregorianCalendar(year + 1900, month, date).
Date(int year, int month, int date, int hrs, int min)
Déprécié, remplacé par Calendar.set(year + 1900, month, date, hrs, min) ou GregorianCalendar(year + 1900, month, date, hrs, min).
Date(int year, int month, int date, int hrs, int min, int sec)
Déprécié, remplacé par Calendar.set(year + 1900, month, date, hrs, min, sec) ou GregorianCalendar(year + 1900, month, date, hrs, min, sec).
Date(long date)
crée un objet Date et l'initialise avec l'argument date précisant un nombre de millisecondes écoulées depuis le 1er Janvier 1970 à 00:00:00 GMT.
Date(String s)
Déprécié, remplacé par DateFormat.parse(String s).

Les méthodes
boolean after(Date when)
vérifie si la date courante est après la date spécifiée.
boolean before(Date when)
vérifie si la date courante est avant la date spécifiée.
Object clone()
retourne une copie de l'objet Date.
int compareTo(Date anotherDate)
compare les deux objets Date et retourne 0 en cas d'égalité, une valeur négative si la date courante est plus petite que celle de l'argument ou une valeur positive dans l'autre cas.
int compareTo(Object o)
compare l'objet Date à un autre objet.
boolean equals(Object obj)
teste l'égalité entre deux dates.
int getDate()
Dépréciée, remplacée par Calendar.get(Calendar.DAY_OF_MONTH).
int getDay()
Dépréciée, remplacée par Calendar.get(Calendar.DAY_OF_WEEK).
int getHours()
Dépréciée, remplacée par Calendar.get(Calendar.HOUR_OF_DAY).
int getMinutes()
Dépréciée, remplacée par Calendar.get(Calendar.MINUTE).
int getMonth()
Dépréciée, remplacée par Calendar.get(Calendar.MONTH).
int getSeconds()
Dépréciée, remplacée par Calendar.get(Calendar.SECOND).
long getTime()
retourne le nombre de millisecondes depuis le 1er janvier 1970 à 00:00:00 GMT.
int getTimezoneOffset()
Dépréciée, remplacée par -(Calendar.get(Calendar.ZONE_OFFSET) + Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000).
int getYear()
Dépréciée, remplacée par Calendar.get(Calendar.YEAR) - 1900.
int hashCode()
retourne la valeur du code de hachage de l'objet Date.
static long parse(String s)
Dépréciée, remplacée par DateFormat.parse(String s).
void setDate(int date)
Dépréciée, remplacée par Calendar.set(Calendar.DAY_OF_MONTH, int date).
void setHours(int hours)
Dépréciée, remplacée par Calendar.set(Calendar.HOUR_OF_DAY, int hours).
void setMinutes(int minutes)
Dépréciée, remplacée par Calendar.set(Calendar.MINUTE, int minutes).
void setMonth(int month)
Dépréciée, remplacée par Calendar.set(Calendar.MONTH, int month).
void setSeconds(int seconds)
Dépréciée, remplacée par Calendar.set(Calendar.SECOND, int seconds).
void setTime(long time)
fixe un temps exprimé en millisecondes à partir du 1er janvier 1970 à 00:00:00 GMT, pour l'objet Date.
void setYear(int year)
Dépréciée, remplacée par Calendar.set(Calendar.YEAR, year + 1900).
String toGMTString()
Dépréciée, remplacée par DateFormat.format(Date date), voir TimeZone.
String toLocaleString()
Dépréciée, remplacée par DateFormat.format(Date date).
String toString()
Converts this Date object to a String of the form
static long UTC(int year, int month, int date, int hrs, int min, int sec)
Dépréciée, remplacée par Calendar.set(year + 1900, month, date, hrs, min, sec) ou GregorianCalendar(year + 1900, month, date, hrs, min, sec).
Les méthodes héritées à partir de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.13 / La classe Dictionary

La classe Dictionary est le parent abstrait de n'importe quelle classe qui référencerait des paires clé/valeur, tel qu'un objet Hashtable.

Chaque clé et chaque valeur sont des objets. Les clés peuvent être associées avec au moins une valeur.

La méthode equals() doit être utilisée par les implémentations de la classe Dictionary, afin de tester l'égalité entre deux objets faisant office de clés.

Cette classe est obsolète, et doit plutôt être remplacée par une implémentation de l'interface Map.

Les constructeurs
Dictionary()
crée un objet Dictionary.

Les méthodes
abstract Enumeration elements()
retourne une énumération des valeurs dans l'objet Dictionary.
abstract Object get(Object key)
retourne la valeur correspondant à la clé passée en argument.
abstract boolean isEmpty()
vérifie si l'objet Dictionary ne contient aucune paire clé/valeur.
abstract Enumeration keys()
retourne un objet Enumeration contenant les clés de l'objet Dictionary.
abstract Object put(Object key, Object value)
enregistre une paire clé/valeur dans l'objet Dictionary.
abstract Object remove(Object key)
supprime la paire clé/valeur correspondant à la clé passée en argument.
abstract int size()
retourne le nombre d'entrées dans l'objet Dictionary.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.14 / La classe EventListenerProxy

La classe EventListenerProxy constitue une classe abstraite d'emballage (wrapper) pour une classe EventListener qui associe un jeu de paramètres supplémentaires avec l'écouteur d'événements.

Les constructeurs
EventListenerProxy(EventListener listener)
crée un objet EventListenerProxy et l'initialise avec l'objet EventListener.

Les méthodes
EventListener getListener()
retourne l'objet EventListener associé à ce proxy.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.15 / La classe EventObject

La classe EventObject constitue la classe racine à partir duquel tous les objets d'états d'événements seraient dérivés.

Les champs
protected Object source
représente l'objet sur lequel se produit initialement l'objet Event.

Les constructeurs
EventObject(Object source)
crée un objet EventObject en spécifiant l'objet source sur lequel se produit l'événement.

Les méthodes
Object getSource()
retourne l'objet sur lequel se produit l'événement.
String toString()
retourne une chaîne de caractères représentant l'objet EventObject.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

42.16 / La classe GregorianCalendar

La classe GregorianCalendar représente une sous-classe concrète de la classe Calendar et fournit le calendrier standard utilisé par la plupart des pays.

Les champs
static int AD
contient une valeur indiquant l'ère Chrétienne Anno Domini (AD) du champ ERA la classe java.util.Calendar.
static int BC
contient une valeur indiquant l'ère Chrétienne Before Christ (BC) du champ ERA la classe java.util.Calendar..
Les champs hérités de la classe java.util.Calendar
AM, AM_PM, APRIL, areFieldsSet, AUGUST, DATE, DAY_OF_MONTH, DAY_OF_WEEK, DAY_OF_WEEK_IN_MONTH, DAY_OF_YEAR, DECEMBER, DST_OFFSET, ERA, FEBRUARY, FIELD_COUNT, fields, FRIDAY, HOUR, HOUR_OF_DAY, isSet, isTimeSet, JANUARY, JULY, JUNE, MARCH, MAY, MILLISECOND, MINUTE, MONDAY, MONTH, NOVEMBER, OCTOBER, PM, SATURDAY, SECOND, SEPTEMBER, SUNDAY, THURSDAY, time, TUESDAY, UNDECIMBER, WEDNESDAY, WEEK_OF_MONTH, WEEK_OF_YEAR, YEAR, ZONE_OFFSET

Les constructeurs
GregorianCalendar()
crée un objet GregorianCalendar initialisé à la date courante du fuseau horaire et à la zone géographique par défaut.
GregorianCalendar(int year, int month, int date)
crée un objet GregorianCalendar initialisé à la date donnée, par rapport au fuseau horaire et à la zone géographique par défaut.
GregorianCalendar(int year, int month, int date, int hour, int minute)
crée un objet GregorianCalendar initialisé à la date et au temps donnés, par rapport au fuseau horaire et à la zone géographique par défaut.
GregorianCalendar(int year, int month, int date, int hour, int minute, int second)
crée un objet GregorianCalendar initialisé à la date, au temps donné par rapport au fuseau horaire et à la zone géographique par défaut.
GregorianCalendar(Locale aLocale)
crée un objet GregorianCalendar basé sur la zone géographique donnée, sur le temps courant et le fuseau horaire par défaut.
GregorianCalendar(TimeZone zone)
crée un objet GregorianCalendar basé sur le fuseau horaire donné, le temps courant et la zone géographique par défaut.
GregorianCalendar(TimeZone zone, Locale aLocale)
crée un objet GregorianCalendar basé sur le fuseau horaire et la zone géographique donnés, et sur le temps courant.

Les méthodes
void add(int field, int amount)
ajoute une valeur donnée au champ spécifié en se fondant sur les règles de calcul calendaires.
protected void computeFields()
calcule les valeurs des champs par rapport à un temps UTC en millisecondes.
protected void computeTime()
calcule un temps UTC en millisecondes à partir des valeurs des champs.
boolean equals(Object obj)
teste l'égalité entre un objet GregorianCalendar et un autre objet.
int getActualMaximum(int field)
retourne la valeur maximum du champ spécifié.
int getActualMinimum(int field)
retourne la valeur minimum du champ spécifié.
int getGreatestMinimum(int field)
retourne la plus haute valeur minimum du champ spécifié.
Date getGregorianChange()
retourne un objet Date à partir de l'objet GregorianCalendar.
int getLeastMaximum(int field)
retourne la plus petite valeur maximum du champ spécifié.
int getMaximum(int field)
retourne la valeur maximum du champ spécifié.
int getMinimum(int field)
retourne la valeur minimum du champ spécifié.
int hashCode()
génère le code de hachage pour l(objet GregorianCalendar.
boolean isLeapYear(int year)
détermine si l'année fournie est une année bissextile.
void roll(int field, boolean up)
ajoute (up=true) ou soustrait (up=false) une unité de temps sur le champ donné sans modifier la largeur de ce champ.
void roll(int field, int amount)
ajoute au champ spécifié une valeur sans changer la largeur du champ.
void setGregorianChange(Date date)
fixe une date pour l'objet GregorianCalendar.
Les méthodes héritées à partir de la classe java.util.Calendar
after, before, clear, clear, clone, complete, get, getAvailableLocales, getFirstDayOfWeek, getInstance, getInstance, getInstance, getInstance, getMinimalDaysInFirstWeek, getTime, getTimeInMillis, getTimeZone, internalGet, isLenient, isSet, set, set, set, set, setFirstDayOfWeek, setLenient, setMinimalDaysInFirstWeek, setTime, setTimeInMillis, setTimeZone, toString
Les méthodes héritées à partir de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.17 / La classe HashMap

La classe HashMap est une table de hachage implémentant l'interface Map.

Cette implémentation fournit toutes les opérations optionnelles de manipulation d'objet Map et permet les valeurs null et les clés null.

L'objet HashMap est queasiment identique à l'objet Hashtable, à l'exception qu'il n'est pas synchronisé et permet les valeurs nulles.

Les constructeurs
HashMap()
crée un objet HashMap vide d'une capacité initiale (16) et un facteur de charge (0.75) par défaut.
HashMap(int initialCapacity)
crée un objet HashMap vide d'une capacité initiale spécifiée et un facteur de charge par défaut (0.75).
HashMap(int initialCapacity, float loadFactor)
crée un objet HashMap vide d'une capacité initiale et un facteur de charge spécifiés.
HashMap(Map m)
crée un objet HashMap en se fondant sur les mêmes caractéristiques de l'objet Map passé en argument.

Les méthodes
void clear()
supprime toutes les paires clé/valeur de l'objet HashMap.
Object clone()
retourne une copie de référence de l'objet HashMap.
boolean containsKey(Object key)
retourne true si l'objet HashMap contient la clé spécifiée.
boolean containsValue(Object value)
retourne true si l'objet HashMap contient une ou plusieurs clés vers la valeur spécifiée.
Set entrySet()
retourne un objet Set contenant les entrées de l'objet HashMap.
Object get(Object key)
retourne la valeur pointée par la clé spécifiée, ou la valeur null si la clé n'est pas trouvée.
boolean isEmpty()
retourne true si l'objet HashMap ne contient aucune paire clé/valeur.
Set keySet()
retourne un objet Set contenant les clés de l'objet HashMap.
Object put(Object key, Object value)
associe la valeur spécifiée à la clé fournie dans l'objet HashMap.
void putAll(Map m)
copie toutes les paires clé/valeur de l'objet Map spécifié au sein de l'objet HashMap.
Object remove(Object key)
supprime la paire clé/valeur correspondant à la clé passée en argument.
int size()
retourne le nombre de paire clé/valeur contenue dans l'objet HashMap.
Collection values()
retourne une collection contenant les valeurs de l'objet HashMap.
Les méthodes héritées à partir de la classe java.util.AbstractMap
equals, hashCode, toString
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Map
equals, hashCode

42.18 / La classe HashSet

La classe HashSet implémente l'interface Set et est renforcée par une table de hachage.

L'objet HashSet n'est pas synchronisé.

Les constructeurs
HashSet()
crée un objet HashSet vide d'une capacité initiale (16) et un facteur de charge (0.75) par défaut.
HashSet(Collection c)
crée un objet HashSet contenant les éléments de la collection spécifiée.
HashSet(int initialCapacity)
crée un objet HashSet vide avec une capacité initiale spécifiée et un facteur de charge par défaut (0.75).
HashSet(int initialCapacity, float loadFactor)
crée un objet HashSet vide avec une capactité initiale et un facteur de charge spécifiés.

Les méthodes
boolean add(Object o)
ajoute l'élément spécifié à l'objet HashMap, s'il n'est pas déjà présent.
void clear()
supprime tous les éléments de l'objet HashMap.
Object clone()
retourne une copie de référence de l'objet HashSet.
boolean contains(Object o)
retourne true si l'objet HashSet contient l'élément spécifié.
boolean isEmpty()
retourne true si l'objet HashSet ne contient aucun élément.
Iterator iterator()
retourne un itérateur sur les éléments de l'objet hashSet.
boolean remove(Object o)
supprime l'élément spécifié de l'objet HashSet, s'il est présent.
int size()
retourne le nombre d'éléments contenus dans l'objet HashSet.
Les méthodes héritées à partir de la classe java.util.AbstractSet
equals, hashCode, removeAll
Les méthodes héritées à partir de la classe java.util.AbstractCollection
addAll, containsAll, retainAll, toArray, toArray, toString
Les méthodes héritées à partir de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Set
addAll, containsAll, equals, hashCode, removeAll, retainAll, toArray, toArray

42.19 / La classe Hashtable

La classe Hashtable implémente l'interface Map et est destinée à contenir des paires d'objets non-nulles clé/valeur.

Le stockage et la récupération des objets à partir d'un objet Hashtable, nécessitent d'implémenter les méthodes hashCode() et equals() dans les objets utilisés comme clés.

Les constructeurs
Hashtable()
crée un objet HashTable vide d'une capacité initiale (11) et un facteur de charge (0.75) par défaut.
Hashtable(int initialCapacity)
crée un objet Hashtable vide, d'une capacité initiale spécifiée et d'un facteur de charge par défaut (0.75).
Hashtable(int initialCapacity, float loadFactor)
crée un objet Hashtable vide, d'une capacité initiale et d'un facteur de charge spécifiés.
Hashtable(Map t)
crée un objet Hashtable contenant les paires clé/valeur de l'objet Map passé en argument.

Les méthodes
void clear()
efface toutes les paires clé/valeur de l'objet Hashtable.
Object clone()
crée une copie de référence de l'objet Hashtable.
boolean contains(Object value)
teste si l'objet Hashtable contient des clés référençant la valeur spécifiée.
boolean containsKey(Object key)
vérifie la présence de la clé spécifiée dans l'objet Hashtable.
boolean containsValue(Object value)
retourne true si l'objet Hashtable contient une ou plusieurs clés référençant la valeur spécifiée.
Enumeration elements()
retourne une énumération des valeurs contenues dans l'objet Hashtable.
Set entrySet()
retourne un objet Set contenant les entrées de l'objet Hashtable.
boolean equals(Object o)
teste l'égalité entre l'objet Hashtable et un autre objet.
Object get(Object key)
retourne la valeur pontée par la clé spécifiée dans l'objet Hashtable.
int hashCode()
retourne le code de hachage pour l'objet Hashtable.
boolean isEmpty()
vérifie si l'objet Hashtable ne contient aucune paire clé/valeur.
Enumeration keys()
retourne une énumération des clés de l'objet Hashtable.
Set keySet()
retourne une objet Set contenant les clés de l'objet Hashtable.
Object put(Object key, Object value)
associe la clé spécifiée à l'objet donné au sein de l'objet Hashtable.
void putAll(Map t)
copie toutes les paires clé/valeur de l'objet Map spécifié au sein de l'objet Hashtable.
protected void rehash()
augmente la capacité de l'objet Hashtable et le réorganise en interne, afin de réadapter judicieusement l'objet et d'accèder à ses entrées plus efficacement.
Object remove(Object key)
supprime de l'objet Hashtable, la paire clé/valeur correspondant à la clé passé en argument.
int size()
retourne le nombre de clés contenues dans l'objet Hashtable.
String toString()
retourne une chaîne de caractères représentant l'objet Hashtable.
Collection values()
retourne un objet Collection contenant les valeurs de la table de hachage courante.
Les méthodes héritées à partir de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.20 / La classe IdentityHashMap

La classe IdentityHashMap implémente l'interface Map avec une table de hachage en utilisant une égalité de référence à la place d'une égalité d'objet lors de la comparaison des clés et valeurs.

Etant donné cette caractéristique, la classe IdentityhashMap est rarement utilisée, seulement dans des cas rares ou les sémantiques d'égalité de référence sont exigées.

Les classes imbriquées
Les classes imbriquées à partir de la classe java.util.Map
Map.Entry

Les constructeurs
IdentityHashMap()
crée un objet IdentityHashMap vide avec une taille maximum par défaut (21).
IdentityHashMap(int expectedMaxSize)
crée un objet IdentityHashMap vide avec une taille maximum précisée.
IdentityHashMap(Map m)
crée un objet IdentityHashMap contenant les paires clé/valeur de l'objet Map spécifié.

Les méthodes
void clear()
supprime toutes les paires clé/valeur de l'objet IdentityHashMap.
Object clone()
retourne une copie de référence de l'objet IdentityHashMap.
boolean containsKey(Object key)
teste si l'objet IdentityHashMap contient la clé spécifiée.
boolean containsValue(Object value)
teste si l'objet IdentityHashMap contient la valeur spécifiée.
Set entrySet()
retourne un objet Set contenant les paires clé/valeur de l'objet IdentityHashMap.
boolean equals(Object o)
teste l'égalité entre l'objet IdentityHashMap et l'objet passé en argument.
Object get(Object key)
retourne la valeur pointée par la clé spécifiée au sein de l'objet IdentityHashMap, ou null si la clé n'existe pas.
int hashCode()
retourne la valeur du code de hachage de l'objet IdentityHashMap.
boolean isEmpty()
retourne true si l'objet IdentityHashMap ne contient aucune paire clé/valeur.
Set keySet()
retourne un objet Set contenant les clés de l'objet IdentityHashMap.
Object put(Object key, Object value)
associe la valeur spécifiée à la clé donnée au sein de l'objet IdentityHashMap.
void putAll(Map t)
copie toutes les paires clé/valeur de l'objet Map passé en argument, au sein de l'objet IdentityHashMap.
Object remove(Object key)
supprime de l'objet IdentityHashMap, la paire clé/valeur correspondant à la clé passée en argument.
int size()
retourne le nombre de paires clé/valeur contenu dans l'objet IdentityHashMap.
Collection values()
retourne une collection contenant les valeurs contenues dans l'objet IdentityHashMap.
Les méthodes héritées à partir de la classe java.util.AbstractMap
toString
Les méthodes héritées à partir de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.21 / La classe LinkedHashMap

La classe LinkedHashMap constitue à la fois une table de hachage Map et une liste chaînée avec un ordre d'itération prévisible.

Cette implémentation diffère de la collection HashMap parcequ'elle maintient une liste doublement chaînée fonctionnant au travers de toutes ses entrées.

L'objet LinkedHashMap définit l'ordre d'itération, qui est normalement l'ordre dans lequel les clés ont été insérées à l'intérieur de la collection.

Les constructeurs
LinkedHashMap()
crée un objet LinkedHashMap vide en mode insertion avec une capacité initiale (16) et un facteur de charge par défaut (0.75).
LinkedHashMap(int initialCapacity)
crée un objet LinkedHashMap vide en mode insertion avec une capacité initiale spécifiée et un facteur de charge par défaut (0.75).
LinkedHashMap(int initialCapacity, float loadFactor)
crée un objet LinkedHashMap vide en mode insertion avec une capacité initiale et un facteur de charge spécifiés.
LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
crée un objet LinkedHashMap vide avec une capacité initiale et un facteur de charge spécifiés, ainsi qu'un argument indiquant un mode d'insertion (false) ou d'accès (false).
LinkedHashMap(Map m)
crée un objet LinkedHashMap en mode insertion contenant les mêmes paires clé/valeurde l'objet Map spécifié.

Les méthodes
void clear()
supprime toutes les paires clé/valeur de l'objet LinkedHashMap.
boolean containsValue(Object value)
retourne true si l'objet LinkedHashMap contient une ou plusieurs clés référençant la valeur spécifiée.
Object get(Object key)
retourne la valeur pointée par la clé spécifiée.
protected boolean removeEldestEntry(Map.Entry eldest)
retourne true si l'objet LinkedHashMap devrait supprimer l'entrée la plus ancienne.
Les méthodes héritées de la classe java.util.HashMap
clone, containsKey, entrySet, isEmpty, keySet, put, putAll, remove, size, values
Les méthodes héritées de la classe java.util.AbstractMap
equals, hashCode, toString
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Map
equals, hashCode

42.22 / La classe LinkedHashSet

La classe LinkedHashSet constitue une table de hachage et une implémentation d'une liste chaînée de l'interface Set avec un ordre d'itération prévisible.

Cette implémentation diffère de la collection HashSet parce qu'elle maintient une liste doublement chaînée fonctionnant à travers toutes ses entrées. L'objet LinkedHashSet définit l'ordre d'itération qui est l'ordre dans lequel des éléments ont été insérés au sein de l'ensemble.

Les constructeurs
LinkedHashSet()
crée un objet LinkedHashSet vide avec une capacité initiale (16) et un facteur de charge (0.75) par défaut.
LinkedHashSet(Collection c)
crée un objet LinkedHashMap contenant les éléments de la collection passée en argument.
LinkedHashSet(int initialCapacity)
crée un objet LinkedHashSet avec une capacité initiale spécifiée et un facteur de charge par défaut (0.75).
LinkedHashSet(int initialCapacity, float loadFactor)
crée un objet LinkedHashSet avec une capacité initiale et un facteur de charge spécifiés.
Les méthodes héritées de la classe java.util.HashSet
add, clear, clone, contains, isEmpty, iterator, remove, size
Les méthodes héritées de la classe java.util.AbstractSet
equals, hashCode, removeAll
Les méthodes héritées de la classe java.util.AbstractCollection
addAll, containsAll, retainAll, toArray, toArray, toString
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Set
add, addAll, clear, contains, containsAll, equals, hashCode, isEmpty, iterator, remove, removeAll, retainAll, size, toArray, toArray

42.23 / La classe LinkedList

La classe LinkedList représente un liste chaînée implémentant l'interface List.

Cette collection implémente toutes les opérations optionnelles sur les listes et permet également d'inclure tous types d'élément y compris avec une valeur null.

En plus d'implémenter l'interface List, la classe LinkedList fournit des méthodes nommées uniformément pour l'obtention, la suppression et l'insertion d'élément au début et à la fin de la liste chaînée. Ces opérations permettent aux listes chaînées d'être utilisées en tant que pile, file d'attente, ou file d'attente double.

Les champs
Les champs hérités de la classe java.util.AbstractList
modCount

Les constructeurs
LinkedList()
crée une liste chaînée vide.
LinkedList(Collection c)
crée une liste chaînée contenant les éléments de la collection passée en argument.

Les méthodes
void add(int index, Object element)
insère l'élément spécifié à la position donnée au sein de l"objet LinkedList.
boolean add(Object o)
ajoute l'élément spécifié à la fin de l'objet LinkedList.
boolean addAll(Collection c)
ajoute tous les éléments de la collection spécifiée à la fin de la liste chaînée.
boolean addAll(int index, Collection c)
insère à partir de la position donnée, tous les les éléments de la collection spécifiée au sein de l'objet LinkedList.
void addFirst(Object o)
insère l'élément donné au début de la liste chaînée.
void addLast(Object o)
ajoute l'élément donné à la fin de la liste chaînée.
void clear()
supprime tous les éléments de l'objet LinkedList.
Object clone()
retourne une copie de référence de l'objet LinkedList.
boolean contains(Object o)
retourne true si la liste chaînée contient l'élément spécifié.
Object get(int index)
retourne l'élément trouvé à la position spécifiée.
Object getFirst()
retourne le premier élément de la liste chaînée.
Object getLast()
retourne le dernier élément de la liste chaînée.
int indexOf(Object o)
retourne l'index de la première occurrence de l'élément spécifié, ou -1 si ce dernier n'est pas trouvé.
int lastIndexOf(Object o)
retourne l'index de la dernière occurrence de l'élément spécifié, ou -1 si ce dernier n'est pas trouvé.
ListIterator listIterator(int index)
retourne un objet ListIterator contenant les éléments de la liste chaînée, à partir de l'index spécifié.
Object remove(int index)
supprime l'élément trouvé à la position spécifié au sein de la liste chaînée.
boolean remove(Object o)
supprime la première occurrence de l'élément spécifié.
Object removeFirst()
supprime et retourne le premier élément de la liste chaînée.
Object removeLast()
supprime et retourne le dernier élément de la liste chaînée.
Object set(int index, Object element)
remplace l'élément situé à la position spécifiée par l'élément passé en argument.
int size()
retourne le nombre d'éléments contenus dans la liste chaînée.
Object[] toArray()
retourne un tableau contenant tous les éléments de la liste chaînée dans un ordre exact.
Object[] toArray(Object[] a)
retourne un tableau contenant tous les éléments de la liste chaînée dans un ordre exact. Le type d'exécution du tableau retourné est celui du tableau passé en argument.
Les méthodes héritées de la classe java.util.AbstractSequentialList
iterator
Les méthodes héritées de la classe java.util.AbstractList
equals, hashCode, listIterator, removeRange, subList
Les méthodes héritées de la classe java.util.AbstractCollection
containsAll, isEmpty, removeAll, retainAll, toString
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.List
containsAll, equals, hashCode, isEmpty, iterator, listIterator, removeAll, retainAll, subList

42.24 / La classe ListResourceBundle

La classe ListResourceBundle représente une sous-classe abstraite de la classe ResourceBundle qui gère les ressources locales dans une utilisation convenable et facile de liste.

Les champs
Les champs hérités de la classe java.util.ResourceBundle
parent

Les constructeurs
ListResourceBundle()
crée un objet ListResourceBundle.

Les méthodes
protected abstract Object[][] getContents()
retourne le contenu (clé/valeur) de l'objet ListResourceBundle dans un tableau à deux dimensions.
Enumeration getKeys()
retourne une énumération de clés contenus par l'objet ListResourceBundle.
Object handleGetObject(String key)
retourne un objet correspondant à la clé donnée.
Les méthodes héritées de la classe java.util.ResourceBundle
getBundle, getBundle, getBundle, getLocale, getObject, getString, getStringArray, setParent
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.25 / La classe Locale

La classe Locale représente une région culturelle, politique ou géographique.

Une opération qui requiert un objet Locale pour exécuter sa tâche est appelé locale-sensitive et l'utilise pour adapter l'information pour l'utilisateur. Par exemple, l'affichage d'un nombre est une opération locale-sensitive puisqu'il devrait être formaté selon l'environnement géographique et culturel de l'utilisateur.

Les champs
static Locale CANADA
représente une constante utile pour une zone géographique.
static Locale CANADA_FRENCH
représente une constante utile pour une zone géographique.
static Locale CHINA
représente une constante utile pour une zone géographique.
static Locale CHINESE
représente une constante utile pour une langue.
static Locale ENGLISH
représente une constante utile pour une langue.
static Locale FRANCE
représente une constante utile pour une zone géographique.
static Locale FRENCH
représente une constante utile pour une langue.
static Locale GERMAN
représente une constante utile pour une langue.
static Locale GERMANY
représente une constante utile pour une zone géographique.
static Locale ITALIAN
représente une constante utile pour une langue.
static Locale ITALY
représente une constante utile pour une zone géographique.
static Locale JAPAN
représente une constante utile pour une zone géographique.
static Locale JAPANESE
représente une constante utile pour une langue.
static Locale KOREA
représente une constante utile pour une zone géographique.
static Locale KOREAN
représente une constante utile pour une langue.
static Locale PRC
représente une constante utile pour une zone géographique.
static Locale SIMPLIFIED_CHINESE
représente une constante utile pour une langue.
static Locale TAIWAN
représente une constante utile pour une zone géographique.
static Locale TRADITIONAL_CHINESE
représente une constante utile pour une langue.
static Locale UK
représente une constante utile pour une zone géographique.
static Locale US
représente une constante utile pour une zone géographique.

Les constructeurs
Locale(String language)
crée un objet Locale à partir d'un code de langue.
Locale(String language, String country)
crée un objet Locale à partir des codes de langue et de pays.
Locale(String language, String country, String variant)
crée un objet Locale à partir des codes de langue et de pays, ainsi qu'un dernier argument pour indiquer un constructeur ou un code de navigateur spécifique, tel que WIN pour Windows, MAC pour Macintosh ou POSIX pour POSIX.

Les méthodes
Object clone()
retourne une copie exacte de l'objet Locale.
boolean equals(Object obj)
teste l'égalité de l'objet Locale par rapport à un autre donné.
static Locale[] getAvailableLocales()
retourne une liste de toutes les zones géographiques installées.
String getCountry()
retourne le code pays/région de l'objet Locale. Le retour peut être vide ou être un code ISO 3166 2-letter.
static Locale getDefault()
retourne l'objet Locale courant et par défaut de la JVM (Java Virtual Machine).
String getDisplayCountry()
retourne le nom du pays contenu par l'objet Locale.
String getDisplayCountry(Locale inLocale)
retourne le nom du pays contenu pour l'objet Locale spécifié.
String getDisplayLanguage()
retourne le nom de la langue contenu par l'objet Locale.
String getDisplayLanguage(Locale inLocale)
retourne le nom de la langue pour l'objet Locale spécifié.
String getDisplayName()
retourne le nom de l'objet Locale.
String getDisplayName(Locale inLocale)
retourne le nom de l'objet Locale spécifié.
String getDisplayVariant()
retourne le nom du constructeur contenu par l'objet Locale.
String getDisplayVariant(Locale inLocale)
retourne le nom du constructeur de l'objet Locale spécifié.
String getISO3Country()
retourne une abréviation sur trois lettres du code régional.
String getISO3Language()
retourne une abréviation sur trois lettres du code de langue.
static String[] getISOCountries()
retourne un tableau contenant les codes régionaux de deux lettres, définis dans l'ISO 3166.
static String[] getISOLanguages()
retourne un tableau contenant les codes régionaux de deux lettres, définis dans l'ISO 639.
String getLanguage()
retourne le code de langue pour l'objet Locale. Le retour peut être vide ou un code ISO 639 en casse minuscule.
String getVariant()
retourne le code constructeur pour l'objet Locale.
int hashCode()
retourne la valeur du code de hachage de l'objet Locale.
static void setDefault(Locale newLocale)
fixe la valeur par défaut de l'objet Locale avec l'objet Locale spécifié.
String toString()
retourne une chaîne de caractères représentant l'objet Locale.
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.26 / La classe Observable

La classe Observable représente un objet observable ou "data" dans le paradigme vue-modèle. Il peut être sous-classé pour représenter un objet que l'application voudrait observer.

Un objet Observable peut avoir un ou plusieurs observateurs, qui peuvent être eux-mêmes n'importe quel objet implémentant l'interface Observer. Suite à ne modification d'une instance observable, une application appelant la méthode notifyObservers() entraîne la notification du changement à tous les observateurs par un appel de leur méthode update(). L'ordre dans lequel les notifications sont effectuées est non-spécifié.

Les constructeurs
Observable()
crée un objet Observable sans aucun objet Observer.

Les méthodes
void addObserver(Observer o)
ajoute un objet Observer au sein de l'ensemble des observateurs de l'objet Observable, en vérifiant qu'il n'existe pas déjà dans l'ensemble.
protected void clearChanged()
indique que l'objet Observable n'a pas été modifié, ou qu'il a déjà avisé la totalité de ses observateurs de sa plus récente modification, tel que la méthode hasChanged() retournerait maintenant false.
int countObservers()
retourne le nombre d'objet Observer contenus dans l'objet Observable.
void deleteObserver(Observer o)
supprime un objet Observer correspondant à l'objet passé en argument.
void deleteObservers()
supprime tous les objets Observer contenus dans l'objet Observable.
boolean hasChanged()
vérifie si l'objet a été modifié.
void notifyObservers()
Si l'objet Observable a été modifié, comme indiqué par la méthode hasChanged(), alors la méthode avise la totalité de ses observateurs et appelle la méthode clearChanged() pour indiquer que cet objet n'a plus changé depuis le dernier appel de méthode.
void notifyObservers(Object arg)
Si l'objet Observable a été modifié, comme indiqué par la méthode hasChanged(), alors la méthode avise la totalité de ses observateurs et appelle la méthode clearChanged() pour indiquer que cet objet n'a plus changé depuis le dernier appel de méthode.
protected void setChanged()
marque l'objet Observable comme ayant changé, la méthode hasChanged retournerait true maintenant.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.27 / La classe Properties

La classe Properties représente un ensemble persistant de propriétés, lesquelles peuvent être sauvegardées dans un flux ou chargées à partir d'un flux.

Toutes les clés et leur valeur correspondante de la liste des propriétés, sont des chaînes de caractères.

Les champs
protected Properties defaults
contient les valeurs par défaut pour toutes les clés non-trouvées dans la liste des propriétés.

Les constructeurs
Properties()
crée un objet Properties sans aucune valeur.
Properties(Properties defaults)
crée un objet Properties contenant les valeurs de la liste de propriétés passée en argument.

Les méthodes
String getProperty(String key)
recherche la propriété pointée par la clé spécifiée.
String getProperty(String key, String defaultValue)
recherche la propriété pointée par la clé spécifiée. Si la clé n'est pas trouvée, la valeur par défaut est retournée.
void list(PrintStream out)
écrit la liste des propriétés au sein de l'objet PrintStream.
void list(PrintWriter out)
écrit la liste des propriétés au sein de l'objet PrintWriter.
void load(InputStream inStream)
lit une liste de propriétés à partir de l'objet InputStream.
Enumeration propertyNames()
retourne une énumération de toutes les clés dans l'objet Properties.
void save(OutputStream out, String header)
Dépréciée, remplacée par store(OutputStream out, String header).
Object setProperty(String key, String value)
appelle la méthode put() de la classe Hashtable, pour ajouter une nouvelle paire clé/valeur.
void store(OutputStream out, String header)
écrit la liste des propriétés dans l'objet Properties vers le flux de sortie dans un format convenable pour le chargement au sein d'un objet Properties utilisant la méthode load().
Les méthodes héritées de la classe java.util.Hashtable
clear, clone, contains, containsKey, containsValue, elements, entrySet, equals, get, hashCode, isEmpty, keys, keySet, put, putAll, rehash, remove, size, toString, values
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.28 / La classe PropertyPermission

La classe PropertyPermission représente les permissions de propriété.

Les actions à accorder sont passées au constructeur dans une chaîne de caractères contenant une liste de zéro ou plusieurs mots-clés séparés par des virgules. Les mots-clés possibles sont "read" (permission en lecture) et "write" (permission en écriture).

Un grand soin devrait être pris avant d'accorder la permission d'accéder à certaines propriétés du système.

Les constructeurs
PropertyPermission(String name, String actions)
crée un objet PropertyPermission avec un nom spécifié et une action read ou write.

Les méthodes
boolean equals(Object obj)
teste l'égalité de l'objet PropertyPermission par rapport à un autre objet.
String getActions()
retourne une représentation canonique des actions.
int hashCode()
retourne la valeur du code de hachage pour l'objet PropertyPermission.
boolean implies(Permission p)
teste si l'objet PropertyPermission possède la permission spécifiée.
PermissionCollection newPermissionCollection()
retourne un objet PermissionCollection pour le stockage des objets PropertyPermission.
Les méthodes héritées de la classe java.security.Permission
checkGuard, getName, toString
Les méthodes héritées de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

42.29 / La classe PropertyResourceBundle

La classe PropertyResourceBundle représente une sous-classe concrète de la classe ResourceBundle qui gère les ressources locales pour une utilisation d'un ensemble de chaînes de caractères statiques à partir du fichier de propriétés.

À la différence d'autres types d'objets ResourceBundle, il ne faut pas faire de sous-classe de PropertyResourceBundle. A la place, il faut fournir des fichiers de propriétés contenant les données de ressources. La méthode ResourceBundle.getBundle() recherchera automatiquement les fichiers de propriétés appropriées classe et crée un PropertyResourceBundle qui se réfère à lui.

Les champs
Les champs hérités de la classe java.util.ResourceBundle
parent

Les constructeurs
PropertyResourceBundle(InputStream stream)
crée un objet PropertyResourceBundle se fondant sur l'objet InputStream.

Les méthodes
Enumeration getKeys()
retourne un objet Enumeration pour la clé donnée. Elle retourne null si la clé n'est pas trouvée.
Object handleGetObject(String key)
retourne l'objet pointée par la clé spécifiée.
Les méthodes héritées de la classe java.util.ResourceBundle
getBundle, getBundle, getBundle, getLocale, getObject, getString, getStringArray, setParent
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.30 / La classe Random

La classe Random est utilisée pour générer un flux de nombres pseudo-aléatoires.

Si deux objets Random sont crés avec la même racine et la même séquence d'appels de méthode, ils généreront et retourneront des séquences de nombres identiques.

Les constructeurs
Random()
crée un générateur de nombre aléatoire.
Random(long seed)
crée un objet Random utilisant la valeur entière seed

Les méthodes
protected int next(int bits)
génère un prochain nombre pseudo-aléatoire.
boolean nextBoolean()
retourne la prochaine valeur booléenne pseudo-aléatoire.
void nextBytes(byte[] bytes)
génère des octets et les place dans le tableau passé en argument.
double nextDouble()
retourne la prochaine valeur de type double pseudo-aléatoire.
float nextFloat()
retourne la prochaine valeur de type float pseudo-aléatoire.
double nextGaussian()
retourne la prochaine valeur Gaussienne de type double pseudo-aléatoire.
int nextInt()
retourne la prochaine valeur de type int pseudo-aléatoire.
int nextInt(int n)
retourne la prochaine valeur de type int pseudo-aléatoire, entre 0 et l'argument spécifié.
long nextLong()
retourne la prochaine valeur de type long pseudo-aléatoire.
void setSeed(long seed)
fixe l'argumet seed utilisé par le générateur de nombre pseudo-aléatoire.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.31 / La classe ResourceBundle

La classe ResourceBundle contient des objets spécifiques représentant des ressources locales.

Lorsqu'un programme nécessite une ressource locale spécifique, une chaîne de caractères par exemple, ce programme peut la charger à partir d'un objet ResourceBundle qui est approprié pour le locale de l'utilisateur courant. De cette façon, il est possible d'écrire un code, en grande partie indépendant du locale de l'utilisateur isolant les la plupart, si pas toute la, information locale-spécifique dans la ressource empaquette.

Les champs
protected ResourceBundle parent
représente le parent de l'objet ResourceBundle.

Les constructeurs
ResourceBundle()
crée l'objet ResourceBundle.

Les méthodes
static ResourceBundle getBundle(String baseName)
retourne un objet ResourceBundle utilisant le nom de base spécifié.
static ResourceBundle getBundle(String baseName, Locale locale)
retourne un objet ResourceBundle utilisant le nom de base et la zone géographique précisés.
static ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader)
retourne un objet ResourceBundle utilisant le nom de base, la zone géographique et le chargeur de classe spécifiés.
abstract Enumeration getKeys()
retourne un objet Enumeration contenant les clés de l'objet ResourceBundle.
Locale getLocale()
retourne l'objet Locale de l'objet ResourceBundle.
Object getObject(String key)
retourne un objet correspondant à la clé spécifiée, à partir de l'objet ResourceBundle ou l'un de ses parents.
String getString(String key)
retourne une chaîne de caractères correspondant à la clé spécifiée, à partir de l'objet ResourceBundle ou l'un de ses parents.
String[] getStringArray(String key)
retourne une chaîne de caractères correspondant à la clé spécifiée, à partir de l'objet ResourceBundle ou l'un de ses parents.
protected abstract Object handleGetObject(String key)
retourne un objet correspondant à la clé spécifiée à partir de l'objet ResourceBundle.
protected void setParent(ResourceBundle parent)
fixe le parent de l'objet ResourceBundle.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.32 / La classe SimpleTimeZone

La classe SimpleTimeZone est une sous-classe concrète d'un objet TimeZone qui représente un fuseau horaire à utiliser avec un objet GregorianCalendar.

La classe SimpleTimeZone possède un décalage à partir de l'heure du méridien de Greenwich, appelé offset brut, et les règles de début et de fin de la programmation de l'horaire d'été. Depuis, l'objet SimpleTimeZone tient seulement les valeurs uniques pour chacun, il ne peut manipuler les changements historiques dans l'offset brut et la programmation de l'horaire d'été, à l'exception que la méthode setStartYear() peut spécifier l'année lorsque la programmation de l'horaire d'été démarre de fait.

Les champs
static int STANDARD_TIME
représente un mode de démarrage ou d'arrêt spécifié comme temps standard.
static int UTC_TIME
représente un mode de démarrage ou d'arrêt spécifié comme temps UTC.
static int WALL_TIME
représente un mode de démarrage ou d'arrêt spécifié comme temps wall clock time.
Les champs hérités de la classe java.util.TimeZone
LONG, SHORT

Les constructeurs
SimpleTimeZone(int rawOffset, String ID)
crée un objet SimpleTimeZone avec l'offset du fuseau horaire de base GMT donné et l'identificateur du fuseau horaire sans programmation de l'horaire d'été.
SimpleTimeZone(int rawOffset, String ID, int startMonth,
int startDay, int startDayOfWeek, int startTime, int endMonth,
int endDay, int endDayOfWeek, int endTime)
crée un objet SimpleTimeZone avec l'offset du fuseau horaire de base GMT, l'identificateur du fuseau horaire et les règles de début et de fin des mois, jours, jours de la semaine et horaires journaliers.
SimpleTimeZone(int rawOffset, String ID, int startMonth,
int startDay, int startDayOfWeek, int startTime, int endMonth,
int endDay, int endDayOfWeek, int endTime, int dstSavings)
crée un objet SimpleTimeZone avec le décalage du fuseau horaire de base GMT, l'identificateur du fuseau horaire et les règles de début et de fin des mois, jours, jours de la semaine et horaires journaliers, ainsi qu'une valeur indiquant l'horaire d'été.
SimpleTimeZone(int rawOffset, String ID, int startMonth,
int startDay, int startDayOfWeek, int startTime, int startTimeMode, int endMonth,
int endDay, int endDayOfWeek, int endTime, int endTimeMode, int dstSavings)
crée un objet SimpleTimeZone avec le décalage du fuseau horaire de base GMT, l'identificateur du fuseau horaire et les règles de début et de fin des mois, jours, jours de la semaine et horaires journaliers, ainsi que deux valeurs indiquant respectivement un mode horaire et l'horaire d'été.

Les méthodes
Object clone()
retourne une copie de l'objet SimpleTimeZone.
boolean equals(Object obj)
teste l'égalité entre deux objets SimpleTimeZone.
int getDSTSavings()
retourne le temps en millisecondes d'avancement de l'horloge durant l'horaire d'été.
int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis)
retourne la différence en millisecondes entre l'horaire local et le temps UTC.
int getOffset(long date)
retourne l'offset du fuseau horaire UTC au temps donné.
int getRawOffset()
retourne le décalage GMT brut pour l'objet SimpleTimeZone.
int hashCode()
génère le code de hachage pour l'objet SimpleDateFormat.
boolean hasSameRules(TimeZone other)
retourne true si l'objet SimpleTimeZone possède les mêmes règles et offset que le fuseau horaire spécifié.
boolean inDaylightTime(Date date)
vérifie si la date spécifiée est comprise dans l'horaire d'été.
void setDSTSavings(int millisSavedDuringDST)
fixe le temps en millisecondes de l'avancement de l'horloge durant l'horaire d'été.
void setEndRule(int endMonth, int endDay, int endTime)
fixe les règles de fin de l'horaire d'été à la date précisée à l'intérieur d'un mois.
void setEndRule(int endMonth, int endDay, int endDayOfWeek, int endTime)
fixe les règles de fin de l'horaire d'été.
void setEndRule(int endMonth, int endDay, int endDayOfWeek, int endTime, boolean after)
fixe les règles de fin de l'horaire d'été.
void setRawOffset(int offsetMillis)
fixe l'offset brut du fuseau horaire GMT.
void setStartRule(int startMonth, int startDay, int startTime)
fixe les règles de début de l'horaire d'été vers une date précidsée à l'intérieur d'un mois.
void setStartRule(int startMonth, int startDay, int startDayOfWeek, int startTime)
fixe les règles de début de l'horaire d'été.
void setStartRule(int startMonth, int startDay, int startDayOfWeek, int startTime, boolean after)
fixe les règles de début de l'horaire d'été.
void setStartYear(int year)
fixe l'année de début de l'horaire d'été.
String toString()
retourne une chaîne de caractères représentant l'objet SimpleTimeZone.
boolean useDaylightTime()
vérifie si le fuseau horaire utilise un horaire d'été.
Les méthodes héritées de la classe java.util.TimeZone
getAvailableIDs, getAvailableIDs, getDefault, getDisplayName, getDisplayName, getDisplayName, getDisplayName, getID, getTimeZone, setDefault, setID
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait

42.33 / La classe Stack

La classe Stack représente une pile LIFO (Last-In-First-Out) d'objets.

Il étend la classe Vector avec cinq opérations qui permettent à un vecteur d'être traité comme une pile.

Les champs
Les champs hérités de la classe java.util.Vector
capacityIncrement, elementCount, elementData
Les champs hérités de la classe java.util.AbstractList
modCount

Les constructeurs
Stack()
crée un objet Stack vide.

Les méthodes
boolean empty()
teste si l'objet Stack est vide.
Object peek()
retourne l'objet au sommet de l'objet Stack sans le supprimer.
Object pop()
supprime et retourne l'objet du sommet de l'objet Stack.
Object push(Object item)
pousse un élément au sommet de l'objet Stack.
int search(Object o)
retourne la position d'un objet correspondant à l'argument spécifié à partir de l'objet Stack.
Les méthodes héritées de la classe java.util.Vector
add, add, addAll, addAll, addElement, capacity, clear, clone, contains, containsAll, copyInto, elementAt, elements, ensureCapacity, equals, firstElement, get, hashCode, indexOf, indexOf, insertElementAt, isEmpty, lastElement, lastIndexOf, lastIndexOf, remove, remove, removeAll, removeAllElements, removeElement, removeElementAt, removeRange, retainAll, set, setElementAt, setSize, size, subList, toArray, toArray, toString, trimToSize
Les méthodes héritées de la classe java.util.AbstractList
iterator, listIterator, listIterator
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.List
iterator, listIterator, listIterator

42.34 / La classe StringTokenizer

La classe StringTokenizer permet à une application de décomposer une chaîne de caractères en jetons.

La méthode de tokenization est beaucoup plus simple que celle employée par la classe StreamTokenizer. Les méthodes de la classe StringTokenizer ne distinguent pas parmi des identificateurs, des nombres, et des chaîne de caractères citées et ne reconnaissent pas non plus les commentaires.

Le jeu de délimiteurs peut être spécifié soit au moment de la création avec les constructeurs appropriés, soit lors de l'accès au prochaîn jeton par l'intermédiaire de la méthode nextToken(String delim).

Les constructeurs
StringTokenizer(String str)
crée un objet StringTokenizer s'appuyant sur la chaîne de caractères passé en argument.
StringTokenizer(String str, String delim)
crée un objet StringTokenizer s'appuyant sur la chaîne de caractères et le délimiteur passés en argument.
StringTokenizer(String str, String delim, boolean returnDelims)
crée un objet StringTokenizer s'appuyant sur la chaîne de caractères passé en argument.

Les méthodes
int countTokens()
calcul le nombre de fois que la méthode nextToken() peut être appelée avant la génération d'une exception.
boolean hasMoreElements()
retourne la même valeur que la méthode hasMoreTokens().
boolean hasMoreTokens()
vérifie s'il n'y a plus de jetons disponibles à partir de l'objet StringTokenizer.
Object nextElement()
retourne la même vameur que la méthode nextToken().
String nextToken()
retourne le prochain jeton à partir de l'objet StringTokenizer.
String nextToken(String delim)
retourne le prochain jeton par rapport au délimiteur spécifié.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.35 / La classe Timer

La classe Timer représente une facilité pour les threads afin de planifier des tâches pour une exécution future dans un thread en arrière plan.

La correspondance à chaque objet Timer est un thread de fond utilisé pour exécuter séquentiellement toutes les tâches d'un objet Timer.

Les constructeurs
Timer()
crée un objet Timer.
Timer(boolean isDaemon)
crée un objet Timer dont le thread associé peut être spécifié pour s'exécuter comme démon.

Les méthodes
void cancel()
termine le minuteur en déchargeant n'importe quelles tâches programmées.
void schedule(TimerTask task, Date time)
programme un tâche spécifiée pour une exécution à un moment spécifié.
void schedule(TimerTask task, Date firstTime, long period)
programme un tâche spécifiée pour une exécution répétitive à un moment spécifié.
void schedule(TimerTask task, long delay)
programme la tâche spécifiée pour une exécution après le délai donné.
void schedule(TimerTask task, long delay, long period)
programme la tâche spécifiée pour une exécution répétitive et démarrant après un délai spécifié.
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
programme la tâche spécifiée pour une exécution répétitive et démarrant à un moment donné.
void scheduleAtFixedRate(TimerTask task, long delay, long period)
programme la tâche spécifiée pour une exécution répétitive et démarrant après un délai spécifié.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.36 / La classe TimerTask

La classe TimerTask représente une tâche qui peut être programmée pour un unique moment précis ou pour une exécution répétitive par rapport à un objet Timer.

Les constructeurs
protected TimerTask()
crée une tâche temporisée.

Les méthodes
boolean cancel()
annule la tâche temporisée.
abstract void run()
exécute l'objet TimerTask.
long scheduledExecutionTime()
retourne le temps d'exécution programmé de l'exécution acutel la plus récente de l'objet TimerTask.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.37 / La classe TimeZone

La classe TimeZone représente un fuseau horaire et aussi un horaire d'été/hiver.

Typiquement, il est possible d'obtenir un objet TimeZone en utilisant la méthode getDefault() qui crée un objet TimeZone basé sur le fuseau horaire d'où le programme fonctionne. Par exemple, pour un programme fonctionnant au Japon, la méthode getDefault() crée un objet de TimeZone basé sur le temps standard japonais.

Les champs
static int LONG
représente un style de retour de la méthode getDisplayName() indiquant un nom long tel que "Pacific Standard Time."
static int SHORT
représente un style de retour de la méthode getDisplayName() indiquant un nom court tel que "PST."

Les constructeurs
TimeZone()
crée un nouvel objet SimpleTimeZone.

Les méthodes
Object clone()
retourne une copie de l'objet TimeZone.
static String[] getAvailableIDs()
retourne tous les identificateurs ID disponibles pour l'objet TimeZone.
static String[] getAvailableIDs(int rawOffset)
retourne tous les identificateurs ID disponibles selon l'offset brut donné, pour l'objet TimeZone.
static TimeZone getDefault()
retourne l'objet TimeZone par défaut.
String getDisplayName()
retourne le nom compréhensible de l'objet TimeZone.
String getDisplayName(boolean daylight, int style)
retourne le nom compréhensible de l'objet TimeZone selon un style long ou court. Si l'argument daylight est égal à true, la méthode retourne le nom de l'horaire.
String getDisplayName(boolean daylight, int style, Locale locale)
retourne le nom compréhensible de l'objet TimeZone par rapport à l'objet Locale spécifié.
String getDisplayName(Locale locale)
retourne le nom compréhensible de l'objet TimeZone par rapport à l'objet Locale spécifié selon un style long ou court. Si l'argument daylight est égal à true, la méthode retourne le nom de l'horaire.
int getDSTSavings()
retourne le temps à ajouter au temps standard local afin d'obtenir le wall clock time local.
String getID()
retourne l'ID de l'objet TimeZone.
abstract int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds)
retourne l'offset du fuseau horaire pour la date courante modifiée dans le cas d'un horaire d'été.
int getOffset(long date)
retourne l'offset du fuseau horaire par rapport au temps UTC à la date spécifiée.
abstract int getRawOffset()
retourne le temps en millisecondes à ajouter au temps UTC afin d'obtenir le temps standard pour l'objet TimeZone.
static TimeZone getTimeZone(String ID)
retourne un objet TimeZone pour l'ID spécifié.
boolean hasSameRules(TimeZone other)
retourne true si la zone possède les mêmes règles et offset que l'objet TimeZone spécifié.
abstract boolean inDaylightTime(Date date)
vérifie si la date donnée est comprise dans l'horaire d'été de l'objet TimeZone.
static void setDefault(TimeZone zone)
fixe l'objet TimeZone qui est retourné par la méthode getDefault().
void setID(String ID)
fixe l'ID de l'objet TimeZone.
abstract void setRawOffset(int offsetMillis)
fixe l'offset brut du fuseau horaire au temps GMT.
abstract boolean useDaylightTime()
vérifie si l'objet TimeZone utilise l'horaire d'été.
Les méthodes héritées de la classe java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

42.38 / La classe TreeMap

La classe TreeMap représente une implémentation de l'interface SortedMap.

La classe TreeMap garantit que les paires clé/valeur seront triées dans un ordre ascendant selon l'ordre naturel des clés ou par l'intermédiaire d'un comparateur fourni au moment de sa création en faisant appel au constructeur approprié.

Cette implémentation n'est pas synchronisée.

Les constructeurs
TreeMap()
crée un objet TreeMap vide, triable par rapport à l'ordre naturel des clés.
TreeMap(Comparator c)
crée un objet TreeMap vide, triable par rapport au comparateur donné.
TreeMap(Map m)
crée un objet TreeMap contenant les paires clé/valeur de l'objet Map donné et trié selon l'ordre naturel des clés.
TreeMap(SortedMap m)
crée un objet TreeMap contenant les paires clé/valeur que l'objet SortedMap donné et trié selon le même ordre.

Les méthodes
void clear()
supprime toutes les paires clé/valeur de l'objet TreeMap.
Object clone()
retourne une copie de référence de l'objet TreeMap.
Comparator comparator()
retourne l'objet Comparator utilisé pour ordonner l'objet TreeMap, ou null si cet l'objet TreeMap utilise son ordre naturel des clés.
boolean containsKey(Object key)
retourne true si l'objet TreeMap contient une paire clé/valeur pour la clé spécifiée.
boolean containsValue(Object value)
retourne true si l'objet TreeMap contient une ou plusieurs clés pointant la valeur spécifiée.
Set entrySet()
retourne un objet Set contenant les paires clé/valeur présentes dans l'objet TreeMap.
Object firstKey()
retourne généralement la première clé dans l'objet TreeMap trié.
Object get(Object key)
retourne la valeur pointée par la clé fournie.
SortedMap headMap(Object toKey)
retourne un objet SortedMap contenant les paires clé/valeur de l'objet TreeMap dont les clés sont strictement inférieure à la clé spécifiée.
Set keySet()
retourne un objet Set des clés contenues dans l'objet TreeMap.
Object lastKey()
retourne généralement la dernière clé de l'objet TreeMap trié.
Object put(Object key, Object value)
associe la valeur spécifiée à la clé donnée au sein de l'objet TreeMap.
void putAll(Map map)
copie toutes les paires clé/valeur contenues dans l'objet Map spécifié au sein de l'objet TreeMap.
Object remove(Object key)
supprime la paire clé/valeur correspondant à la clé passée en argument.
int size()
retourne le nombre de paires clé/valeur contenues dans l'objet TreeMap.
SortedMap subMap(Object fromKey, Object toKey)
retourne un objet SortedMap contenant les paires clé/valeur comprises entre les valeurs fromKey inclus et toKey exclus.
SortedMap tailMap(Object fromKey)
retourne un objet SortedMap contenant les paires clé/valeur du TreeMap dont les clés sont plus grandes ou égales à la clé spécifiée.
Collection values()
retourne une collection contenant les valeurs de l'objet TreeMap.
Les méthodes héritées de la classe java.util.AbstractMap
equals, hashCode, isEmpty, toString
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Map
equals, hashCode, isEmpty

42.39 / La classe TreeSet

La classe TreeSet implémente l'interface Set renforcée par une instance de TreeMap.

La classe TreeSet garantit que l'ensemble trié le serait dans un ordre ascendant, en selon l'ordre naturel des éléments ou par l'intermédiaire d'un comparateur fournit au moment de sa création avec le constructeur approprié.

Cette implémentation n'est pas synchronisée.

Les constructeurs
TreeSet()
crée un objet TreeSet vide, triable selon l'ordre naturel des éléments.
TreeSet(Collection c)
crée un objet TreeSet contenant les éléments de la collection spécifiée, trié selon l'ordre naturel des éléments.
TreeSet(Comparator c)
crée un objet TreeSet vide, triable selon le comparateur spécifié.
TreeSet(SortedSet s)
crée un objet TreeSet contenant les éléments de l'objet SortedSet spécifié, trié dans le même ordre.

Les méthodes
boolean add(Object o)
ajoute l'élément spécifié au sein de l'objet TreeSet s'il n'est pas déjà présent.
boolean addAll(Collection c)
ajoute tous les éléments de la collection spécifiée au sein de l'objet TreeSet.
void clear()
supprime tous les éléments de l'objet TreeSet.
Object clone()
retourne une copie de référence de l'objet TreeSet.
Comparator comparator()
retourne le comparateur utilisé pour ordonner le TreeSet, ou null si l'objet TreeSet utilise l'ordre naturel de ses éléments.
boolean contains(Object o)
retourne true si l'objet TreeSet contient l'élément spécifié.
Object first()
retourne généralement le premier élément du TreeSet trié.
SortedSet headSet(Object toElement)
retourne l'objet SortedSet contenant les éléments de l'objet TreeSet dont les éléments sont strictement inférieurs à l'objet spécifié.
boolean isEmpty()
retourne true si l'objet Set ne contient aucun élément.
Iterator iterator()
retourne un itérateur sur les éléments de l'objet TreeSet.
Object last()
retourne généralement le dernier élément du TreeSet trié.
boolean remove(Object o)
supprime l'élément spécifié de l'objet TreeSet s'il est présent.
int size()
retourne le nombre d'éléments au sein de l'objet TreeSet.
SortedSet subSet(Object fromElement, Object toElement)
retourne un objet SortedSet contenant les éléments de l'objet TreeSet situés entre les valeurs fromElement inclus et toElement exclus.
SortedSet tailSet(Object fromElement)
retourne un objet SortedSet contenant les éléments de l'objet TreeSet dont les éléments sont plus grands ou égaux à l'objet spécifié.
Les méthodes héritées de la classe java.util.AbstractSet
equals, hashCode, removeAll
Les méthodes héritées de la classe java.util.AbstractCollection
containsAll, retainAll, toArray, toArray, toString
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Set
containsAll, equals, hashCode, removeAll, retainAll, toArray, toArray

42.40 / La classe Vector

La classe Vector implémente un tableau d'objets susceptibles de s'expandre.

A l'image d'un tableau, un vecteur contient des éléments qui peuvent être accédés par l'intermédiaire d'un index. Toutefois, la taille du vecteur peut augmenter ou diminuer si nécessaire, afin d'ajuster sa taille lors d'ajouts ou de suppressions de composants.

Chaque vecteur essaie d'optimiser la gestion du stockage en conservant une capacité et un incrément de capacité. La capacité est toujours au moins aussi grande que la taille du vecteur. Elle est habituellement plus grande en raison des susceptibles ajouts de composants au vecteur. La capacité de stockage du vecteur augmente par pallier successif spécifié par la valeur de l'incrément de capactité. Une application doit pouvoir augmenter la capacité d'un vecteur avant d'insérer un grand nombre de composants susceptibles de dépasser la capacité initiale de ce vecteur. Cela a pour avantage de réduire le nombre de réallocation incrémentielle du vecteur en fonction des ajouts.

Les champs
protected int capacityIncrement
représente la quantité par laquelle la capacité du vecteur est automatiquement incrémentée lorsque sa taille devient plus grande que sa capacité.
protected int elementCount
représente le nombre de composants valides dans l'objet Vector.
protected Object[] elementData
représente le tampon à l'intérieur duquel les composants du vecteur sont stockés.
Les champs hérités de la classe java.util.AbstractList
modCount

Les constructeurs
Vector()
crée un objet Vector vide avec une capacité initiale (10) et un incrément de zero par défaut.
Vector(Collection c)
crée un objet Vector contenant les éléments de la collection spécifiée, dans l'ordre infléchi par l'itérateur de la collection.
Vector(int initialCapacity)
crée un vecteur vide avec une capacité initiale spécifiée et un incrément de zero par défaut.
Vector(int initialCapacity, int capacityIncrement)
crée un objet Vector vide avec une capacité initiale et un incrément par défaut.

Les méthodes
void add(int index, Object element)
insère l'élément spécifié à la position donnée au sein de l'objet Vector.
boolean add(Object o)
ajoute l'élément spécifié à la fin de l'objet Vector.
boolean addAll(Collection c)
ajoute tous les éléments de la collection spécifiée à la fin de l'objet Vector dans l'ordre infléchi par l'itérateur de la collection.
boolean addAll(int index, Collection c)
insère tous les éléments de la collection spécifiée à l'intérieur de l'objet Vector à la position spécifiée.
void addElement(Object obj)
ajoute le composant spécifiée à la fin du vecteur en augmentant sa taille de un.
int capacity()
retourne la capacité courante du vecteur.
void clear()
supprime tous les éléments de l'objet Vector.
Object clone()
retourne une copie de l'objet Vector.
boolean contains(Object elem)
vérifie si l'objet Vector contient l'élément spécifié.
boolean containsAll(Collection c)
retourne true si l'objet Vector contient tous les éléments de la collection spécifiée.
void copyInto(Object[] anArray)
copie les composants de l'objet vecteur à l'intérieur du tableau spécifié.
Object elementAt(int index)
retourne l'élément trouvé à l'index spécifié.
Enumeration elements()
retourne une énumération des éléments de l'objet Vector.
void ensureCapacity(int minCapacity)
augmente la capacité de l'objet Vector si cela est nécessaire, afin de s'assurer qu'il puisse contenir au moins le nombre d'éléments spécifiés par l'argument de capacité minimum.
boolean equals(Object o)
teste l'égalité entre l'objet Vector et un autre objet.
Object firstElement()
retourne le premier élément du vecteur.
Object get(int index)
retourne l'élément trouvé à la position spécifiée.
int hashCode()
retourne la valeur du code de hachage pour l'objet Vector.
int indexOf(Object elem)
recherche la première occurrence de l'élément spécifié en testant leur égalité à l'aide de la méthode equals().
int indexOf(Object elem, int index)
recherche la première occurrence de l'élément spécifié en démarrant la recherche à l'index donné et en testant leur égalité à l'aide de la méthode equals().
void insertElementAt(Object obj, int index)
insère l'objet spécifié à un index donné au sein du vecteur.
boolean isEmpty()
vérifie si l'objet Vector ne possède pas de composants.
Object lastElement()
retourne le dernier élément de l'objet Vector.
int lastIndexOf(Object elem)
retourne l'index de la denrière occurrence de l'élément spécifié.
int lastIndexOf(Object elem, int index)
recherche en arrière et en démarrant de l'index spécifié, l'élément fourni et le retourne son index s'il est trouvé.
Object remove(int index)
supprime l'élément à la position spécifiée dans l'objet Vector.
boolean remove(Object o)
supprime la première occurrence de l'élément spécifié, s'il est trouvé.
boolean removeAll(Collection c)
supprime de l'objet Vector, tous les éléments contenus dans la collection passée en arugment.
void removeAllElements()
supprime tous les éléments de l'objet Vector et fixe sa taille à zero.
boolean removeElement(Object obj)
supprime la première occurrence de l'élément spécifié du vecteur.
void removeElementAt(int index)
supprime l'élément spécifié positionné à l'index donné.
protected void removeRange(int fromIndex, int toIndex)
supprime du vecteur tous les éléments compris entre les valeurs fromIndex inclus et toIndex exclus.
boolean retainAll(Collection c)
maintient seulement les éléments de l'objet Vector qui ne sont pas contenus dans la collection spécifiée.
Object set(int index, Object element)
remplace l'élément à la position spécifiée par l'objet passé en argument.
void setElementAt(Object obj, int index)
fixe l'élément donné à la position spécifiée au sein de l'objet Vector.
void setSize(int newSize)
fixe la taille du vecteur.
int size()
retourne le nombre d'éléments contenus dans l'objet Vector.
List subList(int fromIndex, int toIndex)
retourne un objet List contenant les éléments de l'objet Vector compris entre les valeurs fromIndex inclus et toIndex exclus.
Object[] toArray()
retourne un tableau contenant tous les éléments du vecteur dans un ordre exact.
Object[] toArray(Object[] a)
retourne un tableau contenant tous les éléments de l'objet Vector dans un ordre correct. Le type d'exécution du tableau retourné est celui du tableau spécifié.
String toString()
retourne une chaîne de caractères représentant l'objet Vector.
void trimToSize()
réajuste la capacité de l'objet Vector par rapport à sa taille courante.
Les méthodes héritées de la classe java.util.AbstractList
iterator, listIterator, listIterator
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.List
iterator, listIterator, listIterator

42.41 / La classe WeakHashMap

La classe WeakHashMap représente une implémentation d'un objet Map basé sur une table de hachage avec des clès faibles.

Lorsqu'une clé est supprimée de l'objet WeakHashMap, l'entrée correpondante est effectivement supprimée de la collection, ainsi cette classe se comporte légèrement différemment que d'autres implémentations de l'interface Map.

Les constructeurs
WeakHashMap()
crée un objet WeakHashMap vide avec une capacité initiale (16) et un facteur de charge (0.75) par défaut.
WeakHashMap(int initialCapacity)
crée un objet WeakHashMap vide avec une capacité initiale spécifiée et un facteur de charge par défaut (0.75).
WeakHashMap(int initialCapacity, float loadFactor)
crée un objet WeakHashMap vide avec une capacité intiale et un facteur de charge spécifiés.
WeakHashMap(Map t)
crée un objet WeakHashMap contenant les mêmes paires clé/valeur comprises dans l'objet Map spécifié.

Les méthodes
void clear()
supprime toutes les paires clé/valeur de l'objet WeakHashMap.
boolean containsKey(Object key)
retourne true si l'objet WeakHashMap contient une paire clé/valeur correspondant à la clé spécifiée.
boolean containsValue(Object value)
retourne true si l'objet WeakHashMap contient une ou plusieur clés pointant la valeur spécifiée.
Set entrySet()
retourne une collection contenant les paires clé/valeur de l'objet WeakHashMap.
Object get(Object key)
retourne la valeur correspondant à la clé spécifiée au sein de l'objet WeakHashMap.
boolean isEmpty()
retourne true si l'objet WeakHashMap ne contient aucune paire clé/valeur.
Set keySet()
retourne un objet Set contenant les clés de l'objet WeakHashMap.
Object put(Object key, Object value)
associe la valeur spécifiée à la clé donnée au sein de l'objet WeakHashMap.
void putAll(Map m)
copie toutes les paires clé/valeur de l'objet Map spécifié, au sein de l'objet WeakHashMap.
Object remove(Object key)
supprime la paire clé/valeur correspondant à la clé de l'objet WeakHashMap, si elle est présente.
int size()
retourne le nombre de paires clé/valeur contenues dans l'objet WeakHashMap.
Collection values()
retourne une collection contenant les valeurs de l'objet WeakHashMap.
Les méthodes héritées de la classe java.util.AbstractMap
clone, equals, hashCode, toString
Les méthodes héritées de la classe java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Les méthodes héritées de l'interface java.util.Map
equals, hashCode

43 / Le paquetage java.lang.reflect

Le paquetage java.lang.reflect fournit des classes et interfaces permettant d'obtenir des informations introspectives sur les classes et objets ciblés.

Les interfaces
InvocationHandler est implémentée par le gestionnaire d'invocation d'une instance de proxy.
Member reflête les informations identificatrices sur les champs, méthodes et constructeurs.

Les classes
AccessibleObject est la classe de base pour les objets Field, Method et Constructor.
Array fournit des méthodes statiques pour créer et accéder dynamiquement au tableaux Java.
Constructor fournit des informations sur un constructeur d'une classe et comprend des moyens d'accès dynamique vers ce dernier.
Field fournit des informations sur un champ d'une classe ou interface, et comprend des moyens d'accès à ce dernier.
Method fournit des informations sur une méthode d'une classe ou interface, et comprend des moyens d'accès à ce dernier.
Modifier fournit des méthodes et constantes statiques pour décoder les modificateurs d'accès des membres et d'une classe.
Proxy fournit des méthodes statiques pour la création dynamique d'instances et classes de proxy, et elle est aussi la superclasse de toutes les classes proxy dynamiques créées par ces méthodes.
ReflectPermission représente la classes Permission pour les opérations d'introspection.

Les exceptions
InvocationTargetException est une exception contrôlée qui enveloppe une exception lancée par un constructeur ou une méthode invoquée.
UndeclaredThrowableException est lancée par une invocation d'une méthode sur une instance de proxy si sa méthode invoke() du gestionnaire d'invocation lance une exception contrôlée (un objet Throwable qui n'est pas aassignable un objet RuntimeException ou Error) qui ne sont affectables à aucun des types d'exception déclarés dans la clause throws de la méthode appelée sur l'instance de proxy et envoyée au gestionnaire d'invocation.

43.1 / La classe AccessibleObject

La classe AccessibleObject constitue la classe de base pour les objets Field, Method et Constructor.

Elle définit un drapeau d'accessiblité qui permet de contourner le contrôle d'accès par défaut de telle façon que si le drapeau possède la valeur true alors le contrôle d'accès est contourné.

les contrôles d'accès pour les membres publiques, privés, protégé ou par défaut sont exécutés lorsque les champs, méthodes et constructeurs pour respectivement fixer ou obtenir des champs, invoquer des méthodes ou créer et initialiser de nouvelles instances de classes.

Le paramétrage du drapeau d'accessibilité pour un objet réfêchi permet de créer des applications sophistiquées fournissant des privilèges suffisants, tel que la sérialisation d'objet Java ou d'autres mécanisme de persistance, afin de manipuler les objets qui normalement devraient être interdits.

Les constructeurs
protected AccessibleObject()
est utilisé seulement par la Machine Vituelle Java.

Les constructeurs
boolean isAccessible()
infdique si l'objet est accessible.
static void setAccessible(AccessibleObject[] array, boolean flag)
fixe l'accessibilité pour un tableau d'objets avec un contrôle de sécurité.
void setAccessible(boolean flag)
fixe l'accessibilité pour l'objet courant.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

43.2 / La classe Array

La classe Array fournit des méthodes statiques pour créer et accéder dynamiquement aux tableaux Java.

Elle permet la production de conversions dans le sens de l'élargissement durant une opération d'obtention ou d'affectation, mais lance une exception IllegalArgumentException dans le cas d'une tentative de conversion dans le sens du rétrécissement.

Les méthodes
static Object get(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié.
static boolean getBoolean(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'un booléen.
static byte getByte(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'une valeur de type byte.
static char getChar(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'une valeur de type char.
static double getDouble(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'une valeur de type double.
static float getFloat(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'une valeur de type float.
static int getInt(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'une valeur de type int.
static int getLength(Object array)
retourne la longueur du tableau spécifié.
static long getLong(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'une valeur de type long.
static short getShort(Object array, int index)
retourne la valeur de l'élément indexé dans le tableau spécifié sous la forme d'une valeur de type short.
static Object newInstance(Class componentType, int length)
crée un nouveau tableau avec le type d'élément et la longueur passés en argument.
static Object newInstance(Class componentType, int[] dimensions)
crée un nouveau tableau avec le type d'élément et les dimensions passés en argument.
static void set(Object array, int index, Object value)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur donnée.
static void setBoolean(Object array, int index, boolean z)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type boolean.
static void setByte(Object array, int index, byte b)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type byte.
static void setChar(Object array, int index, char c)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type char.
static void setDouble(Object array, int index, double d)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type double.
static void setFloat(Object array, int index, float f)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type float.
static void setInt(Object array, int index, int i)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type int.
static void setLong(Object array, int index, long l)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type long.
static void setShort(Object array, int index, short s)
fixe la valeur de l'élément indexé du tableau spécifié à une valeur de type short.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

43.3 / La classe Constructor

La classe Constructor fournit des informations sur un constructeur d'une classe et comprend des moyens d'accès dynamique vers ce dernier.

Elle permet les tentatives de conversions dans le sens de l'élargissement lorsque la correspondance est adéquate entre les paramètres actuels de newInstance() et les paramètres formels du constructeur sous-jacent, mais lance une exception IllegalArgumentException dans le cas d'une tentaive de conversion dans le sens du rétrécissement.

Les champs
Les champs hérités à partir de l'interface java.lang.reflect.Member
DECLARED, PUBLIC

Les méthodes
boolean equals(Object obj)
teste l'égalité entre le constructeur et un objet spécifié.
Class getDeclaringClass()
retourne l'objet de type Class représentant la classe qui déclare le constructeur représenté par l'objet Constructor courant.
Class[] getExceptionTypes()
retourne un tableau d'objets Class qui représente les types d'exceptions déclarés par l'intermédiaire de l'instruction throws par le constructeur sous-jacent représenté par l'objet Constructor.
int getModifiers()
retourne sous la forme d'un nombre entier, les modificateurs du constructeur représenté par l'objet Constructor.
String getName()
retourne le nom du constructeur représenté par l'objet Constructor sous la forme d'une chaîne de caractères.
Class[] getParameterTypes()
retourne un tableau d'objets Class qui représente les types des paramètres formels dans l'ordre de leur déclaration, du constructeur représenté par l'objet Constructor.
int hashCode()
retpourne le code de hachage de l'objet Constructor.
Object newInstance(Object[] initargs)
utilise l'objet Constructor afin de créer et initialiser une nouvelle instance de sa classe avec des arguments d'initialisations spécifiés dans un tableau d'objets.
String toString()
retourne une chaîne de caractères représentant l'objet Constructor.
Les méthodes héritées à partir de la classe java.lang.reflect.AccessibleObject
isAccessible, setAccessible, setAccessible
Les méthodes héritées à partir de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

43.4 / La classe Field

La classe Field fournit des informations sur un champ d'une classe ou interface, et comprend des moyens d'accès à ce dernier.

Elle autorise les tentatives de conversions dans le sens de l'élargissement lors d'opération d'otention ou d'affectation, mais lance une exception IllegalArgumentException si une conversion dans le sens du rétrécissement est tentée.

Les champs
Les champs hérités à partir de l'interface java.lang.reflect.Member
DECLARED, PUBLIC

Les méthodes
boolean equals(Object obj)
teste l'égalité entre l'objet Field et un autre objet spécifié.
Object get(Object obj)
retourne la valeur du champ représenté par l'objet Field à partir de l'objet spécifié.
boolean getBoolean(Object obj)
retourne la valeur d'un champ booléen d'instance ou statique à partir de l'objet spécifié.
byte getByte(Object obj)
retourne la valeur d'un champ de type byte d'instance ou statique.
char getChar(Object obj)
retourne la valeur d'un champ d'instance ou statique de type char ou d'un autre type primitif convertible vers le type précité en se fondant sur l'élargissement.
Class getDeclaringClass()
retourne un objet Class représentant la classe ou l'interface qui déclare le champ représenté par l'objet Field.
double getDouble(Object obj)
retourne la valeur d'un champ d'instance ou statique de type double ou d'un autre type primitif convertible vers le type précité en se fondant sur l'élargissement.
float getFloat(Object obj)
retourne la valeur d'un champ d'instance ou statique de type float ou d'un autre type primitif convertible vers le type précité en se fondant sur l'élargissement.
int getInt(Object obj)
retourne la valeur d'un champ d'instance ou statique de type int ou d'un autre type primitif convertible vers le type précité en se fondant sur l'élargissement.int via a widening conversion.
long getLong(Object obj)
retourne la valeur d'un champ d'instance ou statique de type long ou d'un autre type primitif convertible vers le type précité en se fondant sur l'élargissement.long via a widening conversion.
int getModifiers()
retourne sous la forme d'une valeur de type int, les modificateurs de l'objet Field.
String getName()
retourne le nom de l'objet Field.
short getShort(Object obj)
retourne la valeur d'un champ d'instance ou statique de type short ou d'un autre type primitif convertible vers le type précité en se fondant sur l'élargissement.
Class getType()
retourne un objet Class qui identifie le type déclaré du champ représenté par l'objet Field.
int hashCode()
retourne le code de hachage de l'objet Field.
void set(Object obj, Object value)
fixe le champ représenté par l'objet Field à partir de l'objet spécifié et avec la valeur donnée.
void setBoolean(Object obj, boolean z)
fixe la valeur du champ sous la forme d'une valeur de type boolean sur l'objet spécifié.
void setByte(Object obj, byte b)
fixe la valeur du champ sous la forme d'une valeur de type byte sur l'objet spécifié.
void setChar(Object obj, char c)
fixe la valeur du champ sous la forme d'une valeur de type char sur l'objet spécifié.
void setDouble(Object obj, double d)
fixe la valeur du champ sous la forme d'une valeur de type double sur l'objet spécifié.
void setFloat(Object obj, float f)
fixe la valeur du champ sous la forme d'une valeur de type float sur l'objet spécifié.
void setInt(Object obj, int i)
fixe la valeur du champ sous la forme d'une valeur de type int sur l'objet spécifié.
void setLong(Object obj, long l)
fixe la valeur du champ sous la forme d'une valeur de type long sur l'objet spécifié.
void setShort(Object obj, short s)
fixe la valeur du champ sous la forme d'une valeur de type short sur l'objet spécifié.
String toString()
retourne une chaîne de caractères représentant l'objet Field.
Les méthodes héritées à partir de la classe java.lang.reflect.AccessibleObject
isAccessible, setAccessible, setAccessible
Les méthodes héritées à partir de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

43.5 / La classe Method

La classe Method fournit des informations sur une méthode d'une classe ou interface, et comprend des moyens d'accès à ce dernier.

Elle permet les tentatives de conversions dans le sens de l'élargissement lorsque la correspondance entre les paramètres actuels de de la méthode invoke() et les paramètres formels de la méthode sous-jacente, mais lance une exception IllegalArgumentException dans le cas ou une conversion dans le ses du rétrécissement est tentée.

Les champs
Le champs hérités à partir de l'interface java.lang.reflect.Member
DECLARED, PUBLIC

Les méthodes
boolean equals(Object obj)
teste l'égalité entre l'objet Method et l'objet spécifié.
Class getDeclaringClass()
retourne un objet Class représentant la classe ou l'interface qui déclare la méthode représentée par l'objet Method.
Class[] getExceptionTypes()
retourne un tableau d'objets Class qui représentent les types d'exceptions susceptibles d'être lancées par la méthode sous-jacente représentée par l'objet Method.
int getModifiers()
retourne sous la forme d'une valeur entière, les modificateurs de la méthode représentée par l'objet Method.
String getName()
retourne le nom de la méthode représentée par l'objet Method.
Class[] getParameterTypes()
retourne un tableau d'objets Class qui représentent les types de paramètres formels dans l'ordre de leur déclaration au sein de la méthode représentée par l'objet Method.
Class getReturnType()
retourne un objet Class qui représente le type de retour de la méthode représentée par l'objet Method.
int hashCode()
retourne le code de hachage de l'objet Method.
Object invoke(Object obj, Object[] args)
invoque la méthode sous-jacente représentée par l'objet Method sur l'objet spécifié avec les paramètres donnés.
String toString()
retourne une chaîne de caractères représentant l'objet Method.
Les méthodes héritées à partir de la classe java.lang.reflect.AccessibleObject
isAccessible, setAccessible, setAccessible
Les méthodes héritées à partir de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

43.6 / La classe Modifier

La classe Modifier fournit des méthodes et constantes statiques pour décoder les modificateurs d'accès des membres et d'une classe.

L'ensemble des modificateurs sont représentés sous la forme de valeurs entières avec des positions de bit distinct représentant les différents modificateurs par rapport au genre du membres.

Les classes
DrapeauValeurDéfinition
ACC_PUBLIC0x0001La classe est publique et donc accessible à l'extérieur de son paquetage.
ACC_FINAL0x0010La classe est finale et donc ne peut être étendue.
ACC_SUPER0x0020La classe est considérée comme une superclasse.
ACC_INTERFACE0x0200La classe est en fait une interface.
ACC_ABSTRACT0x0400La classe est abstraite et donc ne peut être instanciée.
Les champs
DrapeauValeurDéfinition
ACC_PUBLIC0x0001Le champ est public et donc peut être accédé à l'extérieur de son paquetage.
ACC_PRIVATE0x0002Le champ est privé et donc ne peut être utilisé qu'au sein de sa classe.
ACC_PROTECTED0x0004Le champ est protégé, et donc peut être accédé à l'intérieur des sous-classes.
ACC_STATIC0x0008Le champ est statique et est donc accessible au sein de la classe et non d'un objet.
ACC_FINAL0x0010Le champ est final et donc ne peut être réaffecté.
ACC_VOLATILE0x0040Le champ est volatile et donc ne peut être caché.
ACC_TRANSIENT0x0080Le champ est transient et ne peut donc être lu ou écrit par un gestionnaire d'objet persistant.
Les méthodes
DrapeauValeurDéfinition
ACC_PUBLIC0x0001La méthode est publique et peut donc être accédée à l'extérieur de son paquetage.
ACC_PRIVATE0x0002Le méthode est privée et n'est donc accessible qu'au sein de sa classe.
ACC_PROTECTED0x0004La méthode est protégée et peut donc être accédée par des sous-classes.
ACC_STATIC0x0008La méthode est statique et ne peut être utilisée que par la classe et non par un objet.
ACC_FINAL0x0010La méthode est finale et ne peut donc être surchargée.
ACC_SYNCHRONIZED0x0020La méthode est synchronisée et ne peut donc être invoquée que si le verrou est levé.
ACC_NATIVE0x0100La méthode est native indiquant qu'elle est écrite dans un autre langage que Java.
ACC_ABSTRACT0x0400La méthode est abstraite signifiant qu'aucune implémentation n'est fournie.
ACC_STRICT0x0800La méthode est strictfp indiquant que le mode de virgule flottante est du type FP-strict.
Les classes imbriquées
DrapeauValeurDéfinition
ACC_PUBLIC0x0001La classe imbriquée est déclarée explicitement ou implicitement publique.
ACC_PRIVATE0x0002La classe imbriquée est déclarée explicitement privée.
ACC_PROTECTED0x0004La classe imbriquée est déclarée explicitement protégée.
ACC_STATIC0x0008La classe imbriquée est déclarée explicitement ou implicitement statique.
ACC_FINAL0x0010La classe imbriquée est déclarée explicitement finale.
ACC_INTERFACE0x0200La classe imbriquée est en fait une interface.
ACC_ABSTRACT0x0400La classe imbriquée est déclarée explicitement ou implicitement abstraite.
Les champs
static int ABSTRACT
représente le modificateur abstract.
static int FINAL
représente le modificateur final.
static int INTERFACE
représente le modificateur interface.
static int NATIVE
représente le modificateur native.
static int PRIVATE
représente le modificateur private.
static int PROTECTED
représente le modificateur protected.
static int PUBLIC
représente le modificateur public.
static int STATIC
représente le modificateur static.
static int STRICT
représente le modificateur strictfp.
static int SYNCHRONIZED
représente le modificateur synchronized.
static int TRANSIENT
représente le modificateur transient.
static int VOLATILE
représente le modificateur volatile.

Les constructeurs
Modifier()
crée un objet Modifier.

Les méthodes
static boolean isAbstract(int mod)
retourne true si l'argument représente un modificateur abstract ou false dans le cas contraire.
static boolean isFinal(int mod)
retourne true si l'argument représente un modificateur final ou false dans le cas contraire.
static boolean isInterface(int mod)
retourne true si l'argument représente un modificateur interface ou false dans le cas contraire.
static boolean isNative(int mod)
retourne true si l'argument représente un modificateur native ou false dans le cas contraire.
static boolean isPrivate(int mod)
retourne true si l'argument représente un modificateur private ou false dans le cas contraire.
static boolean isProtected(int mod)
retourne true si l'argument représente un modificateur protected ou false dans le cas contraire.
static boolean isPublic(int mod)
retourne true si l'argument représente un modificateur public ou false dans le cas contraire.
static boolean isStatic(int mod)
retourne true si l'argument représente un modificateur static ou false dans le cas contraire.
static boolean isStrict(int mod)
retourne true si l'argument représente un modificateur strictfp ou false dans le cas contraire.
static boolean isSynchronized(int mod)
retourne true si l'argument représente un modificateur synchronized ou false dans le cas contraire.
static boolean isTransient(int mod)
retourne true si l'argument représente un modificateur transient ou false dans le cas contraire.
static boolean isVolatile(int mod)
retourne true si l'argument représente un modificateur volatile ou false dans le cas contraire.
static String toString(int mod)
retourne une chaîne de caractères représentant l'objet Modifier.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

43.7 / La classe Proxy

La classe Proxy fournit des méthodes statiques pour la création dynamique d'instances et classes de proxy, et elle est aussi la superclasse de toutes les classes proxy dynamiques créées par ces méthodes.

Les champs
protected InvocationHandler h
représente le gestionnaire d'invocation pour l'instance de proxy courante.

Les constructeurs
protected Proxy(InvocationHandler h)
crée un objet Proxy à partir d'une sous-classe 5typiquement un classe de proxy dynamique) et avec un gestionnaire d'invocation fourni.

Les méthodes
static InvocationHandler getInvocationHandler(Object proxy)
retourne le gestionnaire d'invocation pour l'instance de proxy spécifié.
static Class getProxyClass(ClassLoader loader, Class[] interfaces)
retourne un objet de type Class en fonction d'un chargeur de classe et d'un tableau d'interfaces.
static boolean isProxyClass(Class cl)
retourne true si et seulement si la classe spécifiée a été dynamiquement générée pour être une classe de proxy utilisant la méthode getProxyClass() ou newProxyInstance().
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
retourne une instance d'un proxy en fonction des interfaces spécifiées qui acheminent les invocations de méthodes vers le gestionnaire d'invocation donné.
Les méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

43.8 / La classe ReflectPermission

La classe ReflectPermission représente la classes Permission pour les opérations d'introspection.

Un objet ReflectPermission est une permission nommée et ne possède aucunes méthodes. Le seul nom couramment défini est suppressAccessChecks, lequel permet de supprimer les contrôles d'accès standards du langage Java pour les membres publiques, protégés, privés et par défaut, exécutés par les objets réflêchis à leur point d'utilisation.

La permission suppressAccessChecks fournit des capacités d'accéder à des champs et d'invoqier des méhodes dans une classe (Notez que ceci inclut non seulement les champs et les méthodes publics, mais aussi protégés et privés). Il est dangereux d'autoriser la permission suppressAccessChecks du fait que l'information (probablement confidentielle) et les méthodes normalement indisponibles risqueraient de devenir accessibles à du code malveillant.

Les constructeurs
ReflectPermission(String name)
crée un objet ReflectPermission avec le nom spécifié.
ReflectPermission(String name, String actions)
crée un objet ReflectPermission avec les actions et le nom spécifiés.

Les méthodes
Les méthodes héritées à partir de la classe java.security.BasicPermission
equals, getActions, hashCode, implies, newPermissionCollection
Les méthodes héritées à partir de la classe java.security.Permission
checkGuard, getName, toString
Les méthodes héritées à partir de la classe java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait

44 / Le paquetage org.w3c.dom

Le paquetage org.w3c.dom fournit des interfaces pour le modèle d'objet de document (DOM : Document Object Model), lequel est un composant de l'API Java pour le traitement XML.

Le DOM Level 2 Core permet aux programmes Java d'accéder, de mettre à jour ou de créer dynamiquement la structure et le contenu d'un document XML.

Interface Description
Attr représente un attribut d'un élément XML.
CDATASection représente un section CDATA <![CDATA[Texte...]]>.
CharacterData représente un noeud XML qui contient des caractères.
Comment représente un commentaire <!-- commentaire-->'.
Document représente un document XML ou HTML.
DocumentFragment représente une partie d'un document XML.
DocumentType représente la déclaration de définition de type de document (DTD) <!DOCTYPE racine [...]>.
DOMConfiguration représente la configuration d'un document et conserve une table des paramètres reconnus.
DOMError constitue une interface décrivant une erreur.
DOMErrorHandler est une interface de retour qu'un objet DOMImplementation peut appeler lors d'un rapport d'erreurs qui se serraient produites lors du traitement de données XML ou autres traitements.
DOMImplementation fournit un nombre de méthodes pour exécuter des opérations qui sont indépendantes d'une instance particulière du DOM.
DOMImplementationList fournit l'abstraction d'une collection ordonnée des implémentations DOM sans définir ou sans contraindre comment cette collection est implémentée.
DOMImplementationSource permet à un implémenteur DOM de fournir une ou plusieurs implémentations basées sur les caractéristiques et versions requises.
DOMLocator décrit une localisation.
DOMStringList fournit l'abstraction d'une collection ordonnée de valeurs DOMString sans définir ou contraindre comment est implémentée cette collection.
Element représente un élément d'un document XML ou HTML.
Entity représente une entité connue analysée ou non-analysée dans un doucment XML.
EntityReference représente une référence d'entité comme &eacute.
NamedNodeMap constitue une collection de noeuds qui peuvent être accédés par leur nom.
NameList fournit l'abstraction d'une collection ordonnée de paires nom/valeurs d'espace de noms qui peuvent être des valeurs null, sans définir ou contraindre comment est implémentée cette collection.
Node représente un noeud dans un document.
NodeList fournit l'abstraction d'une collection ordonnée de noeuds sans définir ou contraindre comment est implémentée cette collection.
Notation représente une notation déclarée dans la DTD <!NOTATION nom SYSTEM "valeur">.
ProcessingInstruction représente une instruction de traitement XML comme un moyen de conserver des informations pour un processeur spécifique (ex.: <?xml-stylesheet type="text/xsl" href="style.xsl"?>).
Text représente un contenu textuel au sein d'un élement ou d'un attribut.
TypeInfo repésente un type référencé à partir d'éléments ou d'attributs, spécifié dans les schémas associés au document XML.
UserDataHandler Lors d'une association d'un objet à une clé sur un noeud en utilisant la méthode Node.setUserData() l'application peut fournir un gestionnaire qui reçoit des appels lorsque le noeud subi un opération de clonage, d'importation ou de renommage.
Exception Description
DOMException Les opérations DOM lèvent des exceptions dans des circonstances exceptionnelles, par exemple lorsque l'opération est impossible à exécuter.

44.1 / L'interface Attr

L'interface Attr représente un attribut au sein d'un objet Element.

<element attribut="valeur"/>

Un attribut est composé d'un nom et d'une valeur. Si une définition de type de document ou un schéma existe, les caractéristiques de l'attribut y sont définies, en l'occurrence, le nom de l'attribut, les valeurs permises ou le type de valeurs (ex.: CDATA, ENTITY, ID, NMTOKEN, etc.) et l'élément auquel il est associé, ainsi que s'il doit être requis (#REQUIRED), implicite (#IMPLIED) ou fixe (#FIXED ["valeur par défaut"]).

<!ATTLIST element attribut CDATA #REQUIRED>

L'interface Attr étend l'interface Node. Ainsi, les champs et méthodes de l'interface Node sont tous disponibles à partir d'un attribut.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
String getName()
retourne le nom de l'attribut.
Element getOwnerElement()
retourne l'élément auquel l'attribut est rattaché.
TypeInfo getSchemaTypeInfo()
retourne le type associé à l'attribut.
boolean getSpecified()
indique si l'attribut avait (true) ou n'avait pas (false) explicitement donné une valeur dans le document.
String getValue()
retourne la valeur de l'attribut.
boolean isId()
indique si l'attribut est (true) ou n'est pas (false) un attribut du type ID.
void setValue(String valeur)
fixe la valeur de l'attribut avec la valeur fournie.
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.2 / L'interface CDATASection

L'interface CDATASection représente un bloc de texte non-analysable, c'est à dire que des caractères spéciaux tels que < ou > ne seront pas pris en compte lors de l'analyse du document par le processeur XML.

<![CDATA[<baliseUn texte...>]]>

Le contenu d'une section CDATA peut ne pas être correctement interprété puisque tout type de caractères (carctères spéciaux ou caractères provenant d'encodages différents) peuvent s'y trouver rendant leur gestion difficile.

L'interface CDATASection étend l'interface Text. Ainsi, les champs et méthodes de l'interface Text sont tous disponibles à partir d'une section de caractères non-analysables.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
Les méthodes héritées de l'interface org.w3c.dom.Text
getWholeText, isElementContentWhitespace, replaceWholeText, splitText
Les méthodes héritées de l'interface org.w3c.dom.CharacterData
appendData, deleteData, getData, getLength, insertData,
replaceData, setData, substringData
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.3 / L'interface CharacterData

L'interface CharacterData permet de gérer des données textuelles. Toutes les méthodes déclarées dans cette interface servent à manipuler des chaînes de caractères.

L'interface CharacterData étend l'interface Node. Ainsi, les champs et méthodes de l'interface Node sont tous disponibles à partir d'un objet CharacterData.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
void appendData(String chaine)
ajoute la chaîne de caractères spécifiée à la fin du contenu textuel.
void deleteData(int pos, int nb)
supprime une sous-chaîne de caractères délimitée par la position de début et le nombre de caractères à traiter.
String getData()
retourne le contenu textuel du noeud.
int getLength()
retourne la longueur du contenu textuel du noeud.
void insertData(int pos, String chaine)
insère une chaîne de caractères à la position spécifiée.
void replaceData(int pos, int nb, String chaine)
remplace la sous-chaîne de caractères délimitée par la position de début et le nombre de caractères à traiter, par la chaîne de caractères spécifiée.
void setData(String data)
fixe le contenu textuel du noeud.
String substringData(int offset, int count)
extrait sous-chaîne de caractères délimitée par la position de début et le nombre de caractères à récupérer.
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.4 / L'interface Comment

L'interface Comment représente un commentaire.

<!-- commentaire... -->

Aucune vérification lexicale n'est pratiquée sur le contenu d'un commentaire. En conséquence, il est permis de placer tout type de caractères dans un commentaire y compris des caractères spéciaux tels que le double tirets --.

L'interface Comment étend l'interface CharacterData. Ainsi, les champs et attributs de l'interface CharacterData sont tous disponibles à partir d'un commentaire.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
Les méthodes héritées de l'interface org.w3c.dom.CharacterData
appendData, deleteData, getData, getLength, insertData,
replaceData, setData, substringData
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.5 / L'interface Document

L'interface Document représente un document XML ou HTML. Le document comprend tous les autres noeuds, tels que les instructions de traitement, la déclaration DTD et l'élément racine.

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE racine SYSTEM "def.dtd">
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<racine>
  contenu...
</racine>

Le prologue XML fait partie du document XML. Les attributs du prologue version, encoding et standalone sont uniquement accessibles et modifiables à partir d'un objet DOMDocument.

L'interface Document étend l'interface Node. Ainsi, les champs et méthodes de l'interface Node sont tous disponibles à partir d'un document XML ou HTML.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
Node adoptNode(Node source)
tente d'adopter un noeud à partir d'un autre document. les fragments de document, les éléments, les attributs, les noeuds textuels, les instructions de traitement, les commentaires et les références d'entité peuvent être adoptés.
Attr createAttribute(String nom)
crée un attribut avec le nom spécifié.
Attr createAttributeNS(String URIEspaceNoms, String NomQualifie)
crée un attribut avec une adresse URI d'espace de noms et un nom qualifié (préfixe:nom).
CcontenuSection createCcontenuSection(String contenu)
crée une section Ccontenu avec le contenu spécifié.
Comment createComment(String contenu)
crée un commentaire avec le contenu spécifié.
DocumentFragment createDocumentFragment()
crée un fragment de document vide.
Element createElement(String nom)
crée un élément portant le nom spécifié.
Element createElementNS(String URIEspaceNoms, String NomQualifie)
crée un élément avec une adresse URI d'espace de noms et un nom qualifié (préfixe:nom).
EntityReference createEntityReference(String nom)
crée une référence d'entité.
ProcessingInstruction createProcessingInstruction(String cible, String contenu)
crée une instruction de traitement aec la cible et le contenu spécifié.
Text createTextNode(String contenu)
crée un noeud textuel avec le contenu spécifié.
DocumentType getDoctype()
retourne la déclaration de type de document ssociée au document.
Element getDocumentElement()
retourne l'element racine du document.
String getDocumentURI()
retourne l'adresse URI localisant le document ou null si elle est indéfinie ou si le document était créé en utilisant la méthode DOMImplementation.createDocument().
DOMConfiguration getDomConfig()
retourne la configuration utilisée lorsque la méthode Document.normalizeDocument() est invoquée.
Element getElementById(String identificateur)
retourne l'élément portant l'attribut ID correspondant à l'identificateur spécifié.
NodeList getElementsByTagName(String nom)
retourne une liste d'éléments contenus dans le document, correspondant au nom passé en argument.
NodeList getElementsBynomNS(String URIEspaceNoms, String NomLocal)
retourne une liste d'éléments contenus dans le document, correspondant au nom local passé en argument et situés dans l'espace de noms indiqué.
DOMImplementation getImplementation()
retourne l'objet DOMImplementation qui gère le document.
String getInputEncoding()
retourne l'encodage de caractères employé par le document lors de son analyse.
boolean getStrictErrorChecking()
indique si la vérification stricte d'erreurs a été imposée.
String getXmlEncoding()
retourne la valeur de l'attribut encoding du prologue XML du document.
boolean getXmlStandalone()
retourne la valeur de l'attribut standalone du prologue XML du document.
String getXmlVersion()
retourne la valeur de l'attribut version du prologue XML du document.
Node importNode(Node noeud, boolean recursif)
importe un noeud à partir d'un autre document. L'arborecence complète de ce noeud peut être importée récursivement en fixant le second argument à true.
void normalizeDocument()
exprime le document sous une forme "normale". En fait, elle met à jour les références d'entité en fonction du dictionnaire d'entités de la DTD et normalise des noeuds Text, c'est-à-dire place tous les noeuds Text dans toute la profondeur de la sous arborescence en dessous du noeud courant, dans une forme "normale" incluant les attributs, où seulement le balisage (éléments, commentaires, instructions de traitement, sections CDATA et références d'entité) sépare les noeuds Text, c'est-à-dire qu'il ne doit pas y avoir de noeuds de type Text adjacents ou vides.
Node renameNode(Node noeud, String URIEspaceNoms, String NomQualifie)
renomme un élément ou un attribut spécifié avec le nom qualifié et le situe dans l'espace de noms indiqué.
void setDocumentURI(String documentURI)
fixe l'adresse URI du document.
void setStrictErrorChecking(boolean verification)
indique si une vérification stricte des erreurs doit être imposée.
void setXmlStandalone(boolean xmlStandalone)
indique si le document XML doit être autonome (standalone="yes") ou dépendant (standalone="no").
void setXmlVersion(String xmlVersion)
fixe le numéro de version du document XML (version="1.0").
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.6 / L'interface DocumentFragment

L'interface DocumentFragment est une portion d'un document XML. Un objet DocumentFragment est un document XML particulier puisqu'il peut contenir plusieurs éléments racines au contraire d'un document standard.

<element attribut="valeur">
  <fils>texte 1...</fils>
</element>
<element attribut="valeur">
  <fils>texte 2...</fils>
</element>
<element attribut="valeur">
  <fils>texte 3...</fils>
</element>

Un fragment de document est habituellement une partie extraite de l'arborescence d'un document XML. Un fragment de document peut avoir été créé avant d'être placé dans un document XML.

L'interface DocumentFragment étend l'interface Node. Ainsi, les champs et méthodes de l'interface Node sont tous disponibles à partir d'un fragment de document XML.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.7 / L'interface DocumentType

L'interface DocumentType représente une déclaration de type de document.

<!DOCTYPE racine SYSTEM "def.dtd">

La Définition de Type de Document définie la structure du document XML. Elle énumère les éléments et attributs, les types de données de ces derniers, ainsi que des entités et des notations.

<!DOCTYPE organisation [
  <!ENTITY un "Nations Unies">
  <!ENTITY onu "Organisation des &un;">
  <!ENTITY us "Etats-Unis D'Amérique">
  <!ENTITY ru "Russie">
  <!ENTITY chi "Chine">
  <!ENTITY gb "Grande Bretagne">
  <!ENTITY fr "France">
  <!ENTITY sgm "Seconde Guerre Mondiale">
  <!ENTITY ny "New York">
  <!ENTITY ya "Yalta">
  <!ENTITY sf "San Francisco">
  <!NOTATION avi SYSTEM "video/avi">
  <!ENTITY vacance SYSTEM "presentation.avi" NDATA avi>
  
  <!ELEMENT description (#PCDATA)>
  <!ATTLIST description
  <!ATTLIST description video ENTITY #REQUIRED>
  <!ELEMENT fondation (#PCDATA)>
  <!ELEMENT membres EMPTY>
  <!ATTLIST membres
              annee CDATA #REQUIRED
              nombre CDATA #REQUIRED
  >
  <!ELEMENT nom (#PCDATA)>
  <!ELEMENT organisation (nom, fondation, membres, description)>
]>

Les entités et les notations déclarées dans la DTD sont disponibles à partir des méthodes getEntities() et getNotations de l'objet DocumentType. Ces méthodes retournent des objets NamedNodeMap composés de paires nom d'une entité ou d'une notation et un objet Entity ou Notation.

Les sous-ensembles, interne et externe, désignent les différentes parties d'une déclaration de type de document, soit respectivement :

L'interface DocumentType étend l'interface Node. Ainsi, les champs et méthodes de l'interface Node sont tous disponibles à partir d'un déclaration de type de document.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
NamedNodeMap getEntities()
retourne une collection NamedNodeMap contenant les entités générales internes ou externes déclarées dans la DTD.
String getInternalSubset()
retourne le sous-ensemble interne sous la forme d'une chaîne de caractères.
String getName()
retourne le nom de la DTD, soit celui de l'élément racine.
NamedNodeMap getNotations()
retourne une collection NamedNodeMap contenant les notations déclarées dans la DTD.
String getPublicId()
retourne l'identificateur public du sous-ensemble externe.
String getSystemId()
retourne l'identificateur système du sous-ensemble externe.
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.8 / L'interface DOMConfiguration

L'interface DOMConfiguration représente la configuration d'un document et conserve une table des paramètres reconnus.

En utilisant la configuration, il est possible de changer le comportement de la méthode Document.normalizeDocument() tel que le remplacement des noeuds CDATASection par des noeuds textuels ou en spécifiant le type du schéma qui doit être utilisé lors de la validation du document. Il peut être utilisé dans les interfaces DOMParser et DOMSerializer.

Les noms de paramètres utilisés par l'objet DOMConfiguration sont définis dans les spécifications DOM Level 3. Les noms sont insensibles à la casse de caractères.

Paramètre Description
canonical-form applique une forme canonique en accord avec les règles spécifiées par le W3C. Par défaut, la valeur est false.
cdata-sections conserve les noeuds CDATASection dans le document ou les transforme en noeud textuel. Par défaut la valeur est true.
check-character-normalization vérifie si les caractères du document sont complètement normalisés comme défini par le W3C. La valeur par défaut est false.
comments conserve (true) les noeuds Comment dans le document ou les abandonne si le paramètre vaut false. La valeur par défaut est true.
datatype-normalization affiche les valeurs normalisées du schéma dans l'arborescence. La valeur par défaut est false.
element-content-whitespace conserve true tous les espaces blancs du document. La valeur par défaut est true.
entities conserve (true) les noeuds EntityReference dans le document. La valeur par défaut est true.
error-handler contient un objet DOMErrorHandler qui sera appelé pour gérer en cas d'erreur.
infoset conserve (true) dans le document les informations définies dans la recommandation XML Information Set.
namespaces traite les espaces de noms. Par défaut, la valeur est true.
namespace-declarations inclut les attributs de déclaration d'espace de noms spécifiés dans le schéma. La valeur par défauf est true.
normalize-characters normalise complètement les caractères dans le document. La valeur par défaut est false.
schema-location liste les adresses URI séparés par des espaces, qui serviront à la validation du document.
schema-type contient une adresse URI absolue représentant le type de langage de schéma utilisé pour valider le document.
split-cdata-sections découpe les sections CDATA contenant le terminateur ]]>. Par défaut, la valeur est true.
validate précise si le document requiert une validation avec un schéma, une DTD, ou autres. La valeur par défaut est false.
validate-if-schema active la validation seulement si la déclaration pour l'élément racine peut être trouvé dans un schéma ou une DTD. par défaut, la valeur est false.
well-formed vérifie si tous les noeuds sont bien formés en accord avec la version XML utilisé par le document. Par défaut, la valeur est true.
Méthode
Description
boolean canSetParameter(String nom, Object valeur)
vérifie si un paramètre peut supporter la valeur spécifiée.
Object getParameter(String nom)
retourne la valeur du paramètre spécifié.
DOMStringList getParameterNames()
retourne la liste des paramètres supportés par l'objet DOMConfiguration.
void setParameter(String nom, Object valeur)
fixe la valeur d'un paramètre en fonction de son nom.

44.9 / L'interface DOMError

L'interface DOMError permet de décrire une erreur.

Champ
Description
static short SEVERITY_ERROR
La sévérité de l'erreur décrite par l'objet DOMError est une erreur.
static short SEVERITY_FATAL_ERROR
La sévérité de l'erreur décrite par l'objet DOMError est une erreur fatale.
static short SEVERITY_WARNING
La sévérité de l'erreur décrite par l'objet DOMError est un avertissement.
Méthode
Description
DOMLocator getLocation()
indique l'emplacement de l'erreur.
String getMessage()
retourne un message décrivant l'erreur qui s'est produite.
Object getRelatedData()
retourne les données relatives.
Object getRelatedException()
retourne la plateforme relative dépendant de l'exception.
short getSeverity()
retourne la sévérité de l'erreur (SEVERITY_WARNING, SEVERITY_ERROR, ou SEVERITY_FATAL_ERROR).
String getType()
retourne le type relatif dépendant des données.

44.10 / L'interface DOMErrorHandler

L'interface DOMErrorHandler représente un gestionnaire d'erreurs. Lorsqu'une erreur se produit, alors l'implémentation DOM peut solliciter le gestionnaire d'erreurs qui provoquera l'invocation de sa méthode unique handleError().

La méthode handlerError() doit donc être implémentée au sein d'un objet qui implémentera l'interface DOMErroHandler.

public GestionnaireErreurXML implements DOMErrorHandler {
  public boolean handlerError(DOMError erreur){
    //Code chargé de gérer une erreur
    return false;
  }
}
Méthode
Description
boolean handleError(DOMError erreur)
est appelée par le gestionnaire DOMErrorHandler lorsqu'une erreur s'est produite.

44.11 / L'interface DOMException

L'interface DOMException représente une exception qui pourrait être levée lors d'opérations sur un document XML avec le DOM.

Les exceptions peuvent être levées pour différentes raisons, une erreur logique, des données perdues ou à cause d'une implémentation instable.

Champ
Description
short code
contient le code d'une exception.
static short DOMSTRING_SIZE_ERR
indique que le texte fourni ne tient pas dans le type DOMString.
static short HIERARCHY_REQUEST_ERR
indique qu'un noeud est inséré à un endroit non autorisé.
static short INDEX_SIZE_ERR
indique que l'index ou la taille est négatif ou plus grand que la valeur autorisée.
static short INUSE_ATTRIBUTE_ERR
indique qu'une tentative d'ajout d'un attribut a été effectuée alors que cet attribut a déjà été utilisé ailleurs.
static short INVALID_ACCESS_ERR
indique qu'un paramètre ou une opération n'est pas supportée par l'objet fondamental.
static short INVALID_CHARACTER_ERR
indique qu'un caractère invalide ou non autorisé est actuellement utilisé.
static short INVALID_MODIFICATION_ERR
indique qu'une tentative est de modification du type d'un objet fondamental a été opérée.
static short INVALID_STATE_ERR
indique qu'une tentative d'utilisation d'un objet inexistant ou inutilisable a été effectuée.
static short NAMESPACE_ERR
indique qu'une tentative de création ou de modification d'un objet a été opérée alors que ce dernier n'est pas conforme à l'espace de noms en vigueur.
static short NO_DATA_ALLOWED_ERR
indique que des données sont employées dans un noeud qui n'en supporte aucunes.
static short NO_MODIFICATION_ALLOWED_ERR
indique qu'une tentative de modification a été opérée dans un objet qui n'en supportent aucunes.
static short NOT_FOUND_ERR
indique qu'une tentative de référencer un noeud a été opérée alors qu'il n'existe pas dans ce contexte.
static short NOT_SUPPORTED_ERR
indique que l'implémentation ne supporte pas le type de l'objet ou de l'opération requis.
static short SYNTAX_ERR
indique qu'une chaîne de caractères invalide ou illégale a été utilisée.
static short TYPE_MISMATCH_ERR
indique que le type d'un objet est incompatible vaec le type attendu du paramètre associé à l'objet.
static short VALIDATION_ERR
indique qu'une opération d'ajout ou de modification dun noeud risque de rendre le document invalide.
static short WRONG_DOCUMENT_ERR
indique qu'un noeud est utilisé dans un document différent de celui qui l'a créé.
Constructeur
Description
DOMException(short code, String message)
crée un nouvel objet DOMException avec un code d'exception et lui associe un message.
Méthode
Description
Les méthodes héritées à partir de la classe java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace,
initCause, printStackTrace, printStackTrace, printStackTrace,
setStackTrace, toString.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait.

44.12 / L'interface DOMImplementation

L'interface DOMImplementation fournit un nombre de méthodes pour exécuter des opération qui sont indépendante de n'importe quelle instance particulière du DOM.

Méthode
Description
Document createDocument(
String URIEspaceNoms, String nomQualifie, DocumentType doctype)
crée un objet Document avec un espace de noms, un nom qualifié pour l'élément racine et une DTD.
DocumentType createDocumentType(
String nomQualifie, String publicId, String systemId)
crée une déclaraction de type de document avec un nom qualifié, et des idetificateurs public et système.
Object getFeature(String caracteristique, String version)
retourne un objet spécialisé qui implémente les APIs spécialisés de la version et de la caractéristique spécifiées.
boolean hasFeature(String caracteristique, String version)
vérifie si l'implémentation DOM implémente une caractèristique et une version spécifiées.

44.13 / L'interface DOMImplementationList

L'interface DOMImplementationList fournit l'abstraction d'une collection ordonnée des implémentations DOM sans définir ou sans contraindre comment cette collection est implémentée.

Les éléments de la liste d'implémentations DOM sont accessibles par un index, démarrant à zéro.

Méthode
Description
int getLength()
retourne le nombre d'objets DOMImplementation au sein de la liste.
DOMImplementation item(int index)
retourne l'objet DOMPlementation situé à l'index fourni.

44.14 / L'interface DOMImplementationSource

L'interface DOMImplementationSource permet à un implémenteur DOM de fournir une ou plusieurs implémentations basées sur les caractéristiques et versions requises.

Chaque objet DOMImplementationSource implémenté est listé dans la liste des liaisons spécifiques de sources disponibles de telle façon que ses objets DOMImplementation soient rendus disponibles.

Méthode
Description
DOMImplementation getDOMImplementation(String caractérstiques)
retourne la première implémentation DOM qui supporte les caractéristiques requises.
DOMImplementationList getDOMImplementationList(String caractérstiques)
retourne une liste d'implémentations DOM qui supportent les caractéristiques requises.

44.15 / L'interface DOMLocator

L'interface DOMLocator permet de décrire un emplacement au sein du code source XML.

La position d'un pointeur fournit des informations sur son environnement, telles que les numéros de ligne et de colonne, mais aussi le noeud pointé et même une adresse URI.

Méthode
Description
int getByteOffset()
retourne la position de l'octet sur lequel l'objet DOMLocator pointe à l'intérieur d'une source.
int getColumnNumber()
retourne le numéro de colonne où le pointeur est positionné.
int getLineNumber()
retourne le numéro de la ligne où le pointeur est positionné.
Node getRelatedNode()
retourne le noeud sur lequel le pointeur est positionné.
String getUri()
retourne l'URI sur laquelle le pointeur est positionné.
int getUtf16Offset()
retourne la position du pointeur par rapport à l'échelle induite par l'encodage de caractères UTF-16.

44.16 / L'interface DOMStringList

L'interface DOMStringList fournit l'abstraction d'une collection ordonnée de valeurs DOMString sans définir ou contraindre comment est implémentée cette collection.

Les éléments de la liste d'objets DOMString sont accessibles par l'intermédiaire d'un index, démarrant à zéro.

Méthode
Description
boolean contains(String chaine)
vérifie si une chaîne de caractères est contenue dans la collection DOMStringList.
int getLength()
retourne le nombre d'objets DOMString contenus dans la liste.
String item(int index)
retourne l'objet DOMString situé à l'index spécifié.

44.17 / L'interface Element

L'interface Element représente un élément dans un document HTML ou XML.

<?xml version="1.0" encoding="UTF-16"?>
<element>
   <autreElement attribut="valeur">
      Texte...
   </autreElement>
</element>

Les éléments peuvent être associés à des attributs. Ils peuvent contenir d'autres éléments ou/et du texte.

En HTML, les éléments sont normalisés par différentes recommandations du W3C. Les documents HTML doivent donc suivre des définitions de type de document établies.

<?xml version="1.0" encoding="UTF-16"?>
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <title>Titre...</title>
   </head>
   <body>
      <p>Texte...</p>
   </body>
</html>

En XML, les éléments doivent être bien formés et respecter les règles énoncées dans la définition de type de document (DTD) ou dans les divers schémas W3C, Relax NG ou autres.

L'interface Element étend l'interface Node. Ainsi, les champs et attributs de l'interface Node sont tous disponibles à partir d'un élément.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
String getAttribute(String nom)
récupère la valeur d'un attribut correspondant au nom spécifié.
Attr getAttributeNode(String nom)
récupère l'attribut correspondant au nom spécifié.
Attr getAttributeNodeNS(String URIEspaceNoms, String nomLocal)
récupère l'attribut correspondant au nom spécifié et situé dans l'espace de noms indiqué.
String getAttributeNS(String URIEspaceNoms, String nomLocal)
récupère la valeur d'un attribut correspondant au nom spécifié et situé dans l'espace de noms indiqué.
NodeList getElementsByTagName(String nom)
retourne une liste d'éléments possèdant le nom passé en argument. L'ordre du document est respecté.
NodeList getElementsByTagNameNS(String URIEspaceNoms, String nomLocal)
retourne une liste d'éléments possèdant le nom passé en argument et situés dans l'espace de noms fourni. L'ordre du document est respecté.
TypeInfo getSchemaTypeInfo()
retourne le type associé à l'élément.
String getTagName()
retourne le nom de l'élément.
boolean hasAttribute(String nom)
indique si l'élément possède des attributs.
boolean hasAttributeNS(String URIEspaceNoms, String nomLocal)
indique si l'élément possède des attributs correspondant au nomlocal indiqué et situés dans l'espace de noms.
void removeAttribute(String nom)
supprime l'attribut correspondant au nom passé en argument.
Attr removeAttributeNode(Attr oldAttr)
supprime l'attribut correspondant à l'objet Attr passé en argument.
void removeAttributeNS(String URIEspaceNoms, String nomLocal)
supprime l'attribut correspondant au nom local passé en argument et situé dans l'espace de noms requis.
void setAttribute(String nom, String valeur)
ajoute un nouvel attribut dans l'élément.
Attr setAttributeNode(Attr newAttr)
ajoute un nouveau noeud Attr dans l'élément.
Attr setAttributeNodeNS(Attr newAttr)
ajoute un nouveau noeud Attr situé dans un espace de noms, dans l'élément.
void setAttributeNS(String URIEspaceNoms, String nomQualifie, String valeur)
ajoute un nouvel attribut situé dans un espace de noms, dans l'élément.
void setIdAttribute(String nom, boolean isId)
ajoute un attribut id au sein de l'élément. Si le second argument est égal à true, alors cet attribut sera déclaré comme un identificateur ID.
void setIdAttributeNode(Attr idAttr, boolean isId)
ajoute un noeud attribut id au sein de l'élément. Si le second argument est égal à true, alors cet attribut sera déclaré comme un identificateur ID.
void setIdAttributeNS(String URIEspaceNoms, String nomLocal, boolean isId)
ajoute un noeud attribut identificateur situé dans un espace de noms, au sein de l'élément. Si le second argument est égal à true, alors cet attribut sera déclaré comme un identificateur ID.
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.18 / L'interface Entity

L'interface Entity représente des entités analysées ou non-analysées, dans un document XML.

Ce modèle représente l'entité elle-même et non la déclaration d'entité.

Un processeur XML peut choisir de développer complétement les entités avant que le modèle de structure ne soit passé au DOM. Dans ce cas, il n'y aurait plus d'objets EntityReference dans le document.

L'interface Entity étend l'interface Node. Ainsi, les champs et attributs de l'interface Node sont tous disponibles à partir d'une entité.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
String getInputEncoding()
retourne l'encodage de caratères utilisé au moment de l'analyse de l'entité externe analysée.
String getNotationName()
retourne le nom de la notation pour l'entité non-analysée..
String getPublicId()
retourne l'identificateur public associé à l'entité.
String getSystemId()
retourne l'identificateur système associé à l'entité.
String getXmlEncoding()
retourne l'encodage de caractères contenu dans l'attribut encoding du prologue XML pour l'entité analysée.
String getXmlVersion()
retourne la version XML contenu dans l'attribut version du prologue XML pour l'entité analysée.
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.19 / L'interface EntityReference

L'interface EntityReference représente une référence d'entité.

&eacute;

Les références de caractères ou d'entités prédéfinies sont considérées comme développées par le processeur HTML ou XML, de telle sorte que les caractères sont représentés par leur code Unicode équivalent plutôt que par une référence d'entité.

En XML, les références d'entités possèdent chacun une déclaration d'entité au sein de la définition de type de document. Les déclarations d'entité forment un dictionnaire sur lequel le processeur XML pourra s'appuyer pour traduire les références d'entités contenues dans le document.

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<!DOCTYPE poeme [
  <!ENTITY Agrave "À">
  <!ENTITY Aacute "Á">
  <!ENTITY Acirc "Â">
  <!ENTITY AElig "Æ">
  <!ENTITY Ccedil "Ç">
  <!ENTITY Egrave "È">
  <!ENTITY Eacute "É">
  <!ENTITY Ecirc "Ê">
  <!ENTITY Igrave "Ì">
  <!ENTITY Iacute "Í">
  <!ENTITY Icirc "Î">
  <!ENTITY Ograve "Ò">
  <!ENTITY Oacute "Ó">
  <!ENTITY Ocirc "Ô">
  <!ENTITY Ugrave "Ù">
  <!ENTITY Uacute "Ú">
  <!ENTITY Ucirc "Û">
  <!ENTITY agrave "à">
  <!ENTITY aacute "á">
  <!ENTITY acirc "â">
  <!ENTITY aelig "æ">
  <!ENTITY ccedil "ç">
  <!ENTITY egrave "è">
  <!ENTITY eacute "é">
  <!ENTITY ecirc "ê">
  <!ENTITY igrave "ì">
  <!ENTITY iacute "í">
  <!ENTITY icirc "î">
  <!ENTITY ograve "ò">
  <!ENTITY oacute "ó">
  <!ENTITY ocirc "ô">
  <!ENTITY ugrave "ù">
  <!ENTITY uacute "ú">
  <!ENTITY ucirc "û">
  <!ELEMENT poeme (#PCDATA)>
  <!ATTLIST poeme xml:space (preserve|default) "default">
]>
<poeme xml:space="preserve">
  &Agrave; quatre heures du matin, l'&eacute;t&eacute;,
  Le soleil d'amour dure encore.
  Sous les bocages s'&eacute;vapore
  L'odeur du soir f&ecirc;t&eacute;.

  L&agrave;-bas, dans leur vaste chantier
  Au soleil des Hesp&eacute;rides,
  D&eacute;j&agrave; s'agitent - en bras de chemise -
  Les charpentiers.

  Dans leurs D&eacute;serts de mousse, tranquilles,
  Ils pr&eacute;parent les lambris pr&eacute;cieux
  O&ugrave; la ville
  Peindra de faux cieux.

  &Ocirc;, pour ces Ouvriers charmants
  Sujets d'un roi de Babylone
  V&eacute;nus ! quitte un instant les Amants
  Dont l'&acirc;me est en couronne.

  &Ocirc; Reine des Bergers,
  Porte aux travailleurs l'eau-de-vie,
  Que leur force soient en paix
  En attendant le bain la mer &agrave; midi.
</poeme>

D'ailleurs, le processeur XML peut complètement développer les références d'entités au moment du développement du document, à la place de fournir les noeuds EntityReference.

Lorsqu'un noeud EntityReference représente une référence à une entité inconnue, le noeud n'a pas d'enfant et sa valeur de remplacement est vide.

L'interface EntityReference étend l'interface Node. Ainsi, les champs et attributs de l'interface Node sont tous disponibles à partir d'une référence d'entité.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.20 / L'interface NamedNodeMap

L'interface NamedNodeMap constitue une collection de noeuds qui peuvent être accédés par leur nom.

La collection NamedNodeMap ne conserve pas l'ordre des noeuds, dans lequel ils auraient été trouvés au sein du document.

A l'instar d'une collection NodeList, les noeuds peuvent être également accédés par un index, démarrant à zéro. Ceci est pratique pour une énumération des noeuds de la collection.

Méthode
Description
int getLength()
retourne le nombre de noeuds au sein de la collection.
Node getNamedItem(String nom)
retourne le noeud correspondant au nom passé en argument.
Node getNamedItemNS(String URIEspaceNoms, String nomLocal)
retourne le noeud correspondant au nom local spécifié et situé dans l'espace de noms indiqué.
Node item(int index)
retourne le noeud situé à l'index spécifié.
Node removeNamedItem(String nom)
supprime le noeud correspondant au nom spécifié.
Node removeNamedItemNS(String URIEspaceNoms, String nomLocal)
supprime le noeud correspondant au nom local spécifié et situé dans l'espace de noms indiqué.
Node setNamedItem(Node arg)
ajoute un noeud en utilisant son attribut nodeName pour le référencer dans la collection.
Node setNamedItemNS(Node arg)
ajoute un noeud en utilisant ses attributs nodeLocal et namespaceURI pour le référencer dans la collection.

44.21 / L'interface NameList

L'interface NameList fournit l'abstraction d'une collection ordonnée de paires nom/URI d'espace de noms qui peuvent être des valeurs null, sans définir ou contraindre comment est implémentée cette collection.

Les éléments de la collection NameList sont accessibles par leur index, démarrant à zéro pur le premier.

Méthode
Description
boolean contains(String chaine)
vérifie si une chaîne de caractères fait partie de la collection NameList.
boolean containsNS(String URIEspaceNoms, String nom)
vérifie si la paire nom et URI d'espace de noms, fait partie de la collection NameList.
int getLength()
retourne le nombre de paires nom et URI d'espace de noms, contenues dans la liste.
String getName(int index)
retourne le nom positionné à l'index spécifié.
String getNamespaceURI(int index)
retourne une URI d'espace de noms situé à l'index spécifié.

44.22 / L'interface Node

L'interface Node représente un noeud XML générique.

Le document, les fragments de document, la déclaration de définition de type de document, les instructions de traitement, les commentaires, les éléments, les attributs, les noeuds textuels, les références d'entité, les entités et les notations sont tous des noeuds XML.

La connaissance du type d'un objet Node s'effectue par l'intermédiaire de la méthode getNodeType() retournant un entier de type short. Cette valeur correspond à un champ statique de l'interface Node. Une comparaison de la valeur obtenue avec ces champs, indique assurément le type du noeud XML.

switch(noeud.getNodeType){
  case ATTRIBUTE_NODE :
    //Traitement d'un attribut
    break;
  case CDATA_SECTION_NODE :
    //Traitement d'une section CDATA
    break;
  case COMMENT_NODE :
    //Traitement d'un commentaire
    break;
  case DOCUMENT_FRAGMENT_NODE :
    //Traitement d'un fragment de document
    break;
  case DOCUMENT_NODE :
    //Traitement d'un document
    break;
  case DOCUMENT_TYPE_NODE :
    //Traitement d'une déclaration DTD
    break;
  case ELEMENT_NODE :
    //Traitement d'un élément
    break;
  case ENTITY_NODE :
    //Traitement d'une entité
    break;
  case ENTITY_REFERENCE_NODE :
    //Traitement d'une référence d'entité
    break;
  case NOTATION_NODE :
    //Traitement d'une notation
    break;
  case PROCESSING_INSTRUCTION_NODE :
    //Traitement d'une instruction de traitement
    break;
  case TEXT_NODE :
    //Traitement d'un texte
    break;
  default:
    //Traitement d'une erreur
}

La méthode getAttributes() retourne une collection NamedNodeMap dans un seul et unique cas, lorsque le noeud courant est un élément. Pour tous les autres noeuds, la méthode renvoie null.

Les valeurs retournées par les méthodes getNodeName(), getNodeValue() peuvent varier en fonction du type du noeud courant.

Typenoeud.nodeName()noeud.nodeValue()
AttrAttr.nameAttr.value
CDATASection"#cdata-section"CharacterData.data
Comment"#comment"CharacterData.data
Document"#document"null
DocumentFragment"#document-fragment"null
DocumentTypeDocumentType.namenull
ElementElement.tagNamenull
Entitynom de l'entiténull
EntityReferencenom de la référence d'entiténull
Notationnom de la notationnull
ProcessingInstructionProcessingInstruction.targetProcessingInstruction.data
Text"#text"CharacterData.data
Champ
Description
static short ATTRIBUTE_NODE
Le noeud est un attribut.
static short CDATA_SECTION_NODE
Le noeud est une section CDATA.
static short COMMENT_NODE
Le noeud est un commentaire.
static short DOCUMENT_FRAGMENT_NODE
Le noeud est un fragment de document.
static short DOCUMENT_NODE
Le noeud est un document.
static short DOCUMENT_POSITION_CONTAINED_BY
Le noeud est contenu par le noeud de référence.
static short DOCUMENT_POSITION_CONTAINS
Le noeud contient le noeud de référence.
static short DOCUMENT_POSITION_DISCONNECTED
Les deux noeuds sont déconnectés.
static short DOCUMENT_POSITION_FOLLOWING
Le noeud suit le noeud de référence.
static short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
La détermination du précédent contre le suivant est l'implémentation spécifique.
static short DOCUMENT_POSITION_PRECEDING
Le second noeud précède le noeud de référence.
static short DOCUMENT_TYPE_NODE
Le noeud est une déclaration DTD.
static short ELEMENT_NODE
Le noeud est un élément.
static short ENTITY_NODE
Le noeud est une entité.
static short ENTITY_REFERENCE_NODE
Le noeud est une référence d'entité.
static short NOTATION_NODE
Le noeud est une notation.
static short PROCESSING_INSTRUCTION_NODE
Le noeud est une instruction de traitement.
static short TEXT_NODE
Le noeud est un texte.
Méthode
Description
Node appendChild(Node noeud)
ajoute le nouveau noeud à la fin de la liste d'enfants du noeud courant.
Node cloneNode(boolean recursif)
retourne un clone du noeud courant. Eventuellement, l'arborescence complète du noeud peut être cloné récursivement en fixant à true l'argument.
short compareDocumentPosition(Node noeud)
compare la position des noeuds au sein du document.
NamedNodeMap getAttributes()
retourne la collection d'attributs du noeud courant.
String getBaseURI()
retourne l'adresse URI de base absolue du noeud courant ou null si l'implémentation n'a pas été capable d'obtenir une adresse URI absolue.
NodeList getChildNodes()
retourne une liste de noeuds contenus dans le noeud courant.
Object getFeature(String caracteristique, String version)
retourne un objet spécialisé qui implémente les APIs spécialisées de la caractéristique et la version spécifiées.
Node getFirstChild()
retourne le premier enfant du noeud courant.
Node getLastChild()
retourne le dernier enfant du noeud courant.
String getLocalName()
retourne le nom local du noeud courant.
String getNamespaceURI()
retourne l'adresse URI d'espace de noms du noeud courant, ou null s'il n'en a pas.
Node getNextSibling()
retourne le noeud suivant immédiatement le noeud courant.
String getNodeName()
retourne le nom du noeud courant, en fonction de son type.
short getNodeType()
retourne le type du noeud courant.
String getNodeValue()
retourne la valeur du noeud courant en fonction de son type.
Document getOwnerDocument()
retourne le document auquel appartien le noeud courant.
Node getParentNode()
retourne le noeud parent du noeud courant.
String getPrefix()
retourne le préfixe d'espace de noms du noed courant.
Node getPreviousSibling()
retourne le noeud précédent immédiatement le noeud courant.
String getTextContent()
retourne le contenu textuel du noeud courant et de toute sa descendance.
Object getUserData(String cle)
retourne l'objet associé à la clé passée en argument.
boolean hasAttributes()
indique si le noeud courant possède des attributs.
boolean hasChildNodes()
indique si le noeud courant possède une descendance.
Node insertBefore(Node noeud, Node noeud_reference)
insère le nouveau noeud avant le noeud de référence.
boolean isDefaultNamespace(String URIEspaceNoms)
indique si l'URI d'espace de noms spécifiée est l'espace de nom par défaut.
boolean isEqualNode(Node noeud)
vérifie si les deux noeuds sont égaux.
boolean isSameNode(Node other)
indique si les deux noeuds sont les mêmes.
boolean isSupported(String feature, String version)
indique si la caractéristique et la version sont supportées par le noeud courant.
String lookupNamespaceURI(String prefix)
retourne l'URI d'espace de noms associé au préfixe spécifié, à partir du noeud courant.
String lookupPrefix(String URIEspaceNoms)
retourne le préfixe associé à l'URI d'espace de noms spécifiée, à partir du noeud courant.
void normalize()
place tous les noeuds Text dans toute la profondeur de la sous arborescence en dessous du noeud courant, dans une forme "normale" incluant les attributs, où seulement le balisage (éléments, commentaires, instructions de traitement, sections CDATA et références d'entité) sépare les noeuds Text, c'est-à-dire qu'il ne doit pas y avoir de noeuds de type Text adjacents ou vides.
Node removeChild(Node noeud)
supprime le noeud spécifié de la liste des enfants du noeud courant.
Node replaceChild(Node noeud, Node ancien_noeud)
remplace l'ancien noeud par le nouveau noeud au sein de la liste des enfants du noeud courant.
void setNodeValue(String valeur)
fixe la valeur textuel du noeud courant.
void setPrefix(String prefix)
fixe le préfixe d'espace de noms du noeud courant.
void setTextContent(String contenu)
fixe le contenu textuel du noeud courant et de sa descendance.
Object setUserData(String cle, Object donnee, UserDataHandler gestionnaire)
associe un objet et un gestionnaire à une clé pour le noeud courant.

44.23 / L'interface NodeList

L'interface NodeList fournit l'abstraction d'une collection ordonnée de noeuds sans définir ou contraindre comment est implémentée cette collection.

Cette collection est retournéedans le cas d'une invocation de la méthode getChildNodes() d'un objet Element par exemple. Dans ce cas, la liste NodeList contient les noeuds enfants de l'élément courant.

Les éléments de la collection NodeList sont accessibles par l'intermédiaire d'un index, démarrant à zéro.

Méthode
Description
int getLength()
retourne le nombre de noeuds contenus dans la collection NodeList.
Node item(int index)
retourne le noeud positionné à l'index spécifié.

44.24 / L'interface Notation

L'interface Notation représente une notation déclarée dans la définition de type de document (DTD).

<!NOTATION GIF89a PUBLIC 
     "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">

<!NOTATION avi SYSTEM "video/avi">

Une notation déclare le format d'une entité non-analysée. Elle peut aussi être utilisée pour la déclaration formelle des cibles d'instruction de traitement.

L'interface Notation étend l'interface Node. Ainsi, les champs et attributs de l'interface Node sont tous disponibles à partir d'une notation.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
String getPublicId()
retourne l'identificateur public.
String getSystemId()
retourne l'identificateur système.
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.25 / L'interface ProcessingInstruction

L'interface ProcessingInstruction représente une instruction de traitement

Les instructions de traitement sont utilisées en XML, pour conserver des informations dans le texte du document pour un processeur spécifique, soit une application.

Une instruction de traitement est composé d'une cible et d'un contenu pouvant lister des paramètres.

<?cible liste_paramètres?>

<?xml-stylesheet href="style.css" type="text/css"?>

L'application cible est dans la plupart des cas un moteur de tranformation XSL, voir CSS. Il est possible de solliciter également d'autres programmes.

<?robots index="yes" follow="yes"?>

<?programme param1="valeur" param2="valeur"?>

Durant le traitement d'un document par un analyseur (parser) XML, l'instruction de traitement dont la cible a été reconnue provoque l'exécution du programme qui lui est associé. Pour gérer des instructions de traitement personnelles, il suffit d'écrire son propre gestionnaire (handler) pour le traitement de document XML. Les navigateurs Web possèdent de tels gestionnaires qui leur permettent de traiter un document XML contenant des instructions de traitement pour le rendu des données (XSL et CSS). Certains robots des moteurs de recherche, déclenche un traitement spécifique lorsqu'ils aperçoivent la cible robots dans un document XML.

L'interface ProcessingInstruction étend l'interface Node. Ainsi, les champs et attributs de l'interface Node sont tous disponibles à partir d'une instruction de traitement.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
String getData()
retourne le contenu de l'instruction de traitement.
String getTarget()
retourne la cible de l'instruction de traitement.
void setData(String data)
fixe le contenu de l'instruction de traitement.
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.26 / L'interface Text

L'interface Text représente le contenu textuel d'un élément ou d'un attribut.

<element attribut="Un noeud texte">
  Un autre noeud texte...
</element>

L'interface Text étend l'interface CharacterData. Ainsi, les champs et attributs de l'interface CharacterData sont tous disponibles à partir d'un texte.

Champ
Description
Les champs hérités de l'interface org.w3c.dom.Node
ATTRIBUTE_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE,
DOCUMENT_POSITION_CONTAINED_BY, DOCUMENT_POSITION_CONTAINS,
DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_FOLLOWING,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC,
DOCUMENT_POSITION_PRECEDING, DOCUMENT_TYPE_NODE, ELEMENT_NODE,
ENTITY_NODE, ENTITY_REFERENCE_NODE, NOTATION_NODE,
PROCESSING_INSTRUCTION_NODE, TEXT_NODE
Méthode
Description
String getWholeText()
retourne le texte contenu par le noeud courant et également par tous les noeuds Text adjacents.
boolean isElementContentWhitespace()
indique si le noeud contient des espaces blancs.
Text replaceWholeText(String contenu)
remplace le texte du noeud courant et celui de tous les noeuds Text adjacents, par le texte spécifié.
Text splitText(int pos)
découpe le noeud courant en deux noeuds à partir d'une position spécifiée.
Les méthodes héritées de l'interface org.w3c.dom.CharacterData
appendData, deleteData, getData, getLength, insertData,
replaceData, setData, substringData
Les méthodes héritées de l'interface org.w3c.dom.Node
appendChild, cloneNode, compareDocumentPosition, getAttributes, getBaseURI,
getChildNodes, getFeature, getFirstChild, getLastChild, getLocalName,
getNamespaceURI, getNextSibling, getNodeName, getNodeType, getNodeValue,
getOwnerDocument, getParentNode, getPrefix, getPreviousSibling,
getTextContent, getUserData, hasAttributes, hasChildNodes, insertBefore,
isDefaultNamespace, isEqualNode, isSameNode, isSupported,
lookupNamespaceURI, lookupPrefix, normalize, removeChild, replaceChild,
setNodeValue, setPrefix, setTextContent, setUserData

44.27 / L'interface TypeInfo

L'interface TypeInfo représente un type référencé d'éléments ou d'attributs, spécifié dans les schémas associé avec le document. Le type est une paire URI d'espace de noms/nom du type et dépend su schéma du document.

Champ
Description
static int DERIVATION_EXTENSION
Si le schéma du document est un schéma W3C, cette constante représente la dérivation par extension.
static int DERIVATION_LIST
Si le schéma du document est un schéma W3C, cette constante représente la liste.
static int DERIVATION_RESTRICTION
Si le schéma du document est un schéma W3C, cette constante représente la dérivation par restriction si des types complexes sont impliqués ou une restriction si des types simples sont impliqués.
static int DERIVATION_UNION
Si le schéma du document est un schéma W3C, cette constante représente l'union si des simples types sont impliqués.
Méthode
Description
String getTypeName()
retourne le nom du type déclaré pour l'attribut ou l'élément associé ou null si le type est inconnu.
String getTypeNamespace()
retourne l'espace de noms du type déclaré pour l'élément ou l'attribut associé, ou null si l'élément n'a pas la déclaration ou si aucune information d'espace de noms n'est disponible.
boolean isDerivedFrom(
String typeEspaceNoms, String typeNom, int methodeDerivation)
retourne une valeur booléenne s'il y a une dérivation entre la définition de type de référence, c'est-à-dire le TypeInfo sur lequel la méthode s'appelle, et l'autre définition de type, c'est-à-dire celle passée comme paramètres. Si le schéma du document est un DTD ou qu'aucun schéma n'est associé au document, cette méthode retournera toujours false. Si le schéma du document est un schéma XML, la méthode rectifiera si la définition de type de référence est dérivée de l'autre définition de type selon le paramètre de dérivation. Si la valeur du paramètre est 0 (aucun bit n'est fixé à 1 pour le paramètre methodeDerivation), la méthode renverra true si l'autre définition de type peut être atteinte récursivement n'importe quelle combinaison de { définition de type de base}, {la définition de type d'item}, ou {des définitions de type de membre } à partir de la définition de type de référence.

44.28 / L'interface UserDataHandler

L'interface UserDataHandler représente un gestionnaire d'événements sur des données XML.

Un objet UserDataHandler est chargé de gérer certaines opérations exécutées sur des noeuds, en l'occurrence l'adoption, le clonage, l'importation, le renommage et la suppression.

La méthode setUserData() d'un objet Node permet d'affecter un gestionnaire d'événements au noeud courant.

Lorsque un noeud est associé à un gestionnaire d'événements, l'application peut adopter un comportement spécifique en fonction de l'action produite sur ce noeud.

Il est nécessaire de créer une classe qui implémentera l'interface UserDataHanler et en particulier sa méthode handle() qui sera appelée dès que le noeud subira une des opérations précitées.

Champ
Description
static short NODE_ADOPTED
Le noeud est adopté en utilisant la méthode Document.adoptNode().
static short NODE_CLONED
Le noeud est cloné en utilisant la méthode Node.cloneNode().
static short NODE_DELETED
Le noeud est supprimé.
static short NODE_IMPORTED
Le noeud est importé en utilisant la méthode Document.importNode().
static short NODE_RENAMED
Le noeud est renommé en utilisant la méthode Node.renameNode().
Méthode
Description
void handle(
short operation, String cle, Object donnee, Node source, Node destination)
Cette méthode est appelée à chaque fois que le noeud pour lequel le gestionnaire courant est enregistré, est importé ou cloné.
  • operation : indique le type de l'opération (les champs statiques de cette interface) qui est exécutée sur le noeud.
  • cle : spécifie la clé pour laquelle le gestionnaire est appelé.
  • donnee : définit la donnée pour laquelle le gestionnaire est appelé.
  • source : fournit le noeud copié, adopté, importé, ou renommé. Il est nulle lorsque le noeud est supprimé.
  • destination : correspond au noeud nouvellement créé, s'il existe.

45 / Le paquetage org.w3c.dom.bootstrap

Le paquetage org.w3c.dom.bootstrap fournit une fabrique qui permet aux applications d'obtenir des instances d'objets DOMImplementation.

Classe Description
DOMImplementationRegistry permet aux applications d'obtenir des instances d'objets DOMImplementation.

46 / Le paquetage org.w3c.dom.events

Le paquetage org.w3c.dom.events fournit un ensemble d'interfaces destinées à gérer divers types d'événements.

Interface Description
DocumentEvent fournit un mécanisme par lequel l'utilisateur peut créer un objet Event d'un type supporté par l'implémentation.
Event fournit des informations contextuelles spécifiques à propos d'un événement au gestionnaire traitant l'événement.
EventListener est la méthode principale pour la gestion d'événements.
EventTarget est implémentée par tous les noeuds dans une implémentation qui supporte le modèle d'événements DOM.
MouseEvent fournit des informations contextuelles spécifiques associées aux événements de souris.
MutationEvent fournit des informations contextuelles spécifiques associées aux événements Mutation.
UIEvent fournit des informations contextuelles spécifiques associées aux événements d'interface utilisateur (UI).
Exception Description
EventException Les opérations Event peuvent lancer des exceptions EventException.

47 / Le paquetage org.w3c.dom.ls

Le paquetage org.w3c.dom.ls propose des interfaces pour la création et la gestion d'objets Load et Save.

Interface Description
DOMImplementationLS contient des méthodes de fabrication d'objets Load et Save.
LSInput représente une source d'entrée pour les données.
LSLoadEvent représente un événement de chargement qui signale l'achèvement d'un chargement d'un document.
LSOutput représente une destination de sortie pour les données.
LSParser Une interface vers un objet qui est capable de construire ou d'augmenter une arborescence à partir de diverses sources d'entrée.
LSParserFilter fournit aux applications la capacité d'examiner des noeuds s'ils sont construits durant l'analyse.
LSProgressEvent représente un objet d'événement de progression qui notifie l'application de la progression de l'analyse d'un document.
LSResourceResolver fournit une voie pour les applications de rediriger des références à des ressources externes.
LSSerializer fournit une API pour la sérialisation d'un document DOM en dehors de XML.
LSSerializerFilter fournit aux applications la capacité d'examiner des noeuds s'ils sont sérialisés et décide que les noeuds devraient être ou ne pas être sérialisés.
Exception Description
LSException Des opérations d'analyse ou d'écriture peuvent lancées une exception LSException si le traitement est stoppé.

48 / Le paquetage org.xml.sax

Le paquetage org.xml.sax constitue le coeur des APIs SAX (Simple API for XML).

L'analyse SAX est radicalement différente de l'analyse DOM. En effet, des événements particuliers sont déclenchés lors du parcours du document XML par l'analyseur SAX. Ces évenements déclenchent des traitements spécifiques exécutés par les gestionnaires de contenus, de DTD (Définition de Type de Document), d'entités externes et d'erreurs.

Les interfaces représentant les gestionnaires doivent être l'objet d'implémentation par des classes spécialisées. Ces dernières contiendront le code permettant de traiter les évenements produits lors de l'analyse SAX.

Interface Description
AttributeList est dépréciée car elle a été remplacée par l'interface Attributes.
Attributes représente un liste d'attributs XML.
ContentHandler représente un gestionnaire du contenu logique d'un document.
DocumentHandler est dépréciée car elle a été remplacée par l'interface ContentHandler.
DTDHandler représente un gestionnaire d'événements relatifs à la DTD de base.
EntityResolver permet de résoudre les entités externes.
ErrorHandler permet de gérer les erreurs SAX.
Locator est utilisé pour l'association d'événement SAX avec un emplacement dans un document.
Parser est dépréciée car elle a été remplacée par l'interface XMLReader.
XMLFilter représente un filtre XML.
XMLReader permet de lire un document XML en utilisant une technique de rappel.
Classe Description
HandlerBase est dépréciée car elle fonctionne avec l'interface DocumentHandler dépréciée.
InputSource représente une unique source d'entrée pour une entité XML.
Exception Description
SAXException indique une erreur générale ou un avertissement SAX.
SAXNotRecognizedException se produit lorsqu'un identificateur n'est pas reconnu.
SAXNotSupportedException se produit lorsqu'une classe ne supporte pas une opération.
SAXParseException indique une erreur ou un avertissement durant l'analyse SAX.

48.1 / L'interface Attributes

L'interface Attributes représente une liste d'attributs XML.

Cette interface permet d'accéder aux attributs d'une liste par différents moyens :

La liste ne contiendra pas les attributs qui ont été déclarés #IMPLIED et non plus les attributs déclarant les URI d'espace de noms (xmlns:préfixe="URIEspaceNoms").

L'ordre des attributs ne suivront pas forcément l'ordre du document XML analysé, puisque cela varie en fonction des implémentations.

Méthode
Description
int getIndex(String qName)
retourne l'index d'un attribut XML correspondant au nom qualifié spécifié.
int getIndex(String URIEspaceNoms, String localName)
retourne l'index d'un attribut XML correspondant au nom local spécifié et situé dans l'espace de noms précisé.
int getLength()
retourne le nombre d'attributs dans la liste.
String getLocalName(int index)
retourne le nom local d'un attribut positionné à l'index spécifié.
String getQName(int index)
retourne le nom qualifié d'un attribut positionné à l'index spécifié.
String getType(int index)
retourne le type d'un attribut positionné à l'index spécifié.
String getType(String qName)
retourne le type d'un attribut correspondant au nom qualifié spécifié.
String getType(String uri, String localName)
retourne le type d'un attribut correspondant au nom local spécifié et situé dans l'espace de noms précisé.
String getURI(int index)
retourne l'adresse URI d'espace de noms d'un attribut positionné à l'index spécifié.
String getValue(int index)
retourne la valeur d'un attribut positionné à l'index spécifié.
String getValue(String qName)
retourne la valeur d'un attribut correspondant au nom qualifié spécifié.
String getValue(String uri, String localName)
retourne la valeur d'un attribut correspondant au nom local spécifié et situé dans l'espace de noms précisé.

48.2 / L'interface ContentHandler

L'interface ContentHandler fournit un ensemble de méthodes permettant de gérer différents événements relatifs à la structure d'un document XML, lors de son analyse.

L'analyse SAX produit des événements spécifiques à chaque fois qu'un objet particulier du document XML est rencontré.

Le document XML est parcouru de haut en bas, c'est à dire, que l'analyseur SAX :

Cette interface est similaire à l'interface dépréciée DocumentHandler, à l'exception qu'elle est capable de gérer les espaces de noms et sur le compte-rendu des entités ignorées dasn des processeurs non-validants

Méthode
Description
void characters(char[] ch, int start, int length)
reçoit la notification de données textuelles.
void endDocument()
reçoit la notification de fin de document.
void endElement(String uri, String localName, String qName)
reçoit la notification de fin d'un élément.
void endPrefixMapping(String prefix)
reçoit la notification de fin de portée d'un préfixe et d'une adresse URI d'espace de noms.
void ignorableWhitespace(char[] ch, int start, int length)
reçoit la notification d'espaces blancs dans le contenu d'un élément.
void processingInstruction(String target, String data)
reçoit la notification d'instruction de traitement.
void setDocumentLocator(Locator locator)
reçoit un objet Locator fournissant l'emplacement d'un événement du document SAX.
void skippedEntity(String name)
reçoit la notification d'une entité ignorée.
void startDocument()
reçoit la notification de début d'un document.
void startElement(String uri, String localName, String qName, Attributes atts)
reçoit la notification du début d'un élément.
void startPrefixMapping(String prefix, String uri)
reçoit la notification de début de portée d'un préfixe et d'une adresse URI d'espace de noms.

48.3 / L'interface DTDHandler

L'interface DTDHandler est chargée de gérer des événements relatifs à la définition de type de document (DTD).

Si une application de SAX a besoin d'informations sur des notations et des entités non-analysées, alors une classe doit implémenter cette interface et définir un comportement pour les deux méthodes, puis doit enregistrer l'instance de cette classe avec l'analyseur SAX en utilisant la méthode XMLReader.setDTDHandler(). L'analyseur emploie cet objet pour rapporter à l'application, les déclarations de notation et d'entité non-analysée.

Méthode
Description
void notationDecl(String name, String publicId, String systemId)
reçoit la notification d'un événement de déclaration d'une notation.
void unparsedEntityDecl(
String name, String publicId, String systemId, String notationName)
reçoit la notification d'un événement d'une déclaration d'entité non-analysée.

48.4 / L'interface EntityResolver

L'interface EntityResolver représente un gestionnaire d'entités externes.

Si une application de SAX a besoin d'un traitement particulier pour les entités externes, une classe doit implémenter l'interface EntityResolver et enregistrer une instance de cette dernière avec l'analyseur SAX en utilisant la méthode de XMLReader.setEntityResolver().

Méthode
Description
InputSource resolveEntity(String publicId, String systemId)
permet à l'application de résoudre des entités externes.

48.5 / L'interface ErrorHandler

L'interface ErrorHandler représente un gestionnaire d'erreurs.

Si une application SAX a besoin de gérer les erreurs SAX, une classe doit implémenter l'interface ErrorHandler et puis enregistrer l'instance de cett dernière avec l'objet XMLReader en utilisant la méthode setErrorHandler(). L'analyseur rapportera toutes les erreurs et avertissements produit lors du processus d'analyse d'un document XML.

Méthode
Description
void error(SAXParseException exception)
reçoit une notification en cas d'erreur récupérable.
void fatalError(SAXParseException exception)
reçoit une notification en cas d'erreur fatale.
void warning(SAXParseException exception)
reçoit une notification en cas d'avertissement.

48.6 / L'interface Locator

L'interface Locator fournit des informations sur l'emplacement où s'est produit un événement relatif à un document XML.

Si un analyseur SAX fournit des informations sur la localisation d'un événement à l'application de SAX, une classe doit implémenter cette interface, puis l'instance de cette classe doit être passée au gestionnaire de contenu par l'intermédaire de la méthode ContentHandler.setDocumentLocator(). L'application peut utiliser l'objet pour obtenir l'emplacement de n'importe quel événement SAX dans le document XML.

Méthode
Description
int getColumnNumber()
retourne le numéro de la colonne où l'événement du document courant s'achève.
int getLineNumber()
retourne le numéro de la ligne où l'événement du document courant s'achève.
String getPublicId()
retourne l'identificateur public pour l'événement du document courant s'achève.
String getSystemId()
retourne l'identificateur système pour l'événement du document courant s'achève.

48.7 / L'interface XMLFilter

L'interface XMLFilter représente un filtre XML.

Un filtre XML est semblable à un objet XMLReader, excepté qu'il obtient ses événements à partir d'un autre objet XMLReader plutôt qu'une source primaire comme un document XML ou une base de données. Les filtres peuvent modifier un flux d'événements pendant qu'ils continuent vers l'application finale.

La classe XMLFilterImpl fournit une base pratique pour la création de filtres SAX2, en passant automatiquement sur tous les événements EntityResolver, DTDHandler, ContentHandler et ErrorHandler.

Méthode
Description
XMLReader getParent()
retourne l'objet parent XMLReader.
void setParent(XMLReader parent)
fixe l'objet parent XMLReader.
Les méthodes héritées de l'interface org.xml.sax.XMLReader
getContentHandler, getDTDHandler, getEntityResolver, getErrorHandler,
getFeature, getProperty, parse, parse, setContentHandler, setDTDHandler,
setEntityResolver, setErrorHandler, setFeature, setProperty

48.8 / L'interface XMLReader

L'interface XMLReader fournit toutes les fonctionnalités et avantages de SAX. Elle est utilisée pour la lecture de document XML.

Les objets implémentant cette interface peuvent être configurés par l'intermédiaire de caractéristiques (features) et de propriétés (properties) standards.

Méthode
Description
ContentHandler getContentHandler()
retourne le gestionnaire de contenu courant.
DTDHandler getDTDHandler()
retourne le gestionnaire de DTD courant.
EntityResolver getEntityResolver()
retourne le gestionnaire d'entités externes et de notations courant.
ErrorHandler getErrorHandler()
retourne le gestionnaire d'erreurs courant.
boolean getFeature(String name)
retourne la valeur d'une caractéristique pour le nom spécifié.
Object getProperty(String name)
retourne la valeur d'une propriété pour le nom spécifié.
void parse(InputSource input)
analyse une source d'entrée XML.
void parse(String systemId)
analyse une source XML à partir d'un identificateur système.
void setContentHandler(ContentHandler handler)
fixe le gestionnaire de contenu à enregistrer pour l'objet XMLReader courant.
void setDTDHandler(DTDHandler handler)
fixe le gestionnaire de DTD à enregistrer pour l'objet XMLReader courant.
void setEntityResolver(EntityResolver resolver)
fixe le gestionnaire d'entités externes et de notations à enregistrer pour l'objet XMLReader courant.
void setErrorHandler(ErrorHandler handler)
fixe le gestionnaire d'erreurs à enregistrer pour l'objet XMLReader courant.
void setFeature(String name, boolean value)
fixe la valeur d'une caractéristique de l'objet XMLReader.
void setProperty(String name, Object value)
fixe la valeur d'une propriété de l'objet XMLReader.

48.9 / La classe InputSource

La classe InputSource constitue une source d'entrée XML pour un analyseur SAX.

Un objet InputSource permet à une application SAX d'encapsuler des informations à propos d'une source d'entrée dans un unique objet, qui peut inclure un identificateur public, un identificateur système, un flux d'octets avec un encodage si possible et/ou un flux de caractères.

L'analyseur SAX utilisera l'objet InputSource pour déterminer comment il doit lire l'entrée XML.

Il y a deux endroits que l'application peut fournir une source d'entrée à l'analyseur: comme argument à la méthode de Parser.parse, ou comme valeur de retour de la méthode d'EntityResolver.resolveEntity.

L'analyseur SAX emploiera l'objet InputSource pour déterminer comment lire l'entrée de XML.

Constructeur
Description
InputSource()
crée une nouvelle instance de la classe InputSource.
InputSource(InputStream byteStream)
crée une nouvelle instance de la classe InputSource en l'initialisant avec un flux d'octets.
InputSource(Reader characterStream)
crée une nouvelle instance de la classe InputSource en l'initialisant avec un flux de carcatères.
InputSource(String systemId)
crée une nouvelle instance de la classe InputSource à partir d'un identificateur système.
Méthode
Description
InputStream getByteStream()
retourne le flux d'octets pour l'objet InputSource.
Reader getCharacterStream()
retourne le flux de caractères pour l'objet InputSource.
String getEncoding()
retourne l'encodage de caractères pour un flux d'octets ou une adresse URI.
String getPublicId()
retourne l'identificateur public de l'objet InputSource.
String getSystemId()
retourne l'identificateur système de l'objet InputSource.
void setByteStream(InputStream byteStream)
fixe le flux d'octets pour l'objet InputSource.
void setCharacterStream(Reader characterStream)
retourne le flux de caractères pour l'objet InputSource.
void setEncoding(String encoding)
fixe l'encodage de caractères.
void setPublicId(String publicId)
fixe l'identificateur public de l'objet InputSource.
void setSystemId(String systemId)
fixe l'identificateur système de l'objet InputSource.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

48.10 / Les caractéristiques et propriétés

Les caractéristiques permettent d'activer ou de désactiver des fonctionnalités spécifiques comme la prise en compte des espaces de noms ou la validation des documents XML.

Les propriétés fournissent des informations à propos du document XML, à l'instar du numéro de version XML ou la partie du document qui a produit l'évenement en cours.

Les caractéristiques et les propriétés sont accessibles et modifiables en les appelant par une URI. Les adresses URI sont le produit d'une concaténation de leur nom avec l'adresse http://xml.org/sax/(features|properties)/.

http://xml.org/sax/features/external-general-entities
http://xml.org/sax/features/namespaces
http://xml.org/sax/features/validation
http://xml.org/sax/properties/document-xml-version
http://xml.org/sax/properties/xml-string
CaractéristiqueMode d'accèsValeur par défaut
Description
external-general-entities Lecture/Ecriture non-spécifié
indique si l'analyseur doit traiter les entités générales externes. La valeur vaut toujours true si validating = true.
external-parameter-entities Lecture/Ecriture non-spécifié
indique si l'analyseur doit traiter les entités paramètres externes. La valeur vaut toujours true si validating = true.
is-standalone (analyse) Lecture seule, (pas d'analyse) none non-applicable
peut être examiné seulement durant une analyse et après le rappel de la méthode startDocument() (Lecture seule). La valeur est true si l'attribut standalone du prologue XML vaut yes.
lexical-handler/parameter-entities Lecture/Ecriture non-spécifié
indique que l'objet LexicalHandler rapportera le début et la fin des entités paramètres.
namespaces Lecture/Ecriture true
indique que les URI d'espaces de noms et les noms locaux non-préfixés pour les noms d'élément et d'attribut seront disponibles.
namespace-prefixes Lecture/Ecriture false
indique que les noms qualifiés (préfixe/nomLocal) et les attributs incluant les déclarations xmlns seront disponibles.
resolve-dtd-uris Lecture/Ecriture true
indique que les ID systèmes dans les déclarations seront convertis en URI absolues avant leur notification. Au contraire, les ID systèmes ne seront pas convertis, mais les analyseurs fourniraient l'URI de base à partir de la méthode Locator.getSystemId(). Cela s'applique aux ID systèmes passés dans les méthodes DTDHandler.notationDecl(), DTDHandler.unparsedEntityDecl(), et DeclHandler.externalEntityDecl()..
string-interning Lecture/Ecriture non-spécifié
possède une valeur true si tous les noms XML en plus des URI d'espace de noms auraient été assignées (interned) en utilisant Java. Ceci supporte des tests rapides d'égalité/inégalité sur des constantes textuelles plutôt que de forcer des appels plus lents à String.equals().
unicode-normalization-checking Lecture/Ecriture false
notifie les erreurs de normalisation Unicode avec la méthode ErrorHandler.error(). Ces erreurs ne sont pas fatales dans la plupart des cas.
use-attributes2 Lecture seule non-applicable
indique si les objets Attribute passés par l'analyseur dans la méthode ContentHandler.startElement() implémentent l'interface org.xml.sax.ext.Attributes2.
use-locator2 Lecture seule non-applicable
indique si les objets Locator passés par l'analyseur dans la méthode ContentHandler.setDocumentLocator(), implémentent l'interface org.xml.sax.ext.Locator2.
use-entity-resolver2 Lecture/Ecriture true
indique s'il est passé à la méthode setEntityResolver() un objet implémentant l'interface org.xml.sax.ext.EntityResolver2, ces nouvelles méthodes seront employées.
validation Lecture/Ecriture non-spécifié
indique si l'analyseur rapporte toutes les erreurs de validité. Si la valeur est true, toutes les entités externes seront lues.
xmlns-uris Lecture/Ecriture false
si la caractéristique namespace-prefixes est fixée, vérifie que l'analyseur traite les attributs de déclaration d'espace de noms comme étant dans l'espace de noms http://www.w3.org/2000/xmlns/. Par défaut, SAX 2 se conforme à la recommandation Namespaces in XML, laquelle déclare explicitement que les attributs ne sont dans aucun espace de noms.
xml-1.1 Lecture seule non-applicable
indique si l'analyseur supporte la version XML 1.1 (true) ou XML 1.0 (false).
PropriétésMode d'accès
Description
declaration-handlerLecture/Ecriture
utilisé pour voir la plupart des déclarations DTD, à l'exception de celles traitées lexicalement. L'objet doit implémenter org.xml.sax.ext.DeclHandler.
document-xml-versionLecture seule
fournit une chaîne de caractères décrivant la version XML ("1.0" ou "1.1").
dom-nodeLecture/Ecriture
est utilisé pour spécifier l'arborescence DOM exploitée par l'analyseur. L'objet doit implémenter l'interface org.w3c.dom.Node.
lexical-handlerLecture/Ecriture
utilisé pour voir certains événements de syntaxe essentiels pour certaines applications comme les commentaires, les délimiteurs de commentaires, de sections CDATA et de DTD. L'objet doit implémenter l'interface org.xml.sax.ext.LexicalHandler.
xml-stringLecture seule
expose la partie du document XML responsable de l'événement courant.

49 / Le paquetage org.xml.sax.helpers

Le paquetage org.xml.sax.helpers fournit des implémentations des interfaces du paquetage org.xml.sax.

Les classes de ce paquetage sont concrètes et constituent des implémentations directement exploitables par des applications SAX.

Classe Description
AttributeListImpl est dépréciée car elle implément l'interface AttributeList qui a été remplacée par Attributes, laquelle est implémentée par la classe AttributesImpl.
AttributesImpl fournit une implémentation pratique de l'interface Attributes.
DefaultHandler implémente les interfaces EntityResolver, DTDHandler, ContentHandler et ErrorHandler et constitue donc un gestionnaire d'événements SAX.
LocatorImpl fournit une implémentation pratique de l'interface Locator.
NamespaceSupport encapsule la logique d'espace de noms pour une utilisation par des applications SAX, ou en interne par les pilotes SAX.
ParserAdapter est une classe implémentant les interfaces Parser et ContentHandler. Elle constitue un analyseur SAX 1 couplé à un gestionnaire de contenu.
ParserFactory est dépréciée car elle a été remplacée par l'interface Parser.
XMLFilterImpl implémente les interfaces XMLFilter, EntityResolver, DTDHandler, ContentHandler et ErrorHandler et constitue donc un lecteur XML SAX couplé à des gestionnaires d'événements SAX.
XMLReaderAdapter est une classe implémentant les interfaces Parser et ContentHandler. Elle constitue donc un analyseur SAX 2 couplé à un gestionnaire de contenu.
XMLReaderFactory rerpésente une fabrique pour la création d'objets XMLReader.

49.1 / La classe AttributesImpl

La classe AttributesImpl implémente l'interface Attribute.

Un objet AttributesImpl constitue une implémentation par défaut chargée de gérer une liste d'attributs XML.

Constructeur
Description
AttributesImpl()
crée une nouvelle instance de la classe AttributesImpl.
AttributesImpl(Attributes atts)
crée une nouvelle instance de la classe AttributesImpl et l'initialise avec une liste d'attributs.
Méthode
Description
void addAttribute(
String uri, String localName, String qName, String type, String value)
ajoute un attribut à la fin de la liste.
void clear()
supprime tous les attributs de la liste.
int getIndex(String qName)
retourne l'index d'un attribut XML correspondant au nom qualifié spécifié.
int getIndex(String URIEspaceNoms, String localName)
retourne l'index d'un attribut XML correspondant au nom local spécifié et situé dans l'espace de noms précisé.
int getLength()
retourne le nombre d'attributs dans la liste.
String getLocalName(int index)
retourne le nom local d'un attribut positionné à l'index spécifié.
String getQName(int index)
retourne le nom qualifié d'un attribut positionné à l'index spécifié.
String getType(int index)
retourne le type d'un attribut positionné à l'index spécifié.
String getType(String qName)
retourne le type d'un attribut correspondant au nom qualifié spécifié.
String getType(String uri, String localName)
retourne le type d'un attribut correspondant au nom local spécifié et situé dans l'espace de noms précisé.
String getURI(int index)
retourne l'adresse URI d'espace de noms d'un attribut positionné à l'index spécifié.
String getValue(int index)
retourne la valeur d'un attribut positionné à l'index spécifié.
String getValue(String qName)
retourne la valeur d'un attribut correspondant au nom qualifié spécifié.
String getValue(String uri, String localName)
retourne la valeur d'un attribut correspondant au nom local spécifié et situé dans l'espace de noms précisé.
void removeAttribute(int index)
supprime l'attribut positionné à l'index spécifié.
void setAttribute(
int index, String uri, String localName, String qName, String type, String value)
ajoute un attribut dans la liste.
void setAttributes(Attributes atts)
copie les attributs de la collection spécifiée, à l'intérieur de la liste courante.
void setLocalName(int index, String localName)
assigne le nom local à un attribut situé à l'index spécifié.
void setQName(int index, String qName)
assigne le nom qualifié de l'attribut situé à l'index spécifié.
void setType(int index, String type)
assigne le type de l'attribut situé à l'index spécifié.
void setURI(int index, String uri)
assigne l'URI d'espace de noms de l'attribut situé à l'index spécifié.
void setValue(int index, String value)
assigne la valeur de l'attribut situé à l'index spécifié.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

49.2 / La classe DefaultHandler

La classe DefaultHandler implémente les interfaces EntityResolver, DTDHandler, ContentHandler et ErrorHandlerDefault.

Un objet DefaultHandler consitue une implémentation par défaut des gestionnaires d'événements pour le contenu, la DTD, les entités externes et les erreurs.

Constructeur
Description
DefaultHandler()
crée une nouvelle instance de la classe DefaultHandler.
Méthode
Description
void characters(char[] ch, int start, int length)
reçoit la notification de données textuelles à l'intérieur d'un élément XML.
void endDocument()
reçoit la notification de fin de document.
void endElement(String uri, String localName, String qName)
reçoit la notification de fin d'un élément.
void endPrefixMapping(String prefix)
reçoit la notification de fin de portée d'un préfixe et d'une adresse URI d'espace de noms.
void error(SAXParseException e)
reçoit la notification d'une erreur d'analyse récupérable.
void fatalError(SAXParseException e)
reçoit la notification d'une erreur d'analyse fatale.
void ignorableWhitespace(char[] ch, int start, int length)
reçoit la notification d'espaces blancs dans le contenu d'un élément.
void notationDecl(String name, String publicId, String systemId)
reçoit une notification de déclaration de notation.
void processingInstruction(String target, String data)
reçoit la notification d'instruction de traitement.
InputSource resolveEntity(String publicId, String systemId)
permet à l'application de résoudre des entités externes.
void setDocumentLocator(Locator locator)
reçoit un objet Locator fournissant l'emplacement d'un événement du document SAX.
void skippedEntity(String name)
reçoit la notification d'une entité ignorée.
void startDocument()
reçoit la notification de début d'un document.
void startElement(
String uri, String localName, String qName, Attributes attributes)
reçoit la notification du début d'un élément.
void startPrefixMapping(String prefix, String uri)
reçoit la notification de début de portée d'un préfixe et d'une adresse URI d'espace de noms.
void unparsedEntityDecl(
String name, String publicId, String systemId, String notationName)
reçoit la notification de la déclaration d'une entité non-analysée.
void warning(SAXParseException e)
reçoit la notification d'un avertissement de l'analyseur.
Méthodes héritées à partir de la classe java.lang.Objec.
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

49.3 / La classe LocatorImpl

La classe LocatorImpl implémente l'interface Locator. Elle fournit des informations à propos de l'emplacement d'une erreur qui serait survenue dans le document XML.

Constructeur
Description
LocatorImpl()
crée une nouvelle instance de la classe LocatorImpl.
LocatorImpl(Locator locator)
crée une nouvelle instance de la classe LocatorImpl et l'intialise avec l'objet Locator.
Méthode
Description
int getColumnNumber()
retourne le numéro de la colonne où l'événement du document courant s'achève.
int getLineNumber()
retourne le numéro de la ligne où l'événement du document courant s'achève.
String getPublicId()
retourne l'identificateur public pour l'événement du document courant s'achève.
String getSystemId()
retourne l'identificateur système pour l'événement du document courant s'achève.
void setColumnNumber(int columnNumber)
assigne le numéro de la colonne de l'événement du document courant.
void setLineNumber(int lineNumber)
assigne le numéro de la ligne de l'événement du document courant.
void setPublicId(String publicId)
retourne l'identificateur public de l'événement du document courant.
void setSystemId(String systemId)
retourne l'identificateur système de l'événement du document courant.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

49.4 / La classe NamespaceSupport

La classe NamespaceSupport encapsule la logique du traitement d'espaces de noms.

Champ
Description
static String NSDECL
représente l'URI de la déclaration d'espace de noms.
static String XMLNS
représente l'URI de l'espace de noms XML.
Constructeur
Description
NamespaceSupport()
crée une nouvelle instance de la classe NamespaceSupport.
Méthode
Description
boolean declarePrefix(String prefix, String uri)
indique si Declare a Namespace prefix.
Enumeration getDeclaredPrefixes()
retourne une énumération de tous les préfixes déclarés dans ce contexte.
String getPrefix(String uri)
retourne un des préfixes associés à l'adresse URI d'espaces de noms spécifiée.
Enumeration getPrefixes()
retourne une énumération de tous les préfixes dont les déclarations sont actives dans le contexte courant.
Enumeration getPrefixes(String uri)
retourne une énumération de tous les préfixes associés à l'URI d'espace de noms spécifiée, dont les déclarations sont actives dans le contexte courant.
String getURI(String prefix)
retourne l'adresse URI d'espace de noms associée au préfixe spécifié.
boolean isNamespaceDeclUris()
indique si les attributs de déclaration d'espace de noms sont placés dans un expace de noms.
void popContext()
etourne vers le précédent contexte d'espace de noms.
String[] processName(String qName, String[] parts, boolean isAttribute)
traite un nom qualifié brut, après que toutes les déclarations dans le contexte courant aient été gérées par la méthode declarePrefix().
void pushContext()
démarre un nouveau contexte d'espace de noms.
void reset()
réinitialise l'objet NamespaceSupport pour une réutilisation.
void setNamespaceDeclUris(boolean value)
indique si les attributs de déclaration d'espace de noms doivent être placés dans un espace de noms par la méthode processName().
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

49.5 / La classe ParserAdapter

La classe ParserAdapter implémente les interfaces DocumentHandler et XMLReader.

Elle constitue donc un analyseur XML couplé à un gestionnaire de contenu.

Constructeur
Description
ParserAdapter()
crée une nouvelle instance de la classe ParserAdapter.
ParserAdapter(Parser parser)
crée une nouvelle instance de la classe ParserAdapter en l'initialisant avec l'analyseur spécifié.
Méthode
Description
void characters(char[] ch, int start, int length)
reçoit la notification de données textuelles.
void endDocument()
reçoit la notification de fin de document.
void endElement(String uri, String localName, String qName)
reçoit la notification de fin d'un élément.
ContentHandler getContentHandler()
retourne le gestionnaire de contenu associé à cet objet.
DTDHandler getDTDHandler()
retourne le gestionnaire de DTD associé à cet objet.
EntityResolver getEntityResolver()
retourne le gestionnaire d'entités associé à cet objet.
ErrorHandler getErrorHandler()
retourne le gestionnaire d'erreurs associé à cet objet.
boolean getFeature(String name)
vérifie si une caractéristique spécifiée par son nom est activée.
Object getProperty(String name)
retourne la valeur de la propriété correspondant au nom spécifié.
void ignorableWhitespace(char[] ch, int start, int length)
reçoit la notification d'espaces blancs dans le contenu d'un élément.
void parse(InputSource input)
analyse un document contenu dans la source d'entrée.
void parse(String systemId)
analyse un document XML pointé par un identificateur système.
void processingInstruction(String target, String data)
reçoit la notification d'instruction de traitement.
void setContentHandler(ContentHandler handler)
assigne un gestionnaire de contenu.
void setDocumentLocator(Locator locator)
reçoit un objet Locator fournissant l'emplacement d'un événement du document SAX.
void setDTDHandler(DTDHandler handler)
assigne un gestionnaire de DTD.
void setEntityResolver(EntityResolver resolver)
assigne un gestionnaire d'entités.
void setErrorHandler(ErrorHandler handler)
assigne un gestionnaire d'erreurs.
void setFeature(String name, boolean value)
fixe la valeur de la caractéristique spécifiée par son nom.
void setProperty(String name, Object value)
assigne une valeur à la propriété correspondant au nom spécifié.
void startDocument()
reçoit la notification de début d'un document.
void startElement(String qName, AttributeList qAtts)
reçoit la notification du début d'un élément.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

49.6 / La classe XMLFilterImpl

La classe XMLFilterImpl implémente XMLFilter, EntityResolver, DTDHandler, ContentHandler et ErrorHandlerBase.

Cette classe constitue donc un analyseur XML couplé à un ensemble de gestionnaires d'événements SAX.

Constructeur
Description
XMLFilterImpl()
crée une nouvelle instance de la classe XMLFilter.
XMLFilterImpl(XMLReader parent)
crée une nouvelle instance de la classe XMLFilter en l'intialisant avec l'objet XMLReader spécifié.
Méthode
Description
void characters(char[] ch, int start, int length)
reçoit la notification de données textuelles.
void endDocument()
reçoit la notification de fin de document.
void endElement(String uri, String localName, String qName)
reçoit la notification de fin d'un élément.
void endPrefixMapping(String prefix)
reçoit la notification de fin de portée d'un préfixe et d'une adresse URI d'espace de noms.
void error(SAXParseException e)
reçoit la notification d'une erreur récupérable.
void fatalError(SAXParseException e)
reçoit la notification d'une erreur fatale.
ContentHandler getContentHandler()
retourne le gestionnaire de contenu associé à cet objet.
DTDHandler getDTDHandler()
retourne le gestionnaire de DTD associé à cet objet.
EntityResolver getEntityResolver()
retourne le gestionnaire d'entités associé à cet objet.
ErrorHandler getErrorHandler()
retourne le gestionnaire d'erreurs associé à cet objet.
boolean getFeature(String name)
vérifie si une caractéristique spécifiée par son nom est activée.
XMLReader getParent()
retourne l'objet XMLReader associé à cet objet.
Object getProperty(String name)
retourne la valeur de la propriété correspondant au nom spécifié.
void ignorableWhitespace(char[] ch, int start, int length)
reçoit la notification d'espaces blancs dans le contenu d'un élément.
void notationDecl(String name, String publicId, String systemId)
reçoit une notification de déclaration de notation.
void parse(InputSource input)
analyse un document contenu dans la source d'entrée.
void parse(String systemId)
analyse un document XML pointé par un identificateur système.
void processingInstruction(String target, String data)
reçoit la notification d'instruction de traitement.
InputSource resolveEntity(String publicId, String systemId)
permet à l'application de résoudre des entités externes.
void setContentHandler(ContentHandler handler)
assigne un gestionnaire de contenu.
void setDocumentLocator(Locator locator)
reçoit un objet Locator fournissant l'emplacement d'un événement du document SAX.
void setDTDHandler(DTDHandler handler)
assigne un gestionnaire de DTD.
void setEntityResolver(EntityResolver resolver)
assigne un gestionnaire d'entités.
void setErrorHandler(ErrorHandler handler)
assigne un gesstionnaire d'erreurs.
void setFeature(String name, boolean value)
fixe la valeur de la caractéristique spécifiée par son nom.
void setParent(XMLReader parent)
assigne un objet XMLReader à l'objet courant.
void setProperty(String name, Object value)
assigne une valeur à la propriété correspondant au nom spécifié.
void skippedEntity(String name)
reçoit la notification d'une entité ignorée.
void startDocument()
reçoit la notification de début d'un document.
void startElement(
String uri, String localName, String qName, Attributes atts)
reçoit la notification du début d'un élément.
void startPrefixMapping(String prefix, String uri)
reçoit la notification de début de portée d'un préfixe et d'une adresse URI d'espace de noms.
void unparsedEntityDecl(
String name, String publicId, String systemId, String notationName)
reçoit la notification de la déclaration d'une entité non-analysée.
void warning(SAXParseException e)
reçoit la notification d'un avertissement de l'analyseur.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

49.7 / La classe XMLReaderAdapter

La classe XMLReaderAdapter adapte un lecteur XML SAX 2 en un analyseur SAX 1.

Constructeur
Description
XMLReaderAdapter()
crée une nouvelle instance de la classe XMLReaderAdapter.
XMLReaderAdapter(XMLReader xmlReader)
crée une nouvelle instance de la classe XMLReaderAdapter en l'initialisant avec un objet XMLReader.
Méthode
Description
void characters(char[] ch, int start, int length)
reçoit la notification de données textuelles.
void endDocument()
reçoit la notification de fin de document.
void endElement(String uri, String localName, String qName)
reçoit la notification de fin d'un élément.
void endPrefixMapping(String prefix)
reçoit la notification de fin de portée d'un préfixe et d'une adresse URI d'espace de noms.
void ignorableWhitespace(char[] ch, int start, int length)
reçoit la notification d'espaces blancs dans le contenu d'un élément.
void parse(InputSource input)
analyse le document pointé par la source d'entrée spécifiée.
void parse(String systemId)
analyse le document pointé par l'identificateur système spécifié.
void processingInstruction(String target, String data)
reçoit la notification d'instruction de traitement.
void setDocumentHandler(DocumentHandler handler)
assigne un gestionnaire de document.
void setDocumentLocator(Locator locator)
reçoit un objet Locator fournissant l'emplacement d'un événement du document SAX.
void setDTDHandler(DTDHandler handler)
assigne un gestionnaire de DTD.
void setEntityResolver(EntityResolver resolver)
assigne un gestionnaire d'entités.
void setErrorHandler(ErrorHandler handler)
assigne un gestionnaire d'erreurs.
void setLocale(Locale locale)
assigne un objet Locale pour le compte rendu d'erreurs.
void skippedEntity(String name)
reçoit la notification d'une entité ignorée.
void startDocument()
reçoit la notification de début d'un document.
void startElement(String uri, String localName, String qName, Attributes atts)
reçoit la notification du début d'un élément.
void startPrefixMapping(String prefix, String uri)
reçoit la notification de début de portée d'un préfixe et d'une adresse URI d'espace de noms.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

49.8 / La classe XMLReaderFactory

La classe XMLReaderFactory représente une fabrique d'objets XMLReader.

Cette classe contient deux méthodes statiques chargées de créer des lecteurs XML à partir des paramètres systèmes par défaut ou d'un nom de classe explicite.

Méthode
Description
static XMLReader createXMLReader()
essaie de créer un objet XMLReader à partir des paramètres par défaut du système.
static XMLReader createXMLReader(String className)
essaie de créer un objet XMLReader à partir d'un nom de classe.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

50 / Le paquetage org.xml.sax.ext

Le paquetage org.xml.sax.ext introduit de nouvelles fonctionnalités SAX 2.

Ce paquetage est indépendant des interfaces et classes principales SAX 2, bien que les fonctionnalités exposées nécessitent généralement d'êre implémentées au coeur d'un analyseur SAX.

Cette indépendance a plusieurs conséquences :

Ce paquetage est une extension standardisée de SAX 2. Il est conçu pour permettre à des analyseurs SAX de passer certains types d'information aux applications, et de servir de modèle simple pour d'autres paquetages d'extension de d'analyseur SAX2. Aucun paquetages d'extension ne devraient être identifiés directement par des analyseurs. Par exemple, la plupart des systèmes de validation peuvent être proprement posés sur des analyseurs supportant les interfaces SAX2 normalisées.

Interface Description
Attributes2 est une extension SAX2 pour fournir des informations supplémentaires à propos des attributs.
DeclHandler est une extension SAX 2 pour améliorer le fonctionnement du gestionnaire d'événements de déclaration de DTD.
EntityResolver2 étend l'interface EntityResolver l'association des références d'entité externe aux sources d'entrée ou pour fournir un sous-ensemble externe pour les documents qui n'en ont pas défini.
LexicalHandler est une extension SAX2 pour la gestion d'événements lexicaux, comme des délimiteurs de DTD ou de sections CDATA.
Locator2 étend l'interface Locator pour ajouter de nouvelles fonctionnalités, comme l'obtention de l'encodage et de la versin XML d'une entité.
Classe Description
Attributes2Impl est une implémentation des interfaces Attributes et Attributes2.
DefaultHandler2 représente un gestionnaire d'événements SAX supportant les extensions introduites par les interfaces LexicalHandler, DeclHandler, et EntityResolver2.
Locator2Impl étend la classe LocatorImpl et ajoute de nouvelles fonctionnalités introduites par l'interface Locator2.

50.1 / L'interface Attributes2

L'interface Attributes2 étend l'interface Attribute et ajoute la possibilité d'obtenir des informations supplémentaires à propos des attributs XML.

Cette interface permet de connaître l'état de la déclaration d'un attribut au sein d'une DTD.

Si une implémentation supporte cette extension, les attributs fournis dans la méthode ContentHandler.startElement() devront implémenter cette interface et la propriété http://xml.org/sax/features/use-attributes2 devra être activée.

Méthode
Description
boolean isDeclared(int index)
indique si l'attribut situé à l'index spécifié a été déclaré dans la DTD.
boolean isDeclared(String qName)
indique si l'attribut correspondant au nom qualifié spécifié a été déclaré dans la DTD.
boolean isDeclared(String uri, String localName)
indique si l'attribut correspondant au nom local spécifié et situé dans l'espace de noms indiqué, a été déclaré dans la DTD.
boolean isSpecified(int index)
indique si la valeur de l'attribut positionné à l'index spécifié, ne possède pas une valeur par défaut exprimé dans la DTD.
boolean isSpecified(String qName)
indique si la valeur de l'attribut correspondant au nom qualifié spécifié, ne possède pas une valeur par défaut exprimé dans la DTD.
boolean isSpecified(String uri, String localName)
indique si la valeur de l'attribut correspondant au nom local spécifié et situé dans l'espace de noms indiqué, ne possède pas une valeur par défaut exprimé dans la DTD.
Méthodes héritées à partir de l'interface org.xml.sax.Attribute2
getIndex, getIndex, getLength, getLocalName, getQName,
getType, getType, getType, getURI, getValue, getValue, getValue

50.2 / L'interface DeclHandler

L'interface DeclHandler permet d'étendre les fonctionnalités pour la gestion d'événement de DTD.

Cette interface a la charge de gérer les déclarations d'éléments et d'attributs au sein de la DTD, et également les déclarations d'entités internes et externes.

Méthode
Description
void attributeDecl(
String eName, String aName, String type, String mode, String value)
rapporte une déclaration de type d'attribut.
void elementDecl(String name, String model)
rapporte une déclaration de type d'élément.
void externalEntityDecl(String name, String publicId, String systemId)
rapporte une déclaration d'entité externe analysée.
void internalEntityDecl(String name, String value)
rapporte une déclaration d'entité interne.

50.3 / L'interface EntityResolver2

L'interface EntityResolver2 étend l'interface EntityResolver pour ajouter un dispositif d'association d'entité externe à des sources d'entrée et pour fournir un sous-ensemble externe pour les documents n'en n'ayant défini aucun.

Méthode
Description
InputSource getExternalSubset(String name, String baseURI)
permet aux applications de fournir un sous-ensemble externe pour les documents qui n'en ont pas défini un explicitement.
InputSource resolveEntity(
String name, String publicId, String baseURI, String systemId)
permet aux applications d'associer des références d'entité externe à des sources d'entrée, ou d'indiquer à l'analyseur qu'il devrait utiliser la résolution d'adresse URI conventionnelle.
Méthodes héritées à partir de l'interface org.xml.sax.EntityResolver
resolveEntity

50.4 / L'interface LexicalHandler

L'interface LexicalHandler fournit des informations lexicales à propos du document XML.

Cette interface permet d'accomplir des traitements particuliers, lorsque des limites de DTD, de sections CDATA ou d'entités sont atteintes. Les commentaires sont également gérés par cette interface.

Méthode
Description
void comment(char[] ch, int start, int length)
rapporte un commentaire XML n'importe où dans le document.
void endCDATA()
rapporte la fin des sections CDATA.
void endDTD()
rapporte la fin des déclarations DTD.
void endEntity(String name)
rapporte la fin de certaines entités XML externes ou internes.
void startCDATA()
rapporte le début des sections CDATA.
void startDTD(String name, String publicId, String systemId)
rapporte le début des déclarations DTD.
void startEntity(String name)
rapporte le début de certaines entités XML externes ou internes.

50.5 / L'interface Locator2

L'interface Locator2 ajoute deux nouvelles méthodes permettant d'obtenir des informations à propos de l'encodage de caractères et de la version XML.

Méthode
Description
String getEncoding()
retourne l'encodage de caractères pour l'entité.
String getXMLVersion()
retourne la version XML utilisée pour l'entité.
Méthodes héritées à partir de l'interface org.xml.sax.Locator
getColumnNumber, getLineNumber, getPublicId, getSystemId

50.6 / La classe Attributes2Impl

La classe Attributes2Impl implémente les interfaces Attributes et Attributes2. Elle améliore donc le fonctionnement de la classe AttributesImpl du paquetage org.xml.sax en prenant en compte de nouvelles fonctionnalités notamment à propos de l'état de la déclaration des attributs au sein de la DTD.

Constructeur
Description
Attributes2Impl()
crée une nouvelle instance de la classe Attributes2Impl.
Attributes2Impl(Attributes atts)
crée une nouvelle instance de la classe Attributes2Impl en l'initialisant avec la collection Attributes.
Méthode
Description
void addAttribute(
String uri, String localName, String qName, String type, String value)
ajoute un attribut à la fin de la liste en l'initialisant avec les valeurs spécifiées.
boolean isDeclared(int index)
indique si l'attribut situé à l'index spécifié a été déclaré dans la DTD.
boolean isDeclared(String qName)
indique si l'attribut correspondant au nom qualifié spécifié a été déclaré dans la DTD.
boolean isDeclared(String uri, String localName)
indique si l'attribut correspondant au nom local spécifié et situé dans l'espace de noms indiqué, a été déclaré dans la DTD.
boolean isSpecified(int index)
indique si la valeur de l'attribut positionné à l'index spécifié, ne possède pas une valeur par défaut exprimé dans la DTD.
boolean isSpecified(String qName)
indique si la valeur de l'attribut correspondant au nom qualifié spécifié, ne possède pas une valeur par défaut exprimé dans la DTD.
boolean isSpecified(String uri, String localName)
indique si la valeur de l'attribut correspondant au nom local spécifié et situé dans l'espace de noms indiqué, ne possède pas une valeur par défaut exprimé dans la DTD.
void removeAttribute(int index)
supprime l'attribut positionné à l'index spécifié.
void setAttributes(Attributes atts)
copie une liste d'attributs au sein de la collection courante.
void setDeclared(int index, boolean value)
indique si l'attribut positionné à l'index spécifié, est (true) ou n'est pas (false) déclaré dans la DTD.
void setSpecified(int index, boolean value)
indique si l'attribut positionné à l'index spécifié, possède (false) ou ne possède (true) pas de valeur par défaut déclarée dans la DTD.
Méthodes héritées à partir de la classe org.xml.sax.helpers.AttributesImpl
clear, getIndex, getIndex, getLength, getLocalName, getQName,
getType, getType, getType, getURI, getValue, getValue, getValue, setAttribute,
setLocalName, setQName, setType, setURI, setValu.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait
Méthodes héritées à partir de l'interface org.xml.sax.Attribute2
getIndex, getIndex, getLength, getLocalName, getQName,
getType, getType, getType, getURI, getValue, getValue, getValue

50.7 / La classe DefaultHandler2

La classe DefaultHandler2 est un gestionnaire d'événements SAX qui prend en compte les nouvelles fonctionnalités introduites par les interfaces DeclHandler, EntityResolver2 et LexicalHandler.

Constructeur
Description
DefaultHandler2()
crée une nouvelle instance de la classe DefaultHandler2.
Méthode
Description
void attributeDecl(
String eName, String aName, String type, String mode, String value)
rapporte une déclaration de type d'attribut.
void comment(char[] ch, int start, int length)
rapporte un commentaire XML n'importe où dans le document.
void elementDecl(String name, String model)
rapporte une déclaration de type d'élément.
void endCDATA()
rapporte la fin des sections CDATA.
void endDTD()
rapporte la fin des déclarations DTD.
void endEntity(String name)
rapporte la fin de certaines entités XML externes ou internes.
void externalEntityDecl(String name, String publicId, String systemId)
rapporte une déclaration d'entité externe analysée.
InputSource getExternalSubset(String name, String baseURI)
permet aux applications de fournir un sous-ensemble externe pour les documents qui n'en ont pas défini un explicitement.
void internalEntityDecl(String name, String value)
rapporte une déclaration d'entité interne.
InputSource resolveEntity(String publicId, String systemId)
invoque la méthode EntityResolver2.resolveEntity() with null entity name and base URI.
InputSource resolveEntity(
String name, String publicId, String baseURI, String systemId)
permet aux applications d'associer des références d'entité externe à des sources d'entrée, ou d'indiquer à l'analyseur qu'il devrait utiliser la résolution d'adresse URI conventionnelle.
void startCDATA()
rapporte le début des sections CDATA.
void startDTD(String name, String publicId, String systemId)
rapporte le début des déclarations DTD.
void startEntity(String name)
rapporte le début de certaines entités XML externes ou internes.
Méthodes héritées à partir de la classe org.xml.sax.helpers.DefaultHandler
characters, endDocument, endElement, endPrefixMapping, error,
fatalError, ignorableWhitespace, notationDecl, processingInstruction,
setDocumentLocator, skippedEntity, startDocument, startElement,
startPrefixMapping, unparsedEntityDecl, warning
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

50.8 / La classe Locator2Impl

La classe Locator2Impl implémente l'interface Locator2, extension de SAX 2, pour gérer des informations supplémentaires sur les entités.

Constructeur
Description
Locator2Impl()
crée un nouvelle instance de la classe Locator2Impl.
Locator2Impl(Locator locator)
crée un nouvelle instance de la classe Locator2Impl et l'initialise avec l'objet Locator spécifié.
Méthode
Description
String getEncoding()
retourne la valeur courante de la propriété d'encodage.
String getXMLVersion()
retourne la valeur courante de la propriété de version XML.
void setEncoding(String encoding)
affecte un encodage à la prorpiété encoding.
void setXMLVersion(String version)
affecte un encodage à la prorpiété version.
Méthodes héritées à partir de la classe org.xml.sax.helpers.LocatorImpl
getColumnNumber, getLineNumber, getPublicId, getSystemId,
setColumnNumber, setLineNumber, setPublicId, setSystemId
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.
Méthodes héritées à partir de l'interface org.xml.sax.Locator
getColumnNumber, getLineNumber, getPublicId, getSystemId

51 / Le paquetage com.sun.java.browser.dom

Le paquetage com.sun.java.browser.dom propose des interfaces et des classes pour l'exécution d'opérations DOM au sein de threads

Interface Description
DOMAccessor Les objets implémentant cette interface doivent retourner un noeud DOM Document (Document getDocument(Object obj)) et une implémentation DOM DOMImplementation (DOMImplementation getDOMImplementation()).
DOMAction comporte une méthode Object run(DOMAccessor accessor) qui est destinée à être appelée par un thread DOM. Un objet implémentant cette interface doit être passée à l'une des méthodes invokeAndWait() ou invokeLater() de la classe DOMService.
Classe Description
DOMService fournit des méthodes capables d'exécuter de façon synchrone ou asynchrone des objets DOMAction.
DOMServiceProvider représente un fournisseur de services qui sera utilisé par les méthodes appropriées d'un objet DOMService.
Exception Description
DOMAccessException est lancée lorsqu'une erreur se produit dans un thread DOM initiée par les méthodes invokeAndWait() et invokeLater() de la classe DOMService.
DOMUnsupportedException est lancée si un objet non-supportée est utilisé avec les méthode DOMServiceProvider.getDocument() et DOMService.getService().
import netscape.javascript.*;
import java.applet.*;
import java.awt.*;
public class UnApplet extends Applet {
  public void init() {
    JSObject win = JSObject.getWindow(this);
    JSObject doc = (JSObject) win.getMember("document");
    JSObject loc = (JSObject) doc.getMember("location");

    String s = (String) loc.getMember("href");
    win.call("uneFonction", new String[]{"Un message personnel..."});
  }
  public String getTitle(){
    DOMService service = null;
    String title = null;
    try{
      service = DOMService.getService(this);

      title = (String) service.invokeAndWait(new DOMAction(){
        public Object run(DOMAccessor accessor){
          HTMLDocument doc = (HTMLDocument) accessor.getDocument(this);
          return doc.getTitle();
        }
      });
    }
    catch (DOMUnsupportedException e){
      e.printStackTrace();
    }
    catch (DOMAccessException e){
      e.printStackTrace();
    }
    return title;
  }
}

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Date de création: 25/08/2005 -->
  <head>
  <title>Une page Web</title>
  <script language="Javascript" type="text/javascript">
    unFonction(msg){
      alert(msg);
    }
  </script>
  </head>
  <body>
     <object 
        classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
        width="200" height="200" align="baseline">
       <param name="code" value="UnApplet.class">
       <param name="codebase" value="html/">
       <param name="type" 
                 value="application/x-java-applet;jpi-version=1.5.0">
       <param name="MAYSCRIPT" value="true">
         Les applets ne sont pas supportés !
     </object>
  </body>
</html>

51.1 / La classe DOMService

La classe abstraite DOMService fournit des méthodes capables d'exécuter de façon synchrone ou asynchrone des objets DOMAction au sein de threads.

Constructeur
Description
DOMService()
crée une nouvelle instance vide de la classe DOMService.
Méthode
Description
static DOMService getService(Object obj)
retourne une nouvelle instance de la classe DOMService en s'appuyant les propriétés d'un objet DOMServiceProvider.
abstract Object invokeAndWait(DOMAction action)
provoque l'exécution synchrone de l'objet DOMAction spécifié.
abstract void invokeLater(DOMAction action)
provoque l'éxécution asynchrone de l'objet DOMAction spécifié.
Méthodes héritées à partir de la classe java.lang.Objec
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

51.2 / La classe DOMServiceProvider

La classe abstraite DOMServiceProvider représente un fournisseur de services qui sera utilisé par les méthodes appropriées d'un objet DOMService.

Constructeur
Description
DOMServiceProvider()
crée une nouvelle instance vide de la classe DOMServiceProvider.
Méthode
Description
abstract boolean canHandle(Object obj)
indique si l'objet DOMService peut déterminer l'association entre l'bjet et le modèle d'objet de document sous-jacent dans le navigateur.
abstract Document getDocument(Object obj)
retourne un objet DOM Document en fonction de l'objet spécifié.
abstract DOMImplementation getDOMImplementation()
retourne une implémentation DOM.
Méthodes héritées à partir de la classe java.lang.Objec
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

52 / Le paquetage javax.xml

Le paquetage javax.xml définit les principales constantes XML et les fonctionnalités à partir des spécifications XML du W3C.

Classe Description
XMLConstants contient des valeurs de bases XML sous la forme de constantes.

52.1 / La classe XMLConstants

La classe XMLConstants définit plusieurs constantes XML utilisables par l'API XML.

Champ
Description
static String DEFAULT_NS_PREFIX ( = "")
représente le préfixe utilisé pour représenter l'espace de noms XML par défaut.
static String FEATURE_SECURE_PROCESSING ( = "http://javax.xml.XMLConstants/feature/secure-processing")
représente la caractéristique pour le traitement sûr.
static String NULL_NS_URI ( = "")
constitue l'URI d'espace de noms utilisé pour représenter qu'il n'y a pas d'espace de noms.
static String RELAXNG_NS_URI ( = "http://relaxng.org/ns/structure/1.0")
représente l'URI d'espace de noms pour le langage de schéma Relax NG.
static String W3C_XML_SCHEMA_INSTANCE_NS_URI ( = "http://www.w3.org/2001/XMLSchema-instance")
rerpésente l'URI d'espace de noms pour W3C XML Schema Instance.
static String W3C_XML_SCHEMA_NS_URI ( = "http://www.w3.org/2001/XMLSchema")
représente l'URI d'espace de noms pour le langage de schéma du W3C.
static String W3C_XPATH_DATATYPE_NS_URI ( = "http://www.w3.org/2003/11/xpath-datatypes")
représente l'URI d'espace de noms pour les types de données XPath du W3C.
static String XML_DTD_NS_URI ( = "http://www.w3.org/TR/REC-xml")
représente l'URI d'espace de noms pour la déclaration de type de document XML.
static String XML_NS_PREFIX ( = "xml")
représente le préfixe d'espace de noms XML officiel.
static String XML_NS_URI ( = "http://www.w3.org/XML/1998/namespace")
représente l'URI d'espace de noms XML officiel.
static String XMLNS_ATTRIBUTE ( = "xmlns")
représente l'attribut officiel utilisé pour la déclaration d'espaces de noms..
static String XMLNS_ATTRIBUTE_NS_URI ( = "http://www.w3.org/2000/xmlns/")
représente l'attribut XML officiel utilisé pour spécifier les déclarations d'espaces de noms XML, XMLNS_ATTRIBUTE et XML_NS_URI.

53 / Le paquetage javax.xml.parsers

Le paquetage javax.xml.parsers fournit des classes permettant d'analyser des documents XML selon les techniques DOM (Document Object Model) et SAX (Simple API for XML).

Les classes produisent deux types d'analyseurs XML

Classe Description
DocumentBuilder définit l'API pour obtenir des instances de document DOM à partir d'un document XML.
DocumentBuilderFactory définit un fabricateur d'API qu'active les applications pour obtenir un analyseur qui produit une arborescence d'objets DOM à partir de document XML.
SAXParser définit l'API qu'active les applications pour obtenir un analyseur SAX chargé de traiter les documents XML.
SAXParserFactory définit un fabricateur d'API qu'active les applications pour obtenir un analyseur SAX chargé de traiter les documents XML.
Exception Description
ParserConfigurationException indique une erreur de configuration sérieuse.
Erreur Description
FactoryConfigurationError se produit lorsqu'un problème de configuration survient avec les fabricateurs d'analyseur.

53.1 / La classe DocumentBuilder

La classe abstraite DocumentBuilder définit l'API pour obtenir des objets Document du paquetage org.w3c.dom à partir de documents XML.

Une instance de cette classe peut être obtenue à partir de la méthode de classe DocumentBuilderFactory.newDocumentBuilder(). Une fois qu'une instance de cette classe est obtenue, XML peut être analysé à partir d'une variété de sources d'entrée. Ces dernières sont des flux InputStream, des fichiers, des adresses URL et des sources SAX.

La classe DocumentBuilder réutilise plusieurs classes de l'API SAX. Ceci ne requiert pas que l'implementeur de l'implémentation DOM sous-jacente utilise uh analyseur SAX pour analyser des ocucments XML dans un objet org.w3c.dom.Document. Il demande simplement que l'implémentation comunique avec l'implémentation utilisant ces APIs existantes.

Constructeur
Description
protected DocumentBuilder()
créeune nouvelle instance de la classe DocumentBuilder. Ce constructeur est protégé.
Méthode
Description
abstract DOMImplementation getDOMImplementation()
obtient une instance de la classe DOMImplementation.
Schema getSchema()
retourne une référence au shéma utilisé par le processeur XML.
abstract boolean isNamespaceAware()
indique si l'analyseur est configuré pour prendre en compte les espaces de noms.
abstract boolean isValidating()
indique si l'analyseur est configuré pour valider les documents XML.
boolean isXIncludeAware()
indique si le mode de traitement pour les inclusions XML est activé pour l'analyseur.
abstract Document newDocument()
retourne une nouvelle instance de la classe Document du paquetage org.w3c.dom.
Document parse(File fichier)
analyse le contenu du fichier spécifié comme un document XML et retourne un objet Document.
abstract Document parse(InputSource source)
analyse le contenu de la source spécifiée comme un document XML et retourne un objet Document.
Document parse(InputStream flux)
analyse le contenu du flux spécifié comme un document XML et retourne un objet Document.
Document parse(InputStream source, String IDSysteme)
analyse le contenu du flux spécifié comme un document XML et retourne un objet Document. Le paramètre IDSysteme constitue une base pour résoudre les adresses URI relatives.
Document parse(String uri)
analyse le contenu de l'adresse URI spécifiée comme un document XML et retourne un objet Document.
void reset()
réinitialise l'objet DocumentBuilder à sa configuration initiale.
abstract void setEntityResolver(EntityResolver er)
spécifie l'objet EntityResolver devant être utilisé pour résoudre les entités présentes dans le document XML à analyser.
abstract void setErrorHandler(ErrorHandler eh)
spécifie l'objet ErrorHandler devant être utilisé durant l'analyse pour gérer les erreurs.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

53.2 / La classe DocumentBuilderFactory

La classe abstraite DocumentBuilderFactory définit une fabrique d'API qui permet à des applications d'obtenir un analyseur qui produit des arborescences d'objet du DOM à partir des documents de XML.

Constructeur
Description
protected DocumentBuilderFactory()
crée une nouvelle instance de la classe DocumentBuilderFactory. Ce constructeur est protégé.
Méthode
Description
abstract Object getAttribute(String name)
retourne les attributs correspondant au nom spécifié, sur l'implémentation sous-jacente.
abstract boolean getFeature(String name)
indique l'état de la caractéristique spécifiée par son nom.
Schema getSchema()
retourne l'objet Schema qui a été fixé par la méthode setSchema().
boolean isCoalescing()
indique si la fabrique est configurée pour produire des analyseurs qui convertissent des noeuds CDATASection en noeuds Text et les ajoutent s'ils sont adjacents.
boolean isExpandEntityReferences()
indique si la fabrique est configurée pour produire des analyseurs qui développent les références d'entité.
boolean isIgnoringComments()
indique si la fabrique est configurée pour produire des analyseurs qui ignorent les commentaires.
boolean isIgnoringElementContentWhitespace()
indique si la fabrique est configurée pour produire des analyseurs qui ignorent les espaces blancs dans le contenu d'un élément.
boolean isNamespaceAware()
indique si la fabrique est configurée pour produire des analyseurs qui prennent en compte les espaces de noms.
boolean isValidating()
indique si la fabrique est configurée pour produire des analyseurs qui valident le contenu XML durant l'analyse.
boolean isXIncludeAware()
indique l'état du traitement des inclusions XML (XInclude).
abstract DocumentBuilder newDocumentBuilder()
crée une nouvelle instance de la classe DocumentBuilder utilisant la configuration courante.
static DocumentBuilderFactory newInstance()
retourne une nouvelle instance de la classe DocumentBuilderFactory.
abstract void setAttribute(String name, Object value)
fixe la valeur d'un attribut de l'implémentation sous-jacente.
void setCoalescing(boolean coalescing)
détermine si l'analyseur doit convertir des noeuds CDATASection en noeud Text et les ajouter s'ils sont adjacents.
void setExpandEntityReferences(boolean expandEntityRef)
détermine si l'analyseur doit développer les références d'entité.
abstract void setFeature(String name, boolean value)
détermine une caractéristique pour les objets DocumentBuilderFactory et DocumentBuilder créés par la fabrique courante.
void setIgnoringComments(boolean ignoreComments)
détermine si l'analyseur doit ignorer les commentaires.
void setIgnoringElementContentWhitespace(boolean whitespace)
détermine si l'analyseur doit ignorer les espaces blancs contenus dans les éléments.
void setNamespaceAware(boolean awareness)
détermine si l'analyseur doit prendre en compte les espaces de noms XML.
void setSchema(Schema schema)
désigne le schéma utilisé par les analyseurs créés par la fabrique courante.
void setValidating(boolean validating)
détermine si l'analyseur doit valider les documents XML lors de leur analyse.
void setXIncludeAware(boolean state)
fixe l'état du traitement des inclusions XML (XInclude).
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

53.3 / La classe SAXParser

La classe abstraite SAXParser englobe une implémentation de la classe XMLReader.

En JAXP 1.0, cette classe englobe l'interface Parser. Toutefois, cette interface a été remplacée par XMLReader. Pour une trnasition facile, la classe SAXParser continue de s'appuyer sur le même nom et interface en plus de supporter de nouvelles méthodes. Une instance de cette classe peut être obtenue à partir de la méthode SAXParserFactory.newSAXParser(). Un fois qu'une instance est obtenue, XML peut être analysé à partir d'une variété de sources d'entrée, telles que des flux InputStream, des fichiers, des adresses URL et des sources SAX.

La méthode statique SAXParserFactory.newSAXParser() crée une nouvelle instance de fabrique basée sur le paramètrage des propriétés ou utilise les propriétés définies par défaut de la plateforme sous-jacente.

La classe DefaulHandler utilisée par des méthodes d'analyse, est contenu dans le paquetage org.xml.sax.helpers. Elle foournit une implémentation par défaut pour les gestionnaires SAX, en l'occurrence EntityResolver, DTDHandler, ContentHandler et ErrorHandler.

Constructeur
Description
protected SAXParser()
crée une nouvelle instance de la classe SAXParser. Ce constructeur est protégé.
Méthode
Description
abstract Parser getParser()
retourne un analyseur SAX qui est encapsulé par l'implémentation de cette classe.
abstract Object getProperty(String name)
retourne la propriété correspondant au nom spécifié.
Schema getSchema()
retourne une référence au schéma utilisé par le processeur XML.
abstract XMLReader getXMLReader()
retourne un objet XMLReader qui est encapsulé par l'implémentation de cette classe.
abstract boolean isNamespaceAware()
indique si la fabrique est configurée pour produire des analyseurs qui prennent en compte les espaces de noms.
abstract boolean isValidating()
indique si la fabrique est configurée pour produire des analyseurs qui valident le contenu XML durant l'analyse.
boolean isXIncludeAware()
indique l'état du traitement des inclusions XML (XInclude).
void parse(File fichier, DefaultHandler gestionnaire)
analyse le contenu du fichier en utilisant le gestionnaire spécifié.
void parse(File f, HandlerBase hb)
Dépréciée car la classe org.xml.sax.HandlerBase est dépréciée.
void parse(InputSource is, DefaultHandler dh)
analyse le contenu de l'objet InputSource en utilisant le gestionnaire spécifié.
void parse(InputSource is, HandlerBase hb)
Dépréciée car la classe org.xml.sax.HandlerBase est dépréciée.
void parse(InputStream is, DefaultHandler dh)
analyse le contenu du flux InputStream en utilisant le gestionnaire spécifié.
void parse(InputStream is, DefaultHandler dh, String systemId)
analyse le contenu du flux InputStream en utilisant le gestionnaire spécifié. Le paramètre IDSysteme constitue une base pour résoudre les adresses URI relatives.
void parse(InputStream is, HandlerBase hb)
Dépréciée car la classe org.xml.sax.HandlerBase est dépréciée.
void parse(InputStream is, HandlerBase hb, String systemId)
Dépréciée car la classe org.xml.sax.HandlerBase est dépréciée.
void parse(String uri, DefaultHandler dh)
analyse le contenu de l'adresse URI en utilisant le gestionnaire spécifié.
void parse(String uri, HandlerBase hb)
Dépréciée car la classe org.xml.sax.HandlerBase est dépréciée.
void reset()
réinitialise l'objet SAXParser à sa configration initiale.
abstract void setProperty(String name, Object value)
fixe la valeur de la propriété spécifiée.
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

53.4 / La classe SAXParserFactory

La classe abstraite SAXParserFactory définit une fabrique d'API qui permet à des applications de configurer et d'obtenir un analyseur SAX pour traiter des documents de XML.

Constructeur
Description
protected SAXParserFactory()
crée une nouvelle instance de la classe SAXParserFactory. Ce constructeur est protégé.
Méthode
Description
abstract boolean getFeature(String name)
retourne les attributs correspondant au nom spécifié, sur l'implémentation org.xml.sax.XMLReader.
Schema getSchema()
retourne l'objet Schema qui a été fixé par la méthode setSchema().
boolean isNamespaceAware()
indique si la fabrique est configurée pour produire des analyseurs qui prennent en compte les espaces de noms.
boolean isValidating()
indique si la fabrique est configurée pour produire des analyseurs qui valident le contenu XML durant l'analyse.
boolean isXIncludeAware()
indique l'état du traitement des inclusions XML (XInclude).
static SAXParserFactory newInstance()
retourne une nouvelle instance de la classe SAXParserFactory.
abstract SAXParser newSAXParser()
retourne une nouvelle instance de la classe SAXParser en utilisant la configuration courante.
abstract void setFeature(String name, boolean value)
détermine une caractéristique pour l'objet org.xml.sax.XMLReader.
void setNamespaceAware(boolean awareness)
détermine si l'analyseur doit prendre en compte les espaces de noms XML.
void setSchema(Schema schema)
désigne le schéma utilisé par les analyseurs créés par la fabrique courante.
void setValidating(boolean validating)
détermine si l'analyseur doit valider les documents XML lors de leur analyse.
void setXIncludeAware(boolean state)
fixe l'état du traitement des inclusions XML (XInclude).
Les méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

54 / Le paquetage javax.xml.transform

Le paquetage javax.xml.transform définit des API génériques pour traiter des instructions de transformation et exécuter des transformations XSLT à partir de sources XML et XSL afin d'obtenir un résultat.

Ces interfaces n'ont aucunes dépendances avec les standards SAX ou DOM, et essaie de faire quelques suppositions si possible à propos des détails de la source et du résultat de transformation. Elle réalise ceci en définissant des interfaces Source et Result.

Pour définir des classes concrètes pour l'utilisateur, l'API définit des spécialisations des interfaces trouvées au niveau racine. Ces interfaces se situent dans les sous-paquetages sax, dom, et stream du paquetage javax.xml.transform.

Interface Description
ErrorListener représente un gestionnaire d'erreurs personnalisable.
Result représente un objet résultant d'un processus de transformation.
Source représente une source d'entrée XML ou XSLT qui concourra à fournir un résultat de transformation.
SourceLocator est chargée de fournir des informations à propos d'une erreur qui se serait produit durant le processus de transformation.
Templates permet d'exécuter des instructions de transformation.
URIResolver permet de résoudre des adresses URI rencontrées dans les instructions XSLT document(), xsl:import, ou xsl:include au sein d'un objet Source.
Classe Description
OutputKeys fournit un jeu de constantes pour des propriétés utilisables au sein des objets Transformer ou Templates.
Transformer permet de transformer une arborescence source en une arborescence résultante.
TransformerFactory représente une fabrique d'instances des classes Transformer et Template.
Exception Description
TransformerConfigurationException indique une erreur sévère de configuration.
TransformerException indique qu'une condition exceptionnelle s'est produite durant le processus de tranformation.
Erreur Description
TransformerFactoryConfigurationError est lancée lorsqu'il existe un problème de configuration des fabricateurs d'objets Transformer.

54.1 / L'interface ErrorListener

public interface ErrorListener To provide customized error handling, implement this interface and use the setErrorListener method to register an instance of the implmentation with the Transformer. The Transformer then reports all errors and warnings through this interface. If an application does not register its own custom ErrorListener, the default ErrorListener is used which reports all warnings and errors to System.err and does not throw any Exceptions. Applications are strongly encouraged to register and use ErrorListeners that insure proper behavior for warnings and errors. For transformation errors, a Transformer must use this interface instead of throwing an Exception: it is up to the application to decide whether to throw an Exception for different types of errors and warnings. Note however that the Transformer is not required to continue with the transformation after a call to fatalError(TransformerException exception). Transformers may use this mechanism to report XML parsing errors as well as transformation errors.

L'interface ErrorListener .

Méthode
Description
void error(TransformerException exception)
Receive notification of a recoverable error.
void fatalError(TransformerException exception)
Receive notification of a non-recoverable error.
void warning(TransformerException exception)
Receive notification of a warning.

54.2 / L'interface Result

L'interface Result fournit à un objet qui l'implémente, l'information nécessaire pour créer une arborecence résultant de la transformation, c'est-à-dire une adresse URI dans laquelle le contenu d'une transformation sera envoyé.

Champ
Description
static String PI_DISABLE_OUTPUT_ESCAPING
représente le nom de l'instruction de traitement qui est envoyée si l'arborescence résultante désactive l'échappement de sortie.
static String PI_ENABLE_OUTPUT_ESCAPING
représente le nom de l'instruction de traitement qui est envoyée si l'arborescence résultante active l'échappement de sortie à un certain point après avoir reçu une instruction de traitement PI_DISABLE_OUTPUT_ESCAPING.
Méthode
Description
String getSystemId()
retourne l'identificateur système pour l'objet Source courant.
void setSystemId(String systemId)
assigne un identificateur système pour l'objet Source courant.

54.3 / L'interface Source

L'interface Source fournit à un objet qui l'implémente, l'information nécessaire pour devenir une source d'entrée, c'est-à-dire une adresse URI connectant l'objet courant à un document XML ou XSLT.

Méthode
Description
String getSystemId()
retourne l'identificateur système pour l'objet Source courant.
void setSystemId(String systemId)
assigne un identificateur système pour l'objet Source courant.

54.4 / L'interface SourceLocator

L'interface SourceLocator est destinée principalement à rapporter des erreurs provenant de la source XML ou des instructions de transformation.

Méthode
Description
int getColumnNumber()
retourne le numéro de la colonne où s'est produit l'erreur.
int getLineNumber()
retourne le numéro de la ligne où s'est produit l'erreur.
String getPublicId()
retourne l'identificateur public pour l'événement du document courant.
String getSystemId()
retourne l'identificateur système pour l'événement du document courant.

54.5 / L'interface Templates

L'interface Templates permet à un objet qui l'implémente, de préparer une source XSLT en vue de l'exécution d'une transformation.

Les objets Templates doivent être threadsafe pour une instance donnée sur de multiples threads exécutés concurremment et peuvent être utilisés de plusieurs fois dans une session donnée.

Méthode
Description
Properties getOutputProperties()
retourne une liste de propriétés correspondant aux attributs de l'élément XSLT xsl:output.
Transformer newTransformer()
crée un nouveau contexte de transformation pour l'objet Templates courant.

54.6 / L'interface URIResolver

L'interface URIResolver permet à un objet qui l'implémente d'être appelé par le processeur XML lorsqu'il rencontre une adresse URI utilisé dans les instructions XSLT document(), xsl:import, et xsl:include au sein d'un objet Source.

Méthode
Description
Source resolve(String href, String base)
est appelée par le processeur lorsqu'il rencontre une instruction XSLT xsl:include, xsl:import, ou document().

54.7 / La classe OutputKeys

Class java.lang.Object javax.xml.transform.OutputKeys

.

public class OutputKeysextends ObjectProvides string constants that can be used to set output properties for a Transformer, or to retrieve output properties from a Transformer or Templates object. All the fields in this class are read-only. See Also: section 16 of the XSL Transformations (XSLT) W3C Recommendation

La classe OutputKeys .

Champ
Description
static String CDATA_SECTION_ELEMENTS
cdata-section-elements = expanded names.
static String DOCTYPE_PUBLIC
doctype-public = string
static String DOCTYPE_SYSTEM
doctype-system = string
static String ENCODING
encoding = string
static String INDENT
indent = "yes" | "no"
static String MEDIA_TYPE
media-type = string
static String METHOD
method = "xml" | "html" | "text" | expanded name
static String OMIT_XML_DECLARATION
omit-xml-declaration = "yes" | "no"
static String STANDALONE
standalone = "yes" | "no"
static String VERSION
version = nmtoken.
Méthode
Description
Méthodes héritées à partir de la classe java.lang.Objec.
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

54.8 / La classe Transformer

public abstract class Transformerextends ObjectAn instance of this abstract class can transform a source tree into a result tree. An instance of this class can be obtained with the TransformerFactory.newTransformer method. This instance may then be used to process XML from a variety of sources and write the transformation output to a variety of sinks. An object of this class may not be used in multiple threads running concurrently. Different Transformers may be used concurrently by different threads. A Transformer may be used multiple times. Parameters and output properties are preserved across transformations.

La classe abstraite Transformer permet d'obtenir un résultat à partir d'un source XML.

Une instance de cette classe peut être obtenu par l'intermédiaire de la méthode TransformerFactory.newTransformer().

Un objet Transformer peut être utilisé pour traiter un document XML provenant de diverses sources (fichier, adresses URI, flux d'octets ou de caractères) et écrire le résultat de la transformation dans divers format (XML, HTML, texte, ou autres).

Un objet Transformer ne peut pas être utilisé dans de multiples threads exécutés concurremment.Néanmoins, des transformateurs différents peuvent être utilisés dans ce contexte.

Un transformateur peut être utilisé plusieurs fois. Les paramètres et les propriétés de sortie sont conservés pour chaque transformation.

Constructeur
Description
protected Transformer()
crée une nouvelle instance de la classe Transformer. Ce constructeur est protégé.
Méthode
Description
abstract void clearParameters()
supprime tous les paramètres ajoutés avec la méthode setParameter().
abstract ErrorListener getErrorListener()
retourne le gestionnaire d'erreurs agissant lors de la transformation.
abstract Properties getOutputProperties()
retourne les propriétés qui auraient un effet sur le résultat d'une transformation.
abstract String getOutputProperty(String name)
retourne la valeur d'une propriété qui aurait un effet sur le résultat d'une transformation.
abstract Object getParameter(String name)
retourne un paramètre employé pour la transformation.
abstract URIResolver getURIResolver()
retourne le gestionnaire d'adresses URI utilisées dans l'instruction XSLT document().
void reset()
réinitialise l'objet Transformer vers sa configuration initiale.
abstract void setErrorListener(ErrorListener listener)
assigne un gestionnaire d'erreurs agissant lors de la transformation.
abstract void setOutputProperties(Properties oformat)
fixe les propriétés qui auraient un effet sur le résultat d'une transformation.
abstract void setOutputProperty(String name, String value)
fixe la valeur d'une propriété qui aurait un effet sur le résultat d'une transformation.
abstract void setParameter(String name, Object value)
ajoute un paramètre employé pour la transformation.
abstract void setURIResolver(URIResolver resolver)
assigne un gestionnaire d'adresses URI utilisées dans l'instruction XSLT document().
abstract void transform(Source xmlSource, Result outputTarget)
transforme la source XML spécifiée vers un objet Result indiqué.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

54.9 / La classe TransformerFactory

La classe abstraite TransformerFactory peut être utilisée pour créer des objets Transformer et Templates.

Constructeur
Description
protected TransformerFactory()
crée une nouvelle instance de la classe TransformerFactory. Ce constructeur est protégé.
Methode
Description
abstract Source getAssociatedStylesheet(
Source source, String media, String title, String charset)
retourne un objet Source contenant des instructions XSLT liées au document XML source spécifié par l'instruction de traitement xml-stylesheet. Il est possible de renvoyer plusieurs feuilles de style. Dans ce cas, elles sont retournées comme si elles étaient une liste d'importations au sein d'une unique source XSLT.
abstract Object getAttribute(String name)
retourne un attribut correspondant au nom passé en argument.
abstract ErrorListener getErrorListener()
retourne le gestionnaire d'erreurs associé à l'objet TransformerFactory.
abstract boolean getFeature(String name)
indique l'état de la caractéristique correspondat au nom spécifié.
abstract URIResolver getURIResolver()
retourne l'objet qui est utilisé par défaut durant la transformation pour résoudre les adresses URI utilisées dans les instructions XSLT document(), xsl:import et xsl:include.
static TransformerFactory newInstance()
retourne une nouvelle instance de la classe TransformerFactory.
abstract Templates newTemplates(Source source)
retourne l'objet Source spécifié sous la forme d'un objet Templates, lequel est une représentation compilée de la source XSLT.
abstract Transformer newTransformer()
retourne une nouvelle instance de la classe Transformer.
abstract Transformer newTransformer(Source source)
retourne un objet Transformer conçu à partir d'une source XSLT spécifiée.
abstract void setAttribute(String name, Object value)
fixe la valeur de l'attribut correspondant au nom spécifié.
abstract void setErrorListener(ErrorListener listener)
assigne un gestionnaire d'erreurs qui est utilisé pour le traitement des instructions de transformation et non pour la transformation elle-même.
abstract void setFeature(String name, boolean value)
fixe la valeur d'une caractéristique l'objet TransformerFactory courant et pour les objets Transformer ou Templates créés par cette fabrique.
abstract void setURIResolver(URIResolver resolver)
assigne un gestionnaire d'adresses URI utilisé par défaut pour résoudre les adresses URI employées dans les instructions XSLT document(), xsl:import et xsl:include.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

55 / Le paquetage javax.xml.transform.sax

Le paquetage javax.xml.transform.sax fournit des fonctionnalités de transformation, lesquelles s'appuyent sur SAX pour leur mise en oeuvre.

Interface Description
TemplatesHandler constitue un gestionnaire de contenu ContentHandler qui peut être utilisé pour traiter des événements d'analyse SAX produit sur la source XSLT, au sein d'un objet Templates.
TransformerHandler constitue un gestionnaire d'événements ContentHandler qui transforme une source XML vers un résultat.
Classe Description
SAXResult représente un support pour un objet Result.
SAXSource rerpésente un support pour un objet Source.
SAXTransformerFactory étend la classe TransformerFactory pour fournir des méthodes de fabrique spécifique à SAX.

55.1 / L'interface TemplatesHandler

L'interface TemplatesHandler représente un gestionnaire de contenu SAX qui peut être utilisé pour traiter les événements d'analyse SAX sur des instructions XSLT, au sein d'un objet Templates.

Méthode
Description
String getSystemId()
retourne l'identificateur système.
Templates getTemplates()
Lorsqu'un objet TemplatesHandler est utilisé comme un gestionnaire de contenu pour l'analyse d'instructions de transformation XSL, cette méthode crée un objet Templates une fois que les événements SAX se soient terminés.
void setSystemId(String systemID)
assigne un identificateur système.
Méthodes héritées à partir de l'interface org.xml.sax.ContentHandler
characters, endDocument, endElement, endPrefixMapping, ignorableWhitespace,
processingInstruction, setDocumentLocator, skippedEntity, startDocument,
startElement, startPrefixMappin.

55.2 / L'interface TransformerHandler

L'interface TransformerHandler étend les interfaces ContentHandler, LexicalHandler et DTDHandler.

L'interface est chargée decapter les événements d'analyse SAX et les utilisent pour la transformation XSLT d'une source XML vers un résultat.

Méthode
Description
String getSystemId()
retourne l'identificateur système.
Transformer getTransformer()
retourne l'objet Transformer associé à ce gestionnaire, lequel est nécessaire pour fixer les paramètres et les propriétés de sortie.
void setResult(Result result)
assigne un objet Result pour recevoir le résultat de la transformation.
void setSystemId(String systemID)
assigne un identificateur système.
Méthodes héritées à partir de l'interface org.xml.sax.ContentHandler
characters, endDocument, endElement, endPrefixMapping, ignorableWhitespace,
processingInstruction, setDocumentLocator, skippedEntity, startDocument,
startElement, startPrefixMappin.
Méthodes héritées à partir de l'interface org.xml.sax.ext.LexicalHandler
comment, endCDATA, endDTD, endEntity, startCDATA, startDTD, startEntity
Méthodes héritées à partir de l'interface org.xml.sax.DTDHandler
notationDecl, unparsedEntityDec.

55.3 / La classe SAXResult

L'interface SAXResult constitue un support pour un résultat de transformation utilisant SAX (Simple API XML).

Champ
Description
static String FEATURE
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passée cette valeur comme un argument, l'objet Transformer supporte la sortie de l'objet Result de ce type.
Les champs hérités de l'interface javax.xml.transform.Result
PI_DISABLE_OUTPUT_ESCAPING, PI_ENABLE_OUTPUT_ESCAPING
Constructeur
Description
SAXResult()
crée une nouvelle instance de la classe SAXResult.
SAXResult(ContentHandler handler)
crée une nouvelle instance de la classe SAXResult et l'initialise avec un gestionnaire de contenu.
Méthode
Description
ContentHandler getHandler()
retourne le gestionnaire de contenu.
LexicalHandler getLexicalHandler()
retourne le gestionnaire lexicale SAX 2.
String getSystemId()
retourne l'identificateur système.
void setHandler(ContentHandler handler)
assigne un gestionnaire de contenu.
void setLexicalHandler(LexicalHandler handler)
assigne un gestionnaire lexicale SAX 2.
void setSystemId(String systemId)
assigne un identificateur système qui doit être utilisé avec le gestionnaire de contenu.
Méthodes héritées à partir de la classe java.lang.Objec
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

55.4 / La classe SAXSource

La classe SAXSource constitue un support pour une source de transformation utilisant SAX (Simple API XML).

Champ
Description
static String FEATURE
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passée cette valeur comme un argument, l'objet Transformer supporte l'entrée de l'objet Source de ce type.
Constructeur
Description
SAXSource()
crée une nouvelle instance de la classe SAXSource.
SAXSource(InputSource inputSource)
crée une nouvelle instance de la classe SAXSource et l'initialise avec un objet InputSource.
SAXSource(XMLReader reader, InputSource inputSource)
crée une nouvelle instance de la classe SAXSource et l'initialise avec des objets XMLReaderInputSource.
Méthode
Description
InputSource getInputSource()
retourne la source d'entrée utilisé par l'objet courant.
String getSystemId()
retourne l'identificateur système.
XMLReader getXMLReader()
retourne le lecteur XML utilisé par l'objet courant.
void setInputSource(InputSource inputSource)
assigne une source d'entrée utilisé par l'objet courant.
void setSystemId(String systemId)
assigne un identificateur système.
void setXMLReader(XMLReader reader)
assigne un lecteur XML utilisé par l'objet courant.
static InputSource sourceToInputSource(Source source)
tente d'obtenir un objet InputSource à partir d'un objet Source.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

55.5 / La classe SAXTransformerFactory

La classe SAXTransformerFactory étend la classe TransformerFactory pour ajouter des méthodes de fabrique spécifique à SAX.

Il fournit deux type de gestionnaires de contenu, une pour la création d'objets Transformer et l'autre pour la création d'objets Templates.

Champ
Description
static String FEATURE
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passée cette valeur comme un argument, l'objet TransformerFactory retourné par la méthode TransformerFactory.newInstance() peut être converti sûrement vers un objet SAXTransformerFactory.
static String FEATURE_XMLFILTER
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passée cette valeur comme un argument, les méthodes newXMLFilter() et newXMLFilter() sont supportées.
Constructeur
Description
protected SAXTransformerFactory()
crée une nouvelle instance de la classe SAXTransformerFactory. Toutefois, ce constructeur est protégé.
Methode
Description
abstract TemplatesHandler newTemplatesHandler()
retourne un objet TemplatesHandler qui peut traiter les événements du gestionnaire de contenu SAX dans un objet Templates.
abstract TransformerHandler newTransformerHandler()
retourne un objet TransformerHandler qui peut traiter les événements du gestionnaire de contenu SAX dans un objet Result.
abstract TransformerHandler newTransformerHandler(Source src)
retourne un objet TransformerHandler qui peut traiter les événements du gestionnaire de contenu SAX dans un objet Result, s'appuyant sur les instructions de tranformations XSL fournies par l'objet Source spécifié.
abstract TransformerHandler newTransformerHandler(Templates templates)
retourne un objet TransformerHandler qui peut traiter les événements du gestionnaire de contenu SAX dans un objet Result, s'appuyant sur les instructions de tranformations XSL fournies par l'objet Templates spécifié. Get a TransformerHandler object that can process SAX ContentHandler events into a Result, based on the Templates argument.
abstract XMLFilter newXMLFilter(Source src)
retourne un objet XMLFilter qui utilise l'objet Source spécifié, lequel contient des instructions de transformation XSL.
abstract XMLFilter newXMLFilter(Templates templates)
retourne un objet XMLFilter qui utilise l'objet Templates spécifié, lequel contient des instructions de transformation XSL.
Méthodes héritées à partir de la classe javax.xml.transform.TransformerFactory
getAssociatedStylesheet, getAttribute, getErrorListener, getFeature, getURIResolver,
newInstance, newTemplates, newTransformer, newTransformer, setAttribute,
setErrorListener, setFeature, setURIResolve.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

56 / Le paquetage javax.xml.transform.dom

Le paquetage javax.xml.transform.sax fournit des fonctionnalités de transformation, lesquelles s'appuyent sur DOM (Document Object Model) pour leur mise en oeuvre.

Interface Description
DOMLocator indique la position d'un noeud au sein de la source DOM.
Classe Description
DOMResult constitue un support pour le résultat d'une transformation.
DOMSource constitue un support pour pour la source d'une transformation.

56.1 / La classe DOMLocator

L'interface DOMLocator étend SourceLocator et ajoute une nouvelle fonctionnalité indiquant la position d'un noeud dans une source DOM.

Méthode
Description
Node getOriginatingNode()
retourne le noeud où l'événement s'est produit.
Méthodes héritées à partir de l'interface javax.xml.transform.SourceLocator
getColumnNumber, getLineNumber, getPublicId, getSystemId

56.2 / La classe DOMResult

La classe DOMResult constitue un support pour le résultat d'une transformation obtenu sous divers format, dont XML, HTML et texte.

Champ
Description
static String FEATURE
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passé cette valeur comme un argument, l'objet Transformer supporte la sortie de l'objet Result de ce type.
Les champs hérités à partir de l'interface javax.xml.transform.Result
PI_DISABLE_OUTPUT_ESCAPING, PI_ENABLE_OUTPUT_ESCAPING
Constructeur
Description
DOMResult()
crée une nouvelle instance de la classe DOMResult.
DOMResult(Node node)
crée une nouvelle instance de la classe DOMResult et l'initialise avec l'objet Node qui accueillera le résultat de la transformation.
DOMResult(Node node, Node nextSibling)
crée une nouvelle instance de la classe DOMResult et l'initialise avec l'objet Node qui insérera le résultat de la transformation avant le second noeud enfant du premier.
DOMResult(Node node, Node nextSibling, String systemId)
crée une nouvelle instance de la classe DOMResult et l'initialise avec l'objet Node qui insérera le résultat de la transformation avant le second noeud enfant du premier et l'identificateur système utilisé en association avec ce noeud.
DOMResult(Node node, String systemId)
crée une nouvelle instance de la classe DOMResult et l'initialise avec un identificateur système, utilisé en association avec le noeud; et l'objet Node qui accueillera le résultat de la transformation.
Méthode
Description
Node getNextSibling()
retourne le noeud enfant à partir duquel les noeuds résultants seront insérés avant.
Node getNode()
Get the node that will contain the result DOM tree.
String getSystemId()
retourne l'identificateur système.
void setNextSibling(Node nextSibling)
assigne le noeud enfant à partir duquel les noeuds résultants seront insérés avant.
void setNode(Node node)
assigne le noeud destiné à contenir l'arborescence du résultat DOM.
void setSystemId(String systemId)
retourne l'identificateur système qui doit être utilisé en association avec le noeud.
Méthodes héritées à partir de la classe java.lang.Objec
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

56.3 / La classe DOMSource

La classe DOMSource constitue un support pour une source de transformation utilisant le DOM (Document Object Model).

Champ
Description
static String FEATURE
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passé cette valeur comme un argument, l'objet Transformer supporte l'entrée de l'objet Source de ce type.
Constructeur
Description
DOMSource()
crée une nouvelle instance de la classe DOMSource.
DOMSource(Node n)
crée une nouvelle instance de la classe DOMSource en l'initialisant à partir d'un noeud XML.
DOMSource(Node node, String systemID)
crée une nouvelle instance de la classe DOMSource en l'initialisant à partir d'un noeud XML et d'un identificateur système.
Méthode
Description
Node getNode()
retourne le noeud qui représente l'arborescence de l'objet DOMSource courant.
String getSystemId()
retourne l'identificateur système.
void setNode(Node node)
assigne le noeud XML spécifié à l'objet courant.
void setSystemId(String systemID)
assigne un identificateur système.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

57 / Le paquetage javax.xml.transform.stream

Le paquetage javax.xml.transform.stream fournit des fonctionnalités de transformation, lesquelles s'appuyent sur des flux InputStream, OutputStream, des objets Reader, Writer, des fichiers ou des adresses URI, pour mettre en oeuvre des transformations.

Classe Description
StreamResult constitue un support pour le résultat d'une transformation, lequel peut être rendu sous le format XML, HTML, texte ou autres.
StreamSource constitue un support pour la source d'une transformation sous la forme d'un flux XML.

57.1 / La classe StreamResult

La classe StreamResult .constitue un support pour le résultat d'une transformation, lequel est obtenu sous le format XML, HTML, texte ou autres.

Champ
Description
static String FEATURE
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passé cette valeur comme un argument, l'objet Transformer supporte la sortie de l'objet Result de ce type.
Les champs hérités à partir de l'interface javax.xml.transform.Result
PI_DISABLE_OUTPUT_ESCAPING, PI_ENABLE_OUTPUT_ESCAPING
Constructeur
Description
StreamResult()
crée une nouvelle instance de la classe StreamResult.
StreamResult(File f)
crée une nouvelle instance de la classe StreamResult en l'initialisant avec un fichier.
StreamResult(OutputStream outputStream)
crée une nouvelle instance de la classe StreamResult en l'initialisant avec un objet OutputStream.
StreamResult(String systemId)
crée une nouvelle instance de la classe StreamResult en l'initialisant avec un identificateur système.
StreamResult(Writer writer)
crée une nouvelle instance de la classe StreamResult en l'initialisant avec un objet Writer.
Méthode
Description
OutputStream getOutputStream()
retourne le flux d'octets.
String getSystemId()
retourne l'identificateur système.
Writer getWriter()
retourne le flux de caractères.
void setOutputStream(OutputStream outputStream)
assigne un flux d'octets pour recevoir le résultat.
void setSystemId(File f)
assigne un identificateur système désignant un fichier.
void setSystemId(String systemId)
assigne un identificateur système qui peut être utilisé en association avec les flux Writer et OutputStream, ou peut être utilisé pour désigner un fichier.
void setWriter(Writer writer)
assigne un objet Writer pour recevoir le résultat.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

57.2 / La classe StreamSource

La classe StreamSource constitue un support pour la source d'une transformation, laquelle est obtenue sous la forme d'un flux de balisage XML.

Champ
Description
static String FEATURE
Si la méthode TransformerFactory.getFeature() retourne true lorsqu'est passé cette valeur comme un argument, l'objet Transformer supporte l'entrée de l'objet Source de ce type.
Constructeur
Description
StreamSource()
crée une nouvelle instance de la classe StreamSource.
StreamSource(File f)
crée une nouvelle instance de la classe StreamSource en l'initialisant avec un fichier.
StreamSource(InputStream inputStream)
crée une nouvelle instance de la classe StreamSource en l'initialisant avec un flux d'octets.
StreamSource(InputStream inputStream, String systemId)
crée une nouvelle instance de la classe StreamSource en l'initialisant avec un flux d'octets et un identificateur système.
StreamSource(Reader reader)
crée une nouvelle instance de la classe StreamSource en l'initialisant avec un objet Reader.
StreamSource(Reader reader, String systemId)
crée une nouvelle instance de la classe StreamSource en l'initialisant avec un flux de caractères et un identificateur système.
StreamSource(String systemId)
crée une nouvelle instance de la classe StreamSource en l'initialisant avec une adresse URI.
Méthode
Description
InputStream getInputStream()
retourne le flux d'octets.
String getPublicId()
retourne l'identificateur public.
Reader getReader()
retourne le flux de caractères.
String getSystemId()
retourne l'identificateur système.
void setInputStream(InputStream inputStream)
assigne un flux de caractères.
void setPublicId(String publicId)
assigne un identificateur public.
void setReader(Reader reader)
assigne un objet Reader.
void setSystemId(File f)
assigne un identificateur système pointant sur un fichier.
void setSystemId(String systemId)
assigne un identificateur système.
Méthodes héritées à partir de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait.

58 / Le paquetage javax.xml.validation

Le paquetage javax.xml.validation fournit une API pour la validation des documents XML par rapport à un schéma XML W3C, RelaxNG ou Schematron.

Classe Description
Schema représente un ensemble de contraintes auxquelles le document XML doit se conformer.
SchemaFactory est une fabrique permettant de créer des objets Schema.
SchemaFactoryLoader est une fabrique permettant de créer des objets SchemaFactory.
TypeInfoProvider fournit un accès à l'information de type déterminée par un objet ValidatorHandler.
Validator constitue un processeur chargé de vérifier la validité du document XML par rapport à un schéma.
ValidatorHandler représente un gestionnaire de validation qui fonctionne avec les flux SAX.

58.1 / La classe Schema

Constructeur
Description
protected Schema()
crée une nouvelle instance de la classe Schema. Toutefois, ce constructeur est protégé.
Méthode
Description
abstract Validator newValidator()
crée un nouvel objet Validator pour le schéma courant.
abstract ValidatorHandler newValidatorHandler()
crée une nouvelle instance de la classe ValidatorHandler pour le schéma courant.
Méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

58.2 / La classe SchemaFactory

La classe abstraite SchemaFactory permet de créer des instances de la classe Schema.

Un objet SchemaFactory est un compilateur de schéma. Il est capable d'utiliser diverses sources pour analyser et construire un objet Schema.

Les sources peuvent être des fichiers, des objets SAXSource ou DOMSource ou encore des ressources externes désignées par une adresse URL.

Constructeur
Description
protected SchemaFactory()
crée une nouvelle instance de la classe SchemaFactory. Toutefois cette classe est protégée.
Méthode
Description
abstract ErrorHandler getErrorHandler()
retourne le gestionnaire d'erreurs associé à l'objet SchemaFactory courant.
boolean getFeature(String name)
vérifie si la caractéristique correspondant au nom spécifié, est activée.
Object getProperty(String name)
obtient la valeur de la propriété correspondant au nom spécifié.
abstract LSResourceResolver getResourceResolver()
retourne l'objet LSResourceResolver associé à l'objet SchemaFactory courant.
abstract boolean isSchemaLanguageSupported(String schemaLanguage)
indique si le schéma spécifié est supporté par l'objet SchemaFactory courant.
static SchemaFactory newInstance(String schemaLanguage)
crée une nouvelle instance de la classe SchemaFactory qui supporte le langage de schéma indiqué.
abstract Schema newSchema()
crée une nouvelle instance de la classe Schema.
Schema newSchema(File schema)
crée un nouveau schéma à partir du fichier fourni.
Schema newSchema(Source schema)
crée un nouveau schéma à partir de la source fournie.
abstract Schema newSchema(Source[] schemas)
crée un nouveau schéma à partir des sources fournis.
Schema newSchema(URL schema)
crée un nouveau schéma à partir d'une ressource externe pointée par l'adresse URL.
abstract void setErrorHandler(ErrorHandler errorHandler)
assigne un gestionnaire d'erreurs pour l'objet SchemaFactory courant.
void setFeature(String name, boolean value)
détermine si la caractéristique correspondant au nom spécifié, doit être activée.
void setProperty(String name, Object object)
assigne une valeur à la propriété correspondant au nom spécifié.
abstract void setResourceResolver(LSResourceResolver resourceResolver)
retourne un objet LSResourceResolver pour l'objet SchemaFactory courant.
Méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

58.3 / La classe SchemaFactoryLoader

La classe abstraite SchemaFactoryLoader permet de créer des instances de la classe SchemaFactory.

Cette classe a pour objectif d'être utilisée par les implémentations de l'API de validation, mais pas directement par les utilisateurs.

Constructeur
Description
protected SchemaFactoryLoader()
crée une nouvelle instance de la classe SchemaFactoryLoader. Toutefois cette classe est protégée.
Méthode
Description
abstract SchemaFactory newFactory(String schemaLanguage)
crée un objet SchemaFactory pour le langage de schéma spécifié.
Méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

58.4 / La classe TypeInfoProvider

La classe abstraite TypeInfoProvider fournit un accès aux informations de type déterminées par l'objet ValidatorHandler.

Quelques langages de schéma, tels que celui du W3C (W3C XML Schema), encourage un validateur à rapporter le "type" qu'il assigne à chaque attribut et élément. Les applications qui souhaitent accéder à ces informations de type peuvent appeler des méthodes définies par cette classe.

L'implémentation de cette classe peut être obtenue par la méthode ValidatorHandler.getTypeInfoProvider().

Constructeur
Description
protected TypeInfoProvider()
crée une nouvelle instance de la classe TypeInfoProvider. Toutefois cette classe est protégée.
Méthode
Description
abstract TypeInfo getAttributeTypeInfo(int index)
retourne un objet TypeInfo non-modifiable pour l'attribut désigné par l'index spécifié.
abstract TypeInfo getElementTypeInfo()
retourne un objet TypeInfo non-modifiable pour l'élément courant.
abstract boolean isIdAttribute(int index)
indique si l'attribut désigné par l'index spécifié, est du type ID.
abstract boolean isSpecified(int index)
indique si l'attribut désigné par l'index spécifié n'a pas été ajouté par le validateur.
Méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

58.5 / La classe Validator

La classe abstraite Validator vérifie qu'un document XML respecte un schéma XML.

Les méthodes validate() prennent en tant qu'argument une instance de la classe Source. Cette dernière doit être un objet SAXSource ou DOMSource.

Constructeur
Description
protected Validator()
crée une nouvelle instance de la classe Validator. Toutefois cette classe est protégée.
Méthode
Description
abstract ErrorHandler getErrorHandler()
retourne le gestionnaire d'erreurs associé au validateur.
boolean getFeature(String name)
vérifie si la caractéristique correspondant au nom spécifié a été activée.
Object getProperty(String name)
retourne la valeur de la propriété correspondant au nom spécifié.
abstract LSResourceResolver getResourceResolver()
retourne l'objet LSResourceResolver associé au validateur courant.
abstract void reset()
réinitialise le validateur courant à sa configuration initiale.
abstract void setErrorHandler(ErrorHandler errorHandler)
assigne un gestionnaire d'erreurs pour le validateur courant.
void setFeature(String name, boolean value)
détermine si la caractéristique correspondant au nom spécifié doit être activée.
void setProperty(String name, Object object)
assigne une valeur à la propriété correspondant au nom spécifié.
abstract void setResourceResolver(LSResourceResolver resourceResolver)
assigne un objet LSResourceResolver pour le validateur courant.
void validate(Source source)
effectue une validation de la source spécifiée.
abstract void validate(Source source, Result result)
effectue une validation de la source spécifiée et envoie le résultat vers l'objet Result fourni.
Méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

58.6 / La classe ValidatorHandler

La classe ValidatorHandler vérifie si les événements d'analyse SAX suivent correctement les contraintes édictées dans le schéma qui lui a été associé.

La classe ValidatorHandler étend la classe ContentHandler, mais elle redéfinit une partie du fonctionnement originel de cette dernière.

  1. Les événements de début et de fin d'élément doivent recevoir une chaîne de caractères non-nulle pour l'adresse URI, le nom local et le nom qualifié, bien que SAX permet à certains d'entre eux d'être nuls. De même, l'objet ContentHandler personnalisé par l'utilisateur recevra des paramètres non nuls.
  2. Les applications doivent s'assurer que les méthodes startPrefixMapping() et endPrefixMapping() de la classe ValidatorHandler sont appelées correctement. De même, l'objet ContentHandler personnalisé par l'utilisateur recevra des événements de début et de fin de préfixe d'espace de noms. Si l'objet ValidatorHandler introduit des liaisons d'espace de noms supplémentaires, l'objet ContentHandler personnalisé par l'utilisateur recevra des événements supplémentaires sur les méthodes startPrefixMapping() et endPrefixMapping().
  3. Les attributs provenant de la méthode ContentHandler.startElement() peuvent ou peuvent ne pas inclure des attributs de déclaration d'espace de noms (xmlns).

Un objet ValidatorHandler est automatiquement réinitialisé à chaque fois que la méthode StartDocument() est invoquée.

Constructeur
Description
protected ValidatorHandler()
crée une nouvelle instance de la classe ValidatorHandler. Toutefois cette classe est protégée.
Méthode
Description
abstract ContentHandler getContentHandler()
retourne l'objet ContentHandler associé à l'objet courant.
abstract ErrorHandler getErrorHandler()
retourne l'objet ErrorHandler associé à l'objet courant.
boolean getFeature(String name)
vérifie si la caractéristique spécifiée par son nom est activée.
Object getProperty(String name)
retourne la valeur de la propriété spécifiée par son nom.
abstract LSResourceResolver getResourceResolver()
retourne l'objet LSResourceResolver associé à l'objet courant.
abstract TypeInfoProvider getTypeInfoProvider()
retourne l'objet TypeInfoProvider associé à l'objet courant.
abstract void setContentHandler(ContentHandler receiver)
assigne un objet ContentHandler associé à l'objet courant.
abstract void setErrorHandler(ErrorHandler errorHandler)
assigne un objet ErrorHandler associé à l'objet courant.
void setFeature(String name, boolean value)
détermine si la caractéristique spécifiée par son nom doit être activée.
void setProperty(String name, Object object)
assigne une valeur à la propriété spécifiée par son nom.
abstract void setResourceResolver(LSResourceResolver resourceResolver)
assigne un objet LSResourceResolver associé à l'objet courant.
Méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

59 / Le paquetage javax.xml.xpath

Le paquetage javax.xml.xpath fournit une API pour l'évaluation d'expressions XPath et l'accès à l'environnement d'évaluation.

Interface Description
XPath fournit un accès aux expressions et à l'environnement d'évaluation XPath.
XPathExpression fournit un accès aux expressions compilées XPath.
XPathFunction fournit un accès aux fonctions XPath.
XPathFunctionResolver permet de résoudre à l'aide d'un nom et du nombre d'arguments d'une fonction XPath.
XPathVariableResolver permet de retrouver une variable XPath dans toutes celles disponibles.
Classe Description
XPathConstants contient un ensemble de constantes XPath.
XPathFactory est une fabrique d'objets XPath.
Exception Description
XPathException représente une exception générique XPath.
XPathExpressionException représente une erreur dans une expression XPath.
XPathFactoryConfigurationException représente une erreur de configuration de l'environnement XPathFactory.
XPathFunctionException représente une erreur dans une fonction XPath.

59.1 / L'interface XPath

La classe XPath permet d'accéder aux expressions et à l'environnement d'évaluation XPath.

Si une requête est faite pour évaluer l'expression XPath en l'absence d'un élément de contexte, un document vide sera employé pour le contexte. Pour les buts d'évaluation des expressions XPath, un objet DocumentFragment est traité comme un noeud Document.

Si l'expression contient une référence de variable, sa valeur sera trouvée par l'objet XPathVariableResolver. Un exception XPathExpressionException est lancée si l'objet XPathVariableResolver est indéfini ou si ce dernier retourne null pour la variable. La valeur d'une variable doit être immuable au cours de n'importe quelle évaluation.

Si l'expression contient une référence à une fonction, celle-ci sera trouvée par l'objet XPathFunctionResolver. Une exception XPathExpressionException est lancée si l'objet XPathFunctionResolver est indéfini ou si ce dernier retourne null pour la fonction.

Les noms qualifiés dans une expression XPath sont résolus en s'appuyant sur le contexte d'espace de noms de XPath.

Le résultat de l'évaluation d'une expression XPath est converti en une instance du type de retour désiré. Des types de retour valides sont définis dans XPathConstants. La conversion en type de retour suit des règles de conversion de XPath.

Méthode
Description
XPathExpression compile(String expression)
compile une expression XPath pour une prochaine évaluation.
String evaluate(String expression, InputSource source)
évalue une expression XPath dans le contexte de la source d'entrée spécifiée et retourne le résultat sous la forme d'une chaîne de caractères.
Object evaluate(String expression, InputSource source, QName returnType)
évalue une expression XPath dans le contexte de la source d'entrée spécifiée et retourne le résultat sous la forme d'un objet dont le type est indiqué.
String evaluate(String expression, Object item)
évalue une expression XPath dans le contexte spécifié et retourne le résultat sous la forme d'une chaîne de caractères.
Object evaluate(String expression, Object item, QName returnType)
évalue une expression XPath dans le contexte spécifié et retourne le résultat sous la forme d'un objet dont le type est indiqué.
NamespaceContext getNamespaceContext()
retourne le contexte d'espace de noms courant.
XPathFunctionResolver getXPathFunctionResolver()
retourne l'objet XPathFunctionResolver associé à cet objet.
XPathVariableResolver getXPathVariableResolver()
retourne l'objet XPathVariableResolver associé à cet objet.
void reset()
réinitialise la configuration initiale de l'objet XPath.
void setNamespaceContext(NamespaceContext nsContext)
assigne un contexte d'espace de noms pour l'objet courant.
void setXPathFunctionResolver(XPathFunctionResolver resolver)
assigne un objet XPathFunctionResolver associé à l'objet courant.
void setXPathVariableResolver(XPathVariableResolver resolver)
assigne un objet XPathVariableResolver associé à l'objet courant.

59.2 / L'interface XPathExpression

La classe XPathExpression fournit un accès à des expressions XPath compilées.

Méthode
Description
String evaluate(InputSource source)
évalue l'expression XPath compilée dans le contexte de la source d'entrée spécifiée et retourne le résultat sous la forme d'une chaîne de caractères.
Object evaluate(InputSource source, QName returnType)
évalue l'expression XPath compilée dans le contexte de la source d'entrée spécifiée et retourne le résultat sous la forme d'un objet du type indiqué.
String evaluate(Object item)
évalue l'expression XPath compilée dans le contexte spécifié et retourne le résultat sous la forme d'une chaîne de caractères.
Object evaluate(Object item, QName returnType)
évalue l'expression XPath compilée dans le contexte spécifié et retourne le résultat sous la forme d'un objet du type indiqué.

59.3 / L'interface XPathFunction

La classe XPathFunction permet d'évaluer une fonction avec une liste d'arguments

Méthode
Description
Object evaluate(List args)
retourne le résultat de l'évaluation de la fonction XPath correspondant à la liste d'arguments spécifiée.

59.4 / L'interface XPathFunctionResolver

La classe XPathFunctionResolver permet d'accéder à une fonction, qui ne doit d'ailleurs pas être une fonction intégrée à XPath, parmi un ensemble de fonctions définies par l'utilisateur.

En particulier, l'objet XPathFunctionResolver est seulement appelé pour les fonctions dans un autre espace de noms (fonctions avec un préfixe explicite). Ceci signifie qu'il n'est pas possible d'utiliser cet objet pour implémenter des spécifications telles que La syntaxe et le traitement des signatures XML (XML-Signature Syntax and Processing), lequel étend la librairie de fonction XPath 1.0 dans le même espace de noms. Cela est une conséquence de la conception de la classe XPathFunctionResolver.

Pour implémenter des fonctions intégrées supplémentaires, il faut étendre directement l'implémentation sous-jacente.

Méthode
Description
XPathFunction resolveFunction(QName functionName, int arity)
trouve une fonction parmi celles définies par l'utilisateur, en utilisant son nom et le nombre de ses paramètres.

59.5 / L'interface XPathVariableResolver

La classe XPathVariableResolver permet d'accéder à une variable, qui doit d'ailleurs être non-mutable, parmi un ensemble de variables définies par l'utilisateur.

Méthode
Description
Object resolveVariable(QName variableName)
trouve une variable parmi celles disponibles, correspondant au nom passé en argument.

59.6 / La classe XPathConstants

La classe XPathConstants fournit un ensemble de constantes pour l'API XPath.

Champ
Description
static QName BOOLEAN
représente le type de données booléen XPath 1.0.
static String DOM_OBJECT_MODEL
contient l'adresse URI du modèle d'objet DOM (http://java.sun.com/jaxp/xpath/dom).
static QName NODE
représente le type de données Node XPath 1.0.
static QName NODESET
rerpésente le type de données NodeSet XPath 1.0.
static QName NUMBER
représente le type de données numérique XPath 1.0.
static QName STRING
représente le type de données de chaîne de caractères XPath 1.0.
Méthode
Description
Les méthode héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

59.7 / La classe XPathFactory

La classe abstraite XPathFactory peut être utilisé pour créer des objets XPath.

Champ
Description
static String DEFAULT_OBJECT_MODEL_URI
représente l'adresse URI du modèle d'objet par défaut.
static String DEFAULT_PROPERTY_NAME
représente le nom de propriété par défaut en accord avec les spécifications JAXP.
Constructeur
Description
protected XPathFactory()
crée une nouvelle instance de la classe XPathFactory. Toutefois cette classe est protégée.
Méthode
Description
abstract boolean getFeature(String name)
indique si la caractéristique spécifiée par son nom est activée.
abstract boolean isObjectModelSupported(String objectModel)
indique si le modèle d'objet spécifié est supporté par l'objet XPathFactory courant.
static XPathFactory newInstance()
crée une nouvelle instance de la classe XPathFactory en utilisant le modèle d'objet par défaut, la constante DEFAULT_OBJECT_MODEL_URI.
static XPathFactory newInstance(String uri)
crée une nouvelle instance de la classe XPathFactory en utilisant le modèle d'objet spécifié.
abstract XPath newXPath()
retourne une nouvelle instance de la classe XPath en utilisant le modèle d'objet déterminé lorsque l'objet XPathFactory a été instanciée.
abstract void setFeature(String name, boolean value)
détermine l'état d'une caractéristique pour les objets XPathFactory et XPath créés par la fabrique courante.
abstract void setXPathFunctionResolver(XPathFunctionResolver resolver)
assigne un objet XPathFunctionResolver.
abstract void setXPathVariableResolver(XPathVariableResolver resolver)
assigne un objet XPathVariableResolver.
Méthodes héritées de la classe java.lang.Object
clone, equals, finalize, getClass, hashCode, notify,
notifyAll, toString, wait, wait, wait

60 / Le paquetage javax.xml.namespace

Le paquetage javax.xml.namespace fournit des fonctionnalités pour gérer les espaces de noms XML.

Interface Description
NamespaceContext permet de lire seulement le traitement contextuel d'espaces de noms XML.
Classe Description
QName rerpésente un nom qualifié comme défini dans les spécifications XML : XML Schema Part2: Datatypes specification, Namespaces in XML et Namespaces in XML Errata.

61 / Le paquetage javax.xml.datatype

Le paquetage javax.xml.datatype fournit des classes pour la gestion des types de données XML.

Type XML Schema Type Java
xs:date XMLGregorianCalendar
xs:dateTime XMLGregorianCalendar
xs:duration Duration
xs:gDay XMLGregorianCalendar
xs:gMonth XMLGregorianCalendar
xs:gMonthDay XMLGregorianCalendar
xs:gYear XMLGregorianCalendar
xs:gYearMonth XMLGregorianCalendar
xs:time XMLGregorianCalendar
Modèle de donnée XQuery 1.0 et XPath 2.0 Type Java
xdt:dayTimeDuration Duration
xdt:yearMonthDuration Duration
Classe Description
DatatypeConstants contient les constantes et les valeurs fondamentales des types de données XML.
DatatypeConstants.Field représente six champs de la classe Duration.
DatatypeFactory est un fabricateur d'objets javax.xml.datatype.
Duration est une représentation immuable d'une période comme définie dans les spécifications XML Schema 1.0.
XMLGregorianCalendar est une représentation pour les types de données XML date/heure définis dans la spécification XML Schema 1.0.
Exception Description
DatatypeConfigurationException indique une erreur sévère de configuration.

62 / Le paquetage java.awt.event

Le paquetage java.awt.event fournit des classes et des interfaces à utiliser avec des composants AWT ou Swing capables de lancer des évnènements.

Les interfaces
ActionListener est employée pour la réception des actions sur un composant.
AdjustmentListener est employée pour la réception adjustment events.
AWTEventListener est employée pour la réception notification of events dispatched to objects that are instances of Component or MenuComponent or their subclasses.
ComponentListener est employée pour la réception component events.
ContainerListener est employée pour la réception container events.
FocusListener est employée pour la réception keyboard focus events on a component.
HierarchyBoundsListener est employée pour la réception ancestor moved and resized events.
HierarchyListener est employée pour la réception hierarchy changed events.
InputMethodListener est employée pour la réception input method events.
ItemListener est employée pour la réception item events.
KeyListener est employée pour la réception keyboard events (keystrokes).
MouseListener est employée pour la réception "interesting" mouse events (press, release, click, enter, and exit) on a component.
MouseMotionListener est employée pour la réception mouse motion events on a component.
MouseWheelListener est employée pour la réception mouse wheel events on a component.
TextListener est employée pour la réception text events.
WindowFocusListener est employée pour la réception WindowEvents, including WINDOW_GAINED_FOCUS and WINDOW_LOST_FOCUS events.
WindowListener est employée pour la réception window events.
WindowStateListener est employée pour la réception window state events.

Les classes
ActionEvent représente un événement sémantique qui indique qu'une action d'un composant défini s'est produit.
AdjustmentEvent représente une événement d'ajustement émis par des objets Adjustable.
AWTEventListenerProxy est une classe qui étend EventListenerProxy, spécifiquement pour l'ajout d'un objet AWTEventListener pour un masque d'événement spécifique.
ComponentAdapter représente une classe adaptatricepour la réception d'événements de composant.
ComponentEvent représente un événement de niveau inférieur qui indique un composant déplacé, une taille modifiée ou un changement de visibilité.
ContainerAdapter représente une classe adaptatrice pour la réception d'événements de conteneur.
ContainerEvent représente un événement de niveau inférieur qui indique que le contenu d'un conteneur à changé à cause du déplacement ou de l'ajout d'un composant.
FocusAdapter représente une classe adaptatrice pour la réception d'événements de focus.
FocusEvent A low-level event which indicates that a Component has gained or lost the input focus.
HierarchyBoundsAdapter représente une classe adaptatrice pour la réception d'événements d'un objet ancêtre déplacé ou redimensionné.
HierarchyEvent représente un événement qui indique un changement vers la hiérarchie de l'objet Component auquel un composant appartient.
InputEvent représente l'événement racine pour tous les événements d'entrée des composants.
InputMethodEvent contient l'information à propos du texte qui est obtenu à partir d'une méthode d'entrée.
InvocationEvent représente un événement qui exécute la méthode run() sur un objet Runnable, lorsq'il est acheminé par le thread expéditeur de l'événement AWT.
ItemEvent représente un événement sémantique qui indique qu'un item est selectionné ou déselectionné.
KeyAdapter représente une classe adaptatrice pour la réception des événements provenant du clavier.
KeyEvent représente un événement qui indique qu'une frappe sur un clavier s'est produite dans un composant.
MouseAdapter représente une classe adaptatrice pour la réception d'événements provenant d'un périphérique de pointage.
MouseEvent représente un événement qui indique qu'une action provenant d'un périphérique de pointage s'est produit dans un composant.
MouseMotionAdapter représente une classe adaptatrice pour la réception d'événements provenant d'un déplacement d'un périphérique de pointage.
MouseWheelEvent représente un événement qui indique que la molette d'un périphérique de pointage a été actionnée dans un composant.
PaintEvent représente un événement d'affichage d'un composant.
TextEvent représente un événement sémantique qui indique que le texte d'un objet a été modifié.
WindowAdapter représente une classe adaptatrice pour la réception d'événements provenant des fenêtres d'une application.
WindowEvent représente un événement d'un niveau inférieur qui indique qu'une fenêtre a changé de condition.