Une large partie de la norme ANSI du langage C est reprise dans Java.
Dans ce sous-chapitre nous expliquons les instructions Java en les comparant
à pascal-delphi. Voici la syntaxe d'une instruction en Java :
1.2 instruction complète
:
Toutes les instructions se terminent donc en Java par un point-virgule
" ; "
1.3 bloc - instruction composée
:
L'élément syntaxique
est aussi dénommé bloc ou instruction composée
au sens de la visibilité des variables Java.
1.4 visibilité dans un bloc - instruction :
Exemple de déclarations licites et de visibilité dans 3 blocs instruction imbriqués :
int a, b = 12; { int x , y = 8 ; { int z =12; x = z ; a = x + 1 ; { int u = 1 ; y = u - b ; } } } |
schéma d'imbrication des 3 blocs |
Nous examinons ci-dessous l'ensemble des instructions simples de
Java.
Java est un langage de la famille des langages hybrides, il possède
la notion d'instruction d'affectation.
Le symbole d'affectation en Java est " = ", soit par exemple :
x = y ; // x doit obligatoirement être un identificateur de variable. |
L'affectation peut être utilisée dans une expression :
soient les instruction suivantes :
simulation d'exécution Java :
instruction | valeur de a | valeur de b |
int a , b = 56 ; | a = ??? | b = 56 |
a = (b = 12)+8 ; | a = 20 | b = 12 |
2.2 Raccourcis et opérateurs d'affectation
Soit op un opérateur appartenant à l'ensemble
des opérateurs suivant { +, - , * , / , % , << , >>
, >>> , & , | , ^ }, il est possible d'utiliser sur une seule
variable le nouvel opérateur op= construit avec l'opérateur
op. Il s'agit plus d'un raccourci syntaxique que d'un
opérateur nouveau (seule sa traduction en bytecode diffère
: la traduction de a op= b devrait être plus courte en instructions
p-code que a = a op b, bien que les optimiseurs soient capables de
fournir le même code optimisé).
x op= y ; signifie en fait : x = x op y |
soient les instruction suivantes :
simulation d'exécution Java :
instruction | valeur de a | valeur de b |
int a , b = 56 ; | a = ??? | b = 56 |
a = -8 ; | a = -8 | b = 56 |
a += b ; | a = 48 | b = 56 |
b *= 3 ; | a = 48 | b = 168 |
Remarque :
3.1 les instructions conditionnelles
Syntaxe :
Schématiquement les conditions sont de deux sortes :
La définition de l'instruction conditionnelle de java est classiquement
celle des langages algorithmiques; comme en pascal l'expression doit
être de type booléen (différent du C), la notion d'instruction
a été définie plus haut.
Exemple d'utilisation du if..else (comparaison avec pascal)
Pascal-Delphi | Java |
var a , b , c : integer ; .... if b=0 then c := 1 else begin c := a / b; writeln("c = ",c); end; c := a*b ; if c <>0 then c:= c+b else c := a |
int a , b , c ; .... if ( b = = 0 ) c =1 ; else { c = a / b; System.out.println("c = " + c); } if ((c = a*b) != 0) c += b; else c = a; |
Remarques :
Exemple de parenthésage du else pendant
Pascal-Delphi | Java |
if Expr1 then begin if Expr2 then InstrA end else InstrB |
if ( Expr1 ) { if ( Expr2 ) InstrA ; } else InstrB |
Il s'agit ici comme dans le cas des opérateurs d'affectation d'une sorte de raccourci entre l'opérateur conditionnel if...else et l'affectation. Le but étant encore d'optimiser le bytecode engendré.
Syntaxe :
Où expression renvoie une valeur booléenne (le test), les deux termes valeur sont des expressions générales (variable, expression numérique, boolénne etc...) renvoyant une valeur de type quelconque.
Sémantique :
Exemple :
Sémantique de l'exemple avec un if..else :
question :
Syntaxe :
Où expression est une expression renvoyant une valeur booléenne (le test de l'itération).
Sémantique :
Identique à celle du pascal (instruction algorithmique tantque
.. faire .. ftant) avec le même défaut de fermeture
de la boucle.
Exemple de boucle while
Pascal-Delphi | Java |
while Expr do Instr | while ( Expr ) Instr ; |
while Expr do begin InstrA ; InstrB ; ... end |
while ( Expr ) { InstrA ; InstrB ; ... } |
Syntaxe :
Où expression est une expression renvoyant une valeur booléenne (le test de l'itération).
Sémantique :
"do Instr while ( Expr )" fonctionne comme l'instruction
algorithmique répéter Instr jusquà
non Expr.
Sa sémantique peut aussi être expliquée à l'aide d'une autre instruction Java while :
do Instr while ( Expr ) º Instr ; while ( Expr ) Instr |
Exemple de boucle do...while
Pascal-Delphi | Java |
repeat InstrA ; InstrB ; ... until not Expr |
do { InstrA ; InstrB ; ... } while ( Expr ) |
Syntaxe :
Sémantique :
Une boucle for contient 3 expressions for (Expr1 ; Expr2
; Expr3 ) Instr, d'une manière
générale chacune de ces expressions joue un rôle différent
dans l'instruction for. Une instruction for en Java (comme en C)
est plus puissante et plus riche qu'une boucle for dans d'autres
langages algorithmiques. Nous donnons ci-après une sémantique
minimale :
"for (Expr1 ; Expr2 ; Expr3
) Instr" fonctionne au minimum comme l'instruction algorithmique pour...
fpour.
Sa sémantique peut aussi être approximativement(*) expliquée à l'aide d'une autre instruction Java while :
for (Expr1 ; Expr2 ; Expr3 ) Instr º | Expr1 ; while ( Expr2 ) { Instr ; Expr3 } |
Exemples montrant la puissance du for
Pascal-Delphi | Java |
for i:=1 to 10 do begin InstrA ; InstrB ; ... end |
for ( i = 1;
i<=10; i++ ) { InstrA ; InstrB ; ... } |
i := 10; k := i; while (i>-450) do begin InstrA ; InstrB ; ... k := k+i; i := i-15; end |
for ( i = 10, k
= i ;i>-450 ; k += i , i -= 15) { InstrA ; InstrB ; ... } |
i := n; while i<>1 do if i mod 2 = 0 then i := i div 2 else i := i+1 |
for ( i = n ;i !=1 ; i % 2 == 0 ?
i /=2 : i++); // pas de corps de boucle ! |
Montrons exemple de boucle for dite boucle infinie :
for ( ; ; ); est équivalente à while (true); |
Voici une boucle ne possédant pas de variable de contrôle(f(x) est une fonction déjà déclarée) :
for (int n=0 ; Math.abs(x-y) < eps ; x = f(x) ); |
Terminons par une boucle for possédant deux variables de contrôle :
//inverse d'une suite de caractère
dans un tableau par permutation des deux extrêmes char [ ] Tablecar ={'a','b','c','d','e','f'} ; for ( i = 0 , j = 5 ; i<j ; i++ , j-- ) { char car ; car = Tablecar[i]; Tablecar[i ]= Tablecar[j]; Tablecar[j] = car; } |
Remarques récapitulatives sur la boucle for en Java :
Syntaxe :
Sémantique :
Une instruction break ne peut se situer qu'à l'intérieur
du corps d'instruction d'un bloc switch (le switch est traité
au paragraphe suivant), ou de l'une des trois itérations while,
do..while, for.
Lorsque break est présente dans l'une des trois itérations
while, do..while, for :
Exemple d'utilisation du break dans un for :
(recherche séquentielle dans un tableau)
int [ ] table= {12,-5,7,8,-6,6,4,78,2};
int elt = 4; for ( i = 0 ; i<8 ; i++ ) if (elt= =table[i]) break ; if (i = = 8)System.out.println("valeur : "+elt+" pas trouvée."); else System.out.println("valeur : "+elt+" trouvée au rang :"+i); |
Explications |
Syntaxe :
Sémantique :
Une instruction continue ne peut se situer qu'à l'intérieur
du corps d'instruction de l'une des trois itérations while,
do..while, for.
Lorsque continue est présente dans l'une des trois itérations
while, do..while, for :
Exemple d'utilisation du continue dans un for :
Rappelons qu'un for s'écrit généralement
: for (Expr1 ; Expr2 ; Expr3 ) Instr L'instruction continue présente dans une telle boucle for s'effectue ainsi :
for ( i = 0, n = 0 ; i<8 ; i++ , k = 2*n ) { if ( ta[i] = = 0 ) continue ; tb[n] = ta[i]; n++; } |
Explications |
Le déroulement est alors le suivant :
et la boucle se poursuit en fonction de la valeur de la condition de rebouclage.
Cette boucle recopie dans le tableau d'entiers tb les valeurs non nulles du tableau d'entiers ta.
Attention
Nous avons déjà signalé plus haut que l'équivalence
suivante entre un for et un while
for (Expr1 ; Expr2 ; Expr3 ) Instr º | Expr1 ; while ( Expr2 ) { Instr ; Expr3 } |
Voyons ce qu'il en est en reprenant l'exemple précédent. Essayons d'écrire la boucle while qui lui serait équivalente selon la définition générale. Voici ce que l'on obtiendrait :
for ( i = 0, n = 0
; i<8 ; i++ , k = 2*n ) { if ( ta[i] = = 0 ) continue ; tb[n] = ta[i]; n++; } |
i = 0; n = 0 ; while ( i<8 ) { if ( ta[i] = = 0 ) continue ; tb[n] = ta[i]; n++; i++ ; k = 2*n; } |
Dans le while le continue réexécute la condition de rebouclage i<8 sans exécuter l'expression i++ ; k = 2*n; (nous avons d'ailleurs ici une boucle infinie). Une boucle while équivalente au for précédent pourrait être la suivante :
for ( i = 0, n
= 0 ; i<8 ; i++ , k = 2*n ) { if ( ta[i] = = 0 ) continue ; tb[n] = ta[i]; n++; }
|
i = 0; n = 0 ; while ( i<8 ) { if ( ta[i] = = 0 ) { i++ ; k = 2*n; continue ; } tb[n] = ta[i]; n++; } |
Syntaxe :
bloc switch :
Sémantique :
La partie expression d'une instruction switch doit être une expression
ou une variable du type byte, char, int ou bien short.
La partie expression d'un bloc switch doit être une constante ou
une valeur immédiate du type byte, char, int
ou bien short.
switch <Epr1> s'appelle la partie sélection de l'instruction : il y a évaluation de <Epr1> puis selon la valeur obtenue le programme s'exécute en séquence à partir du case contenant la valeur immédiate égal. Il s'agit donc d'un déroutement du programme dès que <Epr1> est évaluée vers l'instruction étiquetée par le case <Epr1> associé.
Exemples :
Java - source | Résultats de l'exécution |
int x = 10;
switch (x+1) |
>> case 11 >> case 12 >> default |
int x = 11;
switch (x+1) |
>> case 12 >> default |
Nous voyons qu'après que (x+1) soit évalué, selon sa valeur (11 ou 12) le programme va se dérouter vers case 11 ou case 12 et continue en séquence (suite des instructions du bloc switch)
Utilisée telle quelle, cette instruction n'est pas structurée
et donc son utilisation n'est pas conseillée sous cette forme. Par
contre elle est très souvent utilisée avec l'instruction break
afin de simuler le comportement de l'instruction structurée case..of
du pascal (ci-dessous deux écritures équivalentes) :
:
Exemple de switch..case..break
Pascal-Delphi | Java |
var x : char ; .... case x of 'a' : InstrA; 'b' : InstrB; else InstrElse end; |
char x ; .... switch (x) { case 'a' : InstrA ; break; case 'b' : InstrB ; break; default : InstrElse; } |
Dans ce cas le déroulement de l'instruction switch après déroutement vers le bon case, est interrompu par le break qui renvoie la suite après la fin du bloc switch. Une telle utilisation correspond à une utilisation de if...else imbriqués (donc utilisation structurée) mais devient plus lisible que les if ..else imbriqués, elle est donc fortement conseillée dans ce cas.
En reprenant les deux exemples précédents :
Exemples :
Java - source | Résultats de l'exécution |
int x = 10;
switch (x+1) |
>> case 11 |
int x = 11;
switch (x+1) |
>> case 12 |
Programmes équivalents switch et if...else :
Java - switch | Java - if...else |
int x = 10;
switch (x+1) |
int x = 10;
if (x+1= = 11)System.out.println(">> case 11");
|
7. try...catch
Nous reviendrons plus loin sur les exceptions et l'instruction try..catch. Nous donnons ici la syntaxe d'une version simple et nous indiquons que sa sémantique est semblable à celle du bloc try..except de Delphi. Sachons pour l'instant que Java dispose d'un mécanisme puissant présent dans les langages robustes Ada, C++, Delphi pour intercepter et traiter les erreurs ou incidents survenant dans un bloc d'instruction.
L'instruction try...catch sert à traiter de tels incidents, elle dispose d'un bloc try (pour les instructions à protéger)et d'un ou plusieurs blocs catch (pour divers genres de traitement en cas d'incidents).
try {
BLOC à protéger
}
catch (TypeErreur1 Err1) {
TRAITEMENT d'une erreur
du type TypeErreur1
}
catch (TypeErreur2 Err2) {
TRAITEMENT d'une erreur
du type TypeErreur2
}
...
catch (TypeErreurX ErrX) {
TRAITEMENT d'une erreur
du type TypeErreurX
}
Ci-dessous une exemple permettant d'intercepter une erreur dans la division de l'enteir x par l'entier y :
Exemple de try...catch
Pascal-Delphi | Java |
var x , y : integer; try x := 1; y := 0; Memo.lines.add("division ="+x div y); except on Err : EIntError do begin Memo.lines.add("Calcul impossible."); Memo.lines.add(Err.message); end end; |
int x , y ; try { x = 1; y = 0; System.out.println( "division ="+x/y); } catch (ArithmeticException Err) { System.out.println("Calcul impossible."); System.out.println(Err.getMessage()); } |