Cours avance de JAVA pour reviser ensemble
Cours avancé de JAVA pour réviser ensemble
…
2.1. Les concepts de base
La plate-forme Java utilise quelques notions base dans sa mise en œuvre notamment :
- La compilation du code source dans un langage indépendant de la plate-forme d'exécution : le byte code
- l'exécution du byte code par une machine virtuelle nommée JVM (Java Virtual Machine)
- la notion de package qui permet d'organiser les classes
- le classpath qui permet de préciser au compilateur et à la JVM où elle peut trouver les classes requises par l'application
- le packaging des classes compilés dans une archive de déploiement nommé jar (Java ARchive)
2.1.1. La compilation et l'exécution
Un programme Java est composé d'un ou plus généralement plusieurs fichiers source. N'importe quel éditeur de texte peut être utilisé pour éditer un fichier source Java.
Ces fichiers source possèdent l'extension .java. Ils peuvent contenir une ou plusieurs classes ou interfaces mais il ne peut y avoir qu'une seule classe ou interface déclarée publique par fichier. Le nom de ce fichier source doit obligatoirement correspondre à la casse prêt au nom de cette entité publique suivi de l'extension .java
Il est nécessaire de compiler le source pour le transformer en J-code ou byte-code Java qui sera lui exécuté par la machine virtuelle. Pour être compilé, le programme doit être enregistré au format de caractères Unicode : une conversion automatique est faite par le JDK si nécessaire.
Un compilateur Java, par exemple l'outil javac fourni avec le JDK est utilisé pour compiler chaque fichier source en fichier de classe possédant l'extension .class. Cette compilation gère pour chaque fichier source un ou plusieurs fichiers .class qui contiennent du byte code.
Exemple :
public class MaClasse {
public static void main(String[] args) { System.out.println("Bonjour"); }
}
Résultat :
C:\TEMP>javac MaClasse.java
C:\TEMP>dir MaClas*
Volume in drive C has no label. Volume Serial Number is 1E06-2R43
Directory of C:\TEMP
31/07/2007 13:34 417 MaClasse.class
31/07/2007 13:34 117 MaClasse.java
Le compilateur génère autant de fichier .class que de classes et interfaces définies dans chaque fichier source.
Exemple :
public class MaClasse {
public static void main(String[] args) { System.out.println("Bonjour"); }
}
class MonAutreClasse {
public static void afficher(String message) { System.out.println(message); }
}
Résultat :
C:\TEMP>dir *.class
Volume in drive C has no label. Volume Serial Number is 1E06-2R43
Directory of C:\TEMP
31/07/2007 13:40 417 MaClasse.class
31/07/2007 13:40 388 MonAutreClasse.class
Pour exécuter une application, la classe servant de point d'entrée doit obligatoirement contenir une méthode ayant la signature public static void main(String[] args). Il est alors possible de fournir cette classe à la JVM qui va charger le ou les fichiers .class utiles à l'application et exécuter le code.
Exemple :
C:\TEMP>java MaClasse Bonjour
Pour les classes anonymes, le compilateur génère un nom de fichier constitué du nom de la classe englobante suffixée par $ et un numéro séquentiel.
...
Une classe anonyme peut elle-même définir une classe : dans ce cas le nom du fichier de classe sera celui de la classe anonyme suffixé par le caractère $ et le nom de la classe
Exemple :
import javax.swing.JFrame; import java.awt.event.*;
public class MonApplication {
public static void main(String[] args) { MaFenetre f = new MaFenetre(); f.afficher();
}
}
class MaFenetre {
JFrame mainFrame = null;
2.1.2. Les packages
Les fichiers sources peuvent être organisés en package. Les packages définissent une hiérarchie de noms, chaque nom étant séparé par le caractère point. Le nom d'un package est lié à une arborescence de sous répertoire correspondant à ce nom.
Ceci permet de structurer les sources d'une application car une application peut rapidement contenir plusieurs centaines voir milliers de fichiers source. Les packages permettent aussi d'assurer l'unicité d'une classe grâce à son nom pleinement qualifié (nom du package suivi du caractère «.» suivi du nom de la classe).
L'API Java est organisée en packages répartis en trois grands ensembles :
- Packages standards : ce sont les sous packages du package java
- Packages d'extensions : ce sont les sous packages du package javax
- Packages tiers : ces packages concernant notamment Corba et XML
...
Le package est précisé dans le fichier source grâce à l'instruction package. Le fichier doit donc dans ce cas être stocké dans une arborescence de répertoires qui correspond au nom du package.
Exemple :
package com.jmdoudoux.test; public class MaCLasseTest {
public static void main() {
System.out.println("Bonjour");
}
}
Si les sources de l'application sont dans le répertoire C:\Documents and Settings\jm\workspace\Tests, alors le fichier MaCLasseTest.java doit être dans le répertoire C:\Documents and Settings\jm\workspace\Tests\com\jmdoudoux\test.
Si aucun package n'est précisé, alors c'est le package par défaut (correspondant au répertoire courant) qui est utilisé. Ce n'est pas une bonne pratique d'utiliser le package par défaut sauf pour des tests.
Dans le code source, pour éviter d'avoir à utiliser les noms pleinement qualifiés des classes, il est possible d'utiliser l'instruction import suivi d'un nom de package suivi d'un caractère «.» et du nom d'une classe ou du caractère «*»
Exemple :
import javax.swing.JFrame; import java.awt.event.*;
Remarque : par défaut le package java.lang est toujours importé par le compilateur.
2.1.3. Le déploiement sous la forme d'un jar
Il est possible de créer une enveloppe qui va contenir tous les fichiers d'une application Java ou une portion de cette application dans un fichier .jar (Java archive). Ceci inclus : l'arborescence des packages, les fichiers .class, les fichiers de ressources (images, configuration, ...), ... Un fichier .jar est physiquement une archive de type Zip qui contient tous ces éléments.
L'outil jar fourni avec le jdk permet de manipuler les fichiers jar.
Exemple :
C:\TEMP>jar cvf MonApplication.jar *.class
manifest ajoutÚ
ajout : MaFenetre$1$MonAutreClasse.class (entrÚe = 549) (sortie = 361) (34% comp
ressÚs)
ajout : MaFenetre$1.class (entrÚe = 555) (sortie = 368) (33% compressÚs)
ajout : MaFenetre.class (entrÚe = 687) (sortie = 467) (32% compressÚs)
ajout : MonApplication.class (entrÚe = 334) (sortie = 251) (24% compressÚs)
Le fichier .jar peut alors être diffusé et exécuté si il contient au moins une classe avec une méthode main().
Exemple : déplacement du jar pour être sûre qu'il n'utilise pas de classe du répertoire et exécution
C:\TEMP>copy MonApplication.jar .. 1 file(s) copied.
C:\TEMP>cd ..
C:\>java -cp MonApplication.jar MonApplication
Remarque : un fichier .jar peut contenir plusieurs packages.
Le fichier jar peut inclure un fichier manifest qui permet de préciser des informations d'exécution sur le fichier jar (classe principale à exécuter, classpath, ...) : ceci permet d'exécuter directement l'application en double cliquant sur le fichier .jar.
2.1.4. Le classpath
A l'exécution, la JVM et les outils du JDK recherchent les classes requises dans :
- Les classes de la plate-forme Java (stockées dans le fichier rt.jar)
- Les classes d'extension de la plate-forme Java
- Le classpath
Important : il n'est pas recommandé d'ajouter des classes ou des bibliothèques dans les sous répertoires du JDK.
La notion de classpath est importante car elle est toujours utilisée quelque soit l'utilisation qui est fait de Java (ligne de commandes, IDE, script Ant, ...). Le classpath est sûrement la notion de base en Java qui pose le plus de soucis aux développeurs inexpérimentés en Java mais sa compréhension est absolument nécessaire.
Le classpath permet de préciser au compilateur et à la JVM où ils peuvent trouver les classes dont ils ont besoin pour la compilation et l'exécution d'une application. C'est un ensemble de chemins vers des répertoires ou des fichiers .jar dans lequel l'environnement d'exécution Java recherche les classes (celles de l'application mais aussi celles de tiers) et éventuellement des fichiers de ressources utiles à l'exécution de l'application. Ces classes ne concernent pas celles fournies par l'environnement d'exécution incluses dans le fichier rt.jar qui est implicitement utilisé par l'environnement.
Le classpath est constitué de chemins vers des répertoires et/ou des archives sous la forme de fichiers .jar ou .zip. Chaque élément du classpath peut donc être :
- Pour des fichiers .class : le répertoire qui contient l'arborescence des sous répertoires des packages ou les fichiers .class (si ceux-ci sont dans le package par défaut)
- Pour des fichiers .jar ou .zip : le chemin vers chacun des fichiers
Les éléments du classpath qui ne sont pas des répertoires ou des fichiers .jar ou .zip sont ignorés.
Ces chemins peuvent être absolus ou relatifs. Chaque chemin est séparé par un caractère spécifique au système d'exploitation utilisé : point virgule sous Windows et deux points sous Unix par exemple.
Exemple sous Windows :
.;C:\java\tests\bin;C:\java\lib\log4j-1.2.11.jar;"C:\Program Files\tests\tests.jar"
Dans cet exemple, le classpath est composé de quatre entités :
- le répertoire courant
- le répertoire C:\java\tests\bin
- le fichier C:\java\lib\log4j-1.2.11.jar
- le fichier C:\Program Files\tests\tests.jar qui est entouré par des caractères " parce qu'il y a un espace dans son chemin
Remarque : sous Windows, il est possible d'utiliser le caractère / ou \ comme séparateur d'arborescence de répertoires.
Par défaut, si aucun classpath n'est défini, le classpath est composé uniquement du répertoire courant. Une redéfinition du classpath (avec l'option -classpath ou -cp ou la variable d'environnement système CLASSPATH) inhibe cette valeur par défaut.
La recherche d'une classe se fait dans l'ordre des différents chemins du classpath : cet ordre est donc important surtout si une bibliothèque est précisée dans deux chemins. Dans ce cas, c'est le premier trouvé dans l'ordre précisé qui sera utilisé, ce qui peut être à l'origine de problèmes.
Le classpath peut être défini à plusieurs niveaux :
- Au niveau global : il faut utiliser la variable d'environnement système CLASSPATH
Exemple sous Windows
Développons en Java 43
Il faut utiliser la commande set pour définir la variable d'environnement CLASSPATH. Le séparateur entre chaque élément du classpath est le caractère point virgule. Il ne faut pas mettre d'espace entre le signe égal.
Exemple :
set CLASSPATH=C:\java\classes;C:\java\lib;C:\java\lib\mysql.jar;.
Sous Windows 9x : il est possible ajouter une ligne définissant la variable d'environnement dans le fichier autoexec.bat :
Exemple :
set CLASSPATH=.;c:\java\lib\mysql.jar;%CLASSPATH%
Sous Windows NT/2000/XP : il faut lancer l'application démarrer/paramètre/panneau de configuration/système, ouvrir l'onglet "avancé" et cliquer sur le bouton "Variables d'environnement". Il faut ajouter ou modifier la variable CLASSPATH avec comme valeur les différents éléments du classpath séparés chacun par un caractère point virgule
Exemple sous Unix (interpréteur bash)
Exemple :
CLASSPATH=.:./lib/log4j-1.2.11.jar export CLASSPATH;
- Au niveau spécifique : en utilisant l'option -classpath ou -cp du compilateur javac et de la machine virtuelle
- Au niveau d'un script de lancement : cela permet de définir la variable d'environnement CLASSPATH uniquement pour le contexte d'exécution du script
L'utilisation de la variable système CLASSPATH est pratique car elle évite d'avoir à définir le classpath pour compiler ou exécuter mais c'est une mauvaise pratique car cela peut engendrer des problèmes :
- peut vite devenir un casse tête lorsque le nombre d'applications augmente
- ce n'est pas portable d'une machine à une autre
- peut engendrer des conflits de version entre applications où entre bibliothèques
Si la JVM ou le compilateur n'arrive pas à trouver une classe dans le classpath, une exception de type java.lang.ClassNotFoundException à la compilation ou java.lang.NoClassDefFoundError à l'exécution est levée.
Exemple :
package com.jmdoudoux.test; public class MaCLasseTest {
public static void main() {
System.out.println("Bonjour");
}
}
Le fichier MaCLassTest.class issu de la compilation est stocké dans le répertoire C:\Documents and Settings\jm\workspace\Tests\com\jmdoudoux\test
En débutant en Java, il est fréquent de se placer dans le répertoire qui contient le fichier .class et de lancer la JVM.
Exemple :
C:\Documents and Settings\jmd\workspace\Tests\com\jmdoudoux\test>java MaCLasseTe st
Exception in thread "main" java.lang.NoClassDefFoundError: MaCLasseTest (wrong n
ame: com/jmdoudoux/test/MaCLasseTest)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Cela ne fonctionne pas car la JVM cherche à partir du répertoire courant (défini dans le classpath par défaut) une classe qui soit définie dans le package par défaut (aucun nom de package précisé). Hors dans l'exemple, la classe est défini dans le package com.jmdoudoux.test.
Une autre erreur assez fréquente est de se déplacer dans le répertoire qui contient le premier répertoire du package
Exemple :
C:\Documents and Settings\jm\workspace\Tests\com\jmdoudoux\test>cd ../../..
C:\Documents and Settings\jm\workspace\Tests>java MaCLasseTest Exception in thread "main" java.lang.NoClassDefFoundError: MaCLasseTest
Dans ce cas, cela ne fonctionne pas car le nom de la classe n'est pas pleinement qualifié
Exemple :
C:\Documents and Settings\jmd\workspace\Tests>java com.jmdoudoux.test.MaCL asseTest
Bonjour
En précisant le nom pleinement qualifié de la classe, l'application est exécutée.
Si le classpath est redéfini, il ne faut pas oublier d'ajouter le répertoire courant au besoin en utilisant le caractère point. Cette pratique n'est cependant pas recommandée.
Exemple :
C:\Documents and Settings\jmd\workspace\Tests>java -cp test.jar com.jmdoudoux.te st.MaCLasseTest
Exception in thread "main" java.lang.NoClassDefFoundError: com/jmdoudoux/test/Ma CLasseTest
C:\Documents and Settings\jmd\workspace\Tests>java -cp test.jar;. com.jmdoudoux. test.MaCLasseTest
Bonjour
Les IDE fournissent tous des facilités pour gérer le classpath. Cependant en débutant, il est préférable d'utiliser les outils en ligne de commande pour bien comprendre le fonctionnement du classpath.
2.1.4.1. La définition du classpath pour exécuter une application
Dans cette section, une application est contenue dans le répertoire c:\java\tests. Elle est composée de la classe com.jmdoudoux.test.MaClasse.java.
…
- La syntaxe et les éléments de bases de Java
Ce chapitre contient plusieurs sections :
¨ Les règles de base : cette section présente les règles syntaxiques de base de Java.
¨ Les identificateurs : cette section présente les règles de composition des identificateurs.
¨ Les commentaires : cette section présente les différentes formes de commentaires de Java.
¨ La déclaration et l'utilisation de variables : cette section présente la déclaration des variables, les types élémentaires, les formats des type élémentaires, l'initialisation des variables, l'affectation et les comparaisons.
¨ Les opérations arithmétiques : cette section présente les opérateurs arithmétique sur les entiers et les flottants et les opérateurs d'incrémentation et de décrémentation.
¨ La priorité des opérateurs : cette section présente la priorité des opérateurs.
¨ Les structures de contrôles : cette section présente les instructions permettant la réalisation de boucles, de branchements conditionnels et de débranchements.
¨ Les tableaux : cette section présente la déclaration, l'initialisation explicite et le parcours d'un tableau
¨ Les conversions de types : cette section présente la conversion de types élémentaires.
¨ La manipulation des chaînes de caractères : cette section présente la définition et la manipulation de chaîne de caractères (addition, comparaison, changement de la casse ... ).
3.1. Les règles de base
Java est sensible à la casse.
Les blocs de code sont encadrés par des accolades. Chaque instruction se termine par un caractère ';' (point virgule). Une instruction peut tenir sur plusieurs lignes :
Exemple :
char code = 'D';
L'indentation est ignorée du compilateur mais elle permet une meilleure compréhension du code par le programmeur.
3.2. Les identificateurs
Chaque objet, classe, programme ou variable est associé à un nom : l'identificateur qui peut se composer de tous les caractères alphanumériques et des caractères _ et $. Le premier caractère doit être une lettre, le caractère de soulignement ou le signe dollar.
Rappel : Java est sensible à la casse.
...
3.4. La déclaration et l'utilisation de variables
3.4.1. La déclaration de variables
Une variable possède un nom, un type et une valeur. La déclaration d'une variable doit donc contenir deux choses : un nom et le type de données qu'elle peut contenir. Une variable est utilisable dans le bloc ou elle est définie.
La déclaration d'une variable permet de réserver la mémoire pour en stocker la valeur. Le type d'une variable peut être :
- soit un type élémentaire dit aussi type primitif déclaré sous la forme type_élémentaire variable;
- soit une classe déclarée sous la forme classe variable ;
Exemple :
long nombre; int compteur; String chaine;
Rappel : les noms de variables en Java peuvent commencer par une lettre, par le caractère de soulignement ou par le signe dollar. Le reste du nom peut comporter des lettres ou des nombres mais jamais d'espaces.
Il est possible de définir plusieurs variables de même type en séparant chacune d'elles par une virgule.
Exemple :
int jour, mois, annee ;
Java est un langage à typage rigoureux qui ne possède pas de transtypage automatique lorsque ce transtypage risque de conduire à une perte d'information.
Pour les objets, il est nécessaire en plus de la déclaration de la variable de créer un objet avant de pouvoir l'utiliser. Il faut réserver de la mémoire pour la création d'un objet ( remarque : un tableau est un objet en Java ) avec l'instruction new. La libération de la mémoire se fait automatiquement grâce au garbage collector.
Exemple :
MaClasse instance; // déclaration de l'objet
instance = new MaClasse(); // création de l'objet
OU MaClasse instance = new MaClasse(); // déclaration et création de l'objet
Exemple :
int[] nombre = new int[10];
Il est possible en une seule instruction de faire la déclaration et l'affectation d'une valeur à une variable ou plusieurs variables.
Exemple :
int i=3 , j=4 ;
3.4.2. Les types élémentaires
Les types élémentaires ont une taille identique quelque soit la plate-forme d'exécution : c'est un des éléments qui permet à Java d'être indépendant de la plate-forme sur lequel le code s'exécute.
...
3.4.3. Le format des types élémentaires
Le format des nombres entiers :
Il existe plusieurs formats pour les nombres entiers : les types byte, short, int et long peuvent être codés en décimal, hexadécimal ou octal. Pour un nombre hexadécimal, il suffit de préfixer sa valeur par 0x. Pour un nombre octal, le nombre doit commencer par un zéro. Le suffixe l ou L permet de spécifier que c'est un entier long.
Le format des nombres décimaux :
Il existe plusieurs formats pour les nombres décimaux : les types float et double stockent des nombres flottants : pour être reconnus comme tel ils doivent posséder soit un point, un exposant ou l'un des suffixes f, F, d, D. Il est possible de préciser des nombres qui n'ont pas le partie entière ou pas de partie décimale.
Exemple :
float pi = 3.141f; double valeur = 3d;
float flottant1 = +.1f , flottant2 = 1e10f;
Par défaut un littéral représentant une valeur décimale est de type double : pour définir un littéral représentant une valeur décimale de type float il faut le suffixer par la lettre f ou F.
Attention :
float pi = 3.141; // erreur à la compilation float pi = 3.141f; // compilation sans erreur
Exemple :
double valeur = 1.1;
Le format des caractères :
Un caractère est codé sur 16 bis car il est conforme à la norme Unicode. Il doit être entouré par des apostrophes. Une valeur de type char peut être considérée comme un entier non négatif de 0 à 65535. Cependant la conversion implicite par affectation n'est pas possible.
Exemple :
/* test sur les caractères */
class test1 {
public static void main (String args[]) { char code = 'D';
int index = code - 'A';
System.out.println("index = " + index);
}
}
3.4.4. L'initialisation des variables
Exemple :
int nombre; // déclaration nombre = 100; //initialisation
OU int nombre = 100; //déclaration et initialisation
En Java, toute variable appartenant à un objet (définie comme étant un attribut de l'objet) est initialisée avec une valeur par défaut en accord avec son type au moment de la création. Cette initialisation ne s'applique pas aux variables locales des méthodes de la classe.
Les valeurs par défaut lors de l'initialisation automatique des variables d'instances sont :
Type Valeur par défaut
boolean false
byte, short, int, long 0
float, double 0.0
char \u000
classe null
Remarque : Dans une applet, il est préférable de faire les déclarations et initialisation dans la méthode init().
3.4.5. L'affectation
le signe = est l'opérateur d'affectation et s'utilise avec une expression de la forme variable = expression. L'opération d'affectation est associative de droite à gauche : il renvoie la valeur affectée ce qui permet d'écrire :
x = y = z = 0;
...
3.5. Les opérations arithmétiques
Les opérateurs arithmétiques se notent + (addition), - (soustraction), * (multiplication), / (division) et % (reste de la division). Ils peuvent se combiner à l'opérateur d'affectation
Exemple :
nombre += 10;
3.5.1. L'arithmétique entière
Pour les types numériques entiers, Java met en oeuvre une sorte de mécanisme de conversion implicite vers le type int appelée promotion entière. Ce mécanisme fait partie des règles mise en place pour renforcer la sécurité du code.
Exemple :
short x= 5 , y = 15;
x = x + y ; //erreur à la compilation
Incompatible type for =. Explicit cast needed to convert int to short. x = x + y ; //erreur à la compilation
1 error
Les opérandes et le résultat de l'opération sont convertis en type int. Le résultat est affecté dans un type short : il y a donc risque de perte d'informations et donc erreur à la compilation est émise. Cette promotion évite un débordement de capacité sans que le programmeur soit pleinement conscient du risque : il est nécessaire, pour régler le problème, d'utiliser une conversion explicite ou cast
Exemple :
x = (short) ( x + y );
Il est nécessaire de mettre l'opération entre parenthèse pour que ce soit son résultat qui soit converti car le cast a une priorité plus forte que les opérateurs arithmétiques.
La division par zéro pour les types entiers lève l'exception ArithmeticException
Exemple :
/* test sur la division par zero de nombres entiers */
class test3 {
public static void main (String args[]) {
int valeur=10;
double résultat = valeur / 0;
System.out.println("index = " + résultat);
}
}
3.5.2. L'arithmétique en virgule flottante
Avec des valeurs float ou double, la division par zéro ne produit pas d'exception mais le résultat est indiqué par une valeur spéciale qui peut prendre trois états :
- indéfini : Float.NaN ou Double.NaN (not a number)
- indéfini positif : Float.POSITIVE_INFINITY ou Double.POSITIVE_INFINITY, + o0
- indéfini négatif : Float.NEGATIVE_INFINITY ou Double.NEGATIVE_INFINITY, - o0
Conformément à la norme IEEE754, ces valeurs spéciales représentent le résultat d'une expression invalide NaN, une valeur supérieure au plafond du type pour infini positif ou négatif.
3.5.3. L'incrémentation et la décrémentation
Les opérateurs d'incrémentation et de décrémentation sont : n++ ++n n-- --n
Si l'opérateur est placé avant la variable (préfixé), la modification de la valeur est immédiate sinon la modification n'a lieu qu'à l'issu de l'exécution de la ligne d'instruction (postfixé)
L'opérateur ++ renvoie la valeur avant incrémentation s'il est postfixé, après incrémentation s'il est préfixé.
Exemple :
System.out.println(x++); // est équivalent à System.out.println(x); x = x + 1;
System.out.println(++x); // est équivalent à x = x + 1; System.out.println(x);
Exemple :
/* test sur les incrementations prefixees et postfixees */
class test4 {
public static void main (String args[])
int n1=0; int n2=0; {
System.out.println("n1 = " + n1=n2++; n1 + " n2 = " + n2);
System.out.println("n1 = " + n1=++n2; n1 + " n2 = " + n2);
System.out.println("n1 = " +
n1=n1++; //attention n1 + " n2 = " + n2);
System.out.println("n1 = " + n1 + " n2 = " + n2);
}
}
Résultat :
int n1=0;
int n2=0; // n1=0 n2=0
n1=n2++; // n1=0 n2=1
n1=++n2; // n1=2 n2=2
n1=n1++; // attention : n1 ne change pas de valeur
3.7. Les structures de contrôles
Comme quasi totalité des langages de développement orienté objets, Java propose un ensemble d'instructions qui permettent de d'organiser et de structurer les traitements. L'usage de ces instructions est similaire à celui rencontré dans leur équivalent dans d'autres langages.
3.7.1. Les boucles
while ( boolean ) {
... // code a exécuter dans la boucle
}
Le code est exécuté tant que le booléen est vrai. Si avant l'instruction while, le booléen est faux, alors le code de la boucle ne sera jamais exécuté
Ne pas mettre de ; après la condition sinon le corps de la boucle ne sera jamais exécuté
do {
...
} while ( boolean );
Cette boucle est au moins exécuté une fois quelque soit la valeur du booléen;
for ( initialisation; condition; modification) {
...
} Exemple :
for (i = 0 ; i < 10; i++ ) { ....} for (int i = 0 ; i < 10; i++ ) { ....} for ( ; ; ) { ... } // boucle infinie
L'initialisation, la condition et la modification de l'index sont optionnelles.
Dans l'initialisation, on peut déclarer une variable qui servira d'index et qui sera dans ce cas locale à la boucle.
Il est possible d'inclure plusieurs traitements dans l'initialisation et la modification de la boucle : chacun des traitements doit être séparé par une virgule.
Exemple :
for (i = 0 , j = 0 ; i * j < 1000;i++ , j+= 2) { ....}
La condition peut ne pas porter sur l'index de la boucle :
Exemple :
boolean trouve = false;
for (int i = 0 ; !trouve ; i++ ) {
if ( tableau[i] == 1 )
trouve = true;
... //gestion de la fin du parcours du tableau
}
Il est possible de nommer une boucle pour permettre de l'interrompre même si cela est peu recommandé :
Exemple :
int compteur = 0; boucle:
while (compteur < 100) {
for(int compte = 0 ; compte < 10 ; compte ++) { compteur += compte; System.out.println("compteur = "+compteur); if (compteur> 40) break boucle;
}
}
3.7.2. Les branchements conditionnels
if (boolean) {
...
} else if (boolean) {
...
} else {
...
}
switch (expression) { case constante1 : instr11; instr12; break;
case constante2 : ...
default :
...
}
On ne peut utiliser switch qu'avec des types primitifs d'une taille maximum de 32 bits (byte, short, int, char).
Si une instruction case ne contient pas de break alors les traitements associés au case suivant sont exécutés. Il est possible d'imbriquer des switch
L'opérateur ternaire : ( condition ) ? valeur-vrai : valeur-faux
Exemple :
if (niveau == 5) // equivalent à total = (niveau ==5) ? 10 : 5; total = 10;
else total = 5 ;
System.out.println((sexe == " H ") ? " Mr " : " Mme ");
3.7.3. Les débranchements
break : permet de quitter immédiatement une boucle ou un branchement. Utilisable dans tous les contrôles de flot continue : s'utilise dans une boucle pour passer directement à l'itération suivante
break et continue peuvent s'exécuter avec des blocs nommés. Il est possible de préciser une étiquette pour indiquer le point de retour lors de la fin du traitement déclenché par le break.
Une étiquette est un nom suivi d'un deux points qui définit le début d'une instruction.
3.8. Les tableaux
Ils sont dérivés de la classe Object : il faut utiliser des méthodes pour y accéder dont font partie des messages de la classe Object tel que equals() ou getClass().