|
|
Le but de ce document est de présenter les éléments de syntaxe du langage Java : les types primitifs, les opérateurs arithmétiques et logiques, les structures de contrôle, ...
|
|
|
|
|
|
# Variables de types primitifs ou tableaux
|
|
|
|
|
|
En Java, le terme **primitif** se rapporte aux types de données qui peuvent avoir une réprésentation immédiate en mémoire :
|
|
|
- un entier
|
|
|
- un réel
|
|
|
- un booléen
|
|
|
- un caractère
|
|
|
|
|
|
Les **tableaux** ne sont pas des types primitifs, mais ne peuvent pas non plus être considérés complètement comme des types objets.
|
|
|
|
|
|
Tous les autres types sont **objets**.
|
|
|
|
|
|
Les valeurs de type primitif ont une taille indépendante de la plateforme d’exécution du code.
|
|
|
|
|
|
## Types _entier_ et _flottant_
|
|
|
|
|
|
Le tableau ci-dessous récapitule les types entiers, leur taille et leurs valeurs extrêmes.
|
|
|
|
|
|
| Type | Taille (en bits) | Valeur minimale | Valeur maximale |
|
|
|
| ------ | ------ | ------ | ------ |
|
|
|
| byte | 8 | -128 | 127 |
|
|
|
| short | 16 |-32768 | 32767 |
|
|
|
| int | 32 |-2^31 | 2^31 - 1 |
|
|
|
| long | 64 |-2^63 | 2^63 - 1 |
|
|
|
|
|
|
> :warning: Contrairement au langage C, tous les types entiers sont **signés** (les nombres négatifs sont codés en complément à 2).
|
|
|
|
|
|
> :pencil: Comme en langage C, on peut exprimer un entier (par exemple 15) en décimal (`15`), en octal (`017`) ou en hexadécimal (`0x0F`).
|
|
|
|
|
|
|
|
|
Le tableau suivant donne les mêmes informations que le précédent pour les types flottants (codés conformément à la norme _IEEE 754_).
|
|
|
|
|
|
Deux notations sont utilisables : décimale (`-3.25`) ou exponentielle (`-3.232323E-12`, le `E` peut être aussi écrit `e`).
|
|
|
|
|
|
| Type | Taille (en bits) | Chiffres significatifs | Valeur positive minimale | Valeur positive maximale |
|
|
|
| ------ | ------ | ------ | ------ | ------ |
|
|
|
| float | 32 | 7 | 1.423984E-45 | 3.402823E38|
|
|
|
| double | 32 | 15 | 4.94065645841246E-234 | 1.79769313486231E308 |
|
|
|
|
|
|
|
|
|
## Les types _booléen_ et _caractère_
|
|
|
|
|
|
Le type booléen est désigné par le mot-clé `boolean` et représente un **état logique vrai ou faux**.
|
|
|
|
|
|
Il existe deux constantes qui peuvent être valeurs d’une variable de type booléen : `true` et `false`.
|
|
|
|
|
|
Le type caractère est désigné par le mot-clé `char`. Un caractère est codé sur 16 bits, sa valeur est le code Unicode UTF-16 du caractère.
|
|
|
|
|
|
On peut désigner une valeur de type `char` :
|
|
|
|
|
|
- par le caractère entre `'`, comme par exemple `'a'`
|
|
|
- par son code _Unicode_ sous la forme `\uxxxx` (où `xxxx` est exprimé en hexadécimal), comme par exemple `\u0066` (qui représente également la lettre `a`).
|
|
|
|
|
|
Il est possible d'effectuer des opérations arithmétiques sur des caractères pour passer d'un caractère à un autre ou pour changer la casse. Par exemple , `'a'+1` représente le caractère `'b'`.
|
|
|
|
|
|
## Le type _tableau_
|
|
|
|
|
|
Le type tableau est désigné par le **type de ses éléments suivi de `[]`**.
|
|
|
|
|
|
Par exemple, `byte[]` représente un tableau d’octets.
|
|
|
|
|
|
## Le mot-clé `void`
|
|
|
|
|
|
`void` n'a pas la même interprétation que dans le langage C. Il est utilisé uniquement en **valeur de retour de méthode** pour indiquer que la méthode ne renvoie pas de résultat.
|
|
|
|
|
|
# Déclaration de variables, affectation
|
|
|
|
|
|
La déclaration d’un entier, d’un flottant, d’un booléen ou d’un caractère s’effectue de la même manière qu’en C.
|
|
|
|
|
|
Il est possible de déclarer une variable n’importe où à l’intérieur d’un **bloc d’instructions** (délimité par `{}`).
|
|
|
|
|
|
```java
|
|
|
public static void main(String[] args) {
|
|
|
int answer = 42;
|
|
|
...
|
|
|
}
|
|
|
|
|
|
> : warning: La portée d’une variable est le bloc d’instructions dans lequel elle est déclarée. Elle est invisible et inutilisable en dehors.
|
|
|
|
|
|
> :memo: Il est possible d’initialiser une variable lors de sa déclaration :
|
|
|
|
|
|
```java
|
|
|
public static void main(String[] args) {
|
|
|
int i = 0;
|
|
|
float c;
|
|
|
c = 3; // une instruction
|
|
|
// notez au passage la syntaxe d’un commentaire de fin de ligne ...
|
|
|
/* ceci est un autre commentaire qui n’invalide pas le reste de la ligne... */
|
|
|
boolean b = (c>i);
|
|
|
System.out.println(b); // affiche la valeur de b sur la console et passe a la ligne
|
|
|
}
|
|
|
La déclaration d’un tableau en Java est en revanche différente de celle en C, elle fait appel à la notion de constructeur (à travers le mot-clé new). Ci-dessous est présenté un exemple de déclaration, initialisation et manipulation de tableau.
|
|
|
public static void main(String[] args)
|
|
|
{
|
|
|
// args est un tableau de chaînes de caractères représentant les arguments
|
|
|
// passés à l’application sur la ligne de commande
|
|
|
// Contrairement à C, args[0] représente le premier "vrai" argument.
|
|
|
1. Unicode (http://www.unicode.org) est une norme qui définit un jeu de caractères universel (qui comprend tous les caractères disponibles dans toutes les langues écrites) et plusieurs types de codages de longueurs fixes (16 bits ou 32 bits par caractère, respectivement appelés UTF-16 et UTF-32) ou variables (de 8 à 24 bits par caractère, appelé UTF-8). Java est conçu de base pour manipuler les caractères et les chaînes de caractères UTF-16 (il est même possible d’utiliser des caractères Unicode dans les codes sources.
|
|
|
2
|
|
|
|
|
|
// Déclaration d’un tableau statique de 5 valeurs de type short
|
|
|
// (l’espace mémoire réservé n’est pas extensible)
|
|
|
short[] s = new short[5];
|
|
|
// Les indices, comme en C, varient de 0 à taille-1
|
|
|
s[0] = 3;
|
|
|
s[1] = 4;
|
|
|
// le nom du tableau postfixé de .length désigne la capacité du tableau
|
|
|
s[2] = s.length;
|
|
|
// la précédence des opérateurs est identique à celle de C
|
|
|
s[3] = s[2]*s[0]-s[1];
|
|
|
// On ne peut pas demander de manière simple l’affichage d’un tableau,
|
|
|
// on obtiendrait non pas la liste, mais une valeur unique n’ayant rien à voir.
|
|
|
// L’argument de println est une chaîne de caractères.
|
|
|
// Java se charge de convertir n’importe quel type en chaîne de caractères.
|
|
|
// On doit cependant concaténer plutôt qu’écrire s[0]+s[1] ...
|
|
|
// car sinon on afficherait non pas la liste mais la somme.
|
|
|
// s[0]+s[1] est converti automatiquement en int,
|
|
|
// s[0]+"" ("" est la chaîne vide) est converti en chaîne de caractères (String)
|
|
|
// Affiche (sur la console) les éléments du tableau sur une ligne et passe à la ligne
|
|
|
System.out.println(s[0]+""+s[1]+""+s[2]+""+s[3]+""+s[4]);
|
|
|
}
|
|
|
1.6 Opérateurs arithmétiques, relationnels et logiques
|
|
|
Cette sous-section décrit rapidement l’ensemble des opérateurs utilisables en Java.
|
|
|
1.6.1 Les opérateurs arithmétiques et leurs priorités
|
|
|
On trouve en Java les mêmes opérateurs qu’en C (à l’exception de l’opérateur puissance) :
|
|
|
— l’addition, notée +
|
|
|
— la soustraction, notée -
|
|
|
— l’opposé, (opérateur unaire) noté -
|
|
|
— l’identité (opérateur unaire), notée +
|
|
|
— la multiplication, notée *
|
|
|
— la division (entière si les deux opérandes sont de type entier), notée / — le reste de la division entière, noté %
|
|
|
La priorité s’opère comme suit :
|
|
|
1. les opérateurs unaires - et + sont les plus prioritaires,
|
|
|
2. les opérateurs * et / ont ensuite la priorité la plus élevée,
|
|
|
3. viennent ensuite les opérateurs binaires + et -.
|
|
|
4. l’associativité s’effectue de gauche à droite pour des opérateurs de même priorité.
|
|
|
1.6.2 Les opérateurs relationnels et logiques et leurs priorités
|
|
|
Les opérateurs relationnels sont au nombre de six :
|
|
|
— inférieur à, noté <
|
|
|
— supérieur à, noté >
|
|
|
— égal à, noté ==
|
|
|
— inférieur ou égal à, noté <= — supérieur ou égal à, noté >= — différent de, noté !=
|
|
|
3
|
|
|
|
|
|
2
|
|
|
Le langage Java compte enfin sept opérateurs « bit-à-bit » (dans l’ordre de priorité) :
|
|
|
— la négation bit-à-bit, notée ̃
|
|
|
— le décalage de n bits à gauche, noté <<
|
|
|
— le décalage de n bits à droite avec recopie du signe, noté >> — le décalage de n bits à droite sans recopie du signe, noté >>> — le ET bit-à-bit, noté &
|
|
|
— le OU exclusif bit-à-bit, noté ˆ
|
|
|
— le OU bit-à-bit, noté |
|
|
|
Instructions de contrôle
|
|
|
Le langage Java compte également trois opérateurs logiques :
|
|
|
— la négation logique, notée !
|
|
|
— la conjonction logique, notée && — la disjonction logique, notée ||
|
|
|
La négation logique est l’opérateur le plus prioritaire. Les priorités des autres opérateurs sont iden- tiques et l’associativité s’effectue de gauche à droite.
|
|
|
Avant de présenter la syntaxe des différentes instructions de contrôle, rappelons d’abord qu’une ins- truction élémentaire (affectation, déclaration, appel de méthode, . . .) en Java doit être terminée par un point-virgule. Dans la suite, lorsque nous utiliserons le mot instruction, nous désignerons :
|
|
|
— soit une instruction élémentaire,
|
|
|
— soit une instruction de contrôle,
|
|
|
— soit un bloc d’instructions (des deux types précédents), délimité par {}.
|
|
|
Dans ce qui suit, les crochets ([]) sont utilisés pour dénoter le caractère optionnel d’une construction.
|
|
|
2.1 if/else
|
|
|
if condition
|
|
|
{
|
|
|
instructions
|
|
|
}
|
|
|
ou :
|
|
|
if condition
|
|
|
{
|
|
|
instructions
|
|
|
}
|
|
|
else {
|
|
|
instructions
|
|
|
}
|
|
|
La condition doit être exprimée entre parenthèses, exemple :
|
|
|
if (a==b)
|
|
|
System.out.println("stop");
|
|
|
else
|
|
|
System.out.print(".");
|
|
|
4
|
|
|
|
|
|
2.2 switch
|
|
|
La construction switch permet d’exprimer une liste de décisions. Sa syntaxe est la suivante :
|
|
|
switch (expression)
|
|
|
{
|
|
|
case valeur1 :
|
|
|
instructions
|
|
|
case valeur2 :
|
|
|
instructions
|
|
|
... default :
|
|
|
instructions
|
|
|
}
|
|
|
Exemple :
|
|
|
switch (a) {
|
|
|
case 1 :
|
|
|
System.out.println("1");
|
|
|
case 2 :
|
|
|
System.out.println("2");
|
|
|
break;
|
|
|
default :
|
|
|
System.out.println(a);
|
|
|
}
|
|
|
Il faut remarquer que les case ne sont que des étiquettes de branchement, aucun test n’y est effectué. L’expression est testée au début du switch et, selon sa valeur, le programme branche à l’étiquette correspondante et le flot d’instruction suit son cours. Ceci veut dire que s’il n’existe pas de rupture de flot de contrôle (voir break plus loin dans cette sous-section) les instructions à l’étiquette case adéquate et toutes les instructions aux étiquettes suivantes sont exécutées.
|
|
|
L’étiquette default permet de spécifier un comportement par défaut (lorsqu’aucune étiquette ne correspond à la valeur de l’expression) ou un post-traitement.
|
|
|
2.3 for
|
|
|
for (instruction1; expression; instruction2)
|
|
|
{
|
|
|
instructions
|
|
|
}
|
|
|
L’instruction instruction1 est une instruction élémentaire exécutée une et une seule fois avant le premier tour de boucle. C’est en général la déclaration et l’initialisation du compteur de boucle.
|
|
|
L’expression booléenne expression est évaluée avant chaque tour de boucle et dénote une condition. Si cette condition n’est pas vérifiée, on ne rentre plus dans le corps de la boucle.
|
|
|
L’instruction instruction2 est une instruction élémentaire exécutée à chaque fin de tour de boucle. C’est en général l’opération d’incrémentation ou de décrémentation du compteur de boucle.
|
|
|
Exemple :
|
|
|
for(int i=0;i<7;i++)
|
|
|
{
|
|
|
System.out.println(i);
|
|
|
}
|
|
|
5
|
|
|
|
|
|
2.4 while
|
|
|
while (expression)
|
|
|
{
|
|
|
instructions
|
|
|
}
|
|
|
2.5 do while
|
|
|
do {
|
|
|
instructions
|
|
|
}
|
|
|
while (expression);
|
|
|
La différence entre cette instruction de contrôle et la précédente tient dans le fait que l’expression dénotant la condition d’arrêt est évaluée à la fin de chaque tour de boucle plutôt qu’au début (ce qui signifie que l’instruction constituant le corps de la boucle est exécutée au moins une fois).
|
|
|
2.6 break et continue
|
|
|
Ces deux instructions sont des instructions de rupture de flot de contrôle. Alors que break peut être utilisée dans n’importe quelle instruction de contrôle ou bloc d’instructions, continue ne peut être utilisée que dans les itérations (c’est à dire for et les variantes de while).
|
|
|
L’instruction break permet de sortir immédiatement d’un bloc d’instruction ou d’une boucle. Par exemple, si une telle instruction termine chaque case d’un switch, alors uniquement le bloc d’instructions associé au case correspondant à une valeur de l’expression sera exécuté (et le default sera dans ce cas vraiment un traitement par défaut).
|
|
|
L’instruction continue permet quant à elle de court-circuiter le reste du corps d’une boucle pour redémarrer de suite un nouveau tour (en effectuant tout de même les traitements intervenant à chaque fin de tour).
|
|
|
|
|
|
|
|
|
> : warning: Une valeur immédiate entière (résultat d'un calcul par exemple) est implicitement de type **`int`**, ce qui peut poser problème si on essaye de l’affecter à une variable de type `byte`.
|
|
|
|
|
|
:warning: Une valeur immédiate flottante est implicitement de type **`double`**, ce qui peut poser problème si on essaye de l’affecter à une variable de type `float`.
|
|
|
|
|
|
En langage C, ce genre de problème se règle par un forçage de type (aussi appelé transtypage ou cast). Il en est de même en Java, le cast ayant la même syntaxe, consistant à faire précéder la valeur du type compatible entre parenthèses. Dans le cas du cast en float, il existe une abbréviation qui consiste à rajouter uniquement la lettre f derrière la valeur flottante (-3,2E-4f). |