UKOnline

Type de données élémentaire

Lorsqu'on écrit des programmes, on a besoin de stocker et manipuler des données. En Java, toute donnée appartient à un type bien précis. Il y a les données dites de type primitif et les données de type objet. On va uniquement voir les données de type primitif pour le moment et on reviendra sur les données de type objet au chapitre 4.

Il existe huit types primitifs en Java : quatre variantes de nombres entiers, deux variantes de nombres flottants (c'est-à-dire à virgule), un type booléen (vrai ou faux) et un type caractère. Cette section présente les types primitifs de Java et les littéraux associés. Un littéral est la représentation dans le code source d'une donnée de type primitif.

Entier et flottant

Il existe deux sortes de valeurs numériques : les entiers qui n'ont pas de partie fractionnaire, et les flottants qui en ont une. Les flottants sont parfois appelés nombres à virgule flottante ou nombres réels (attention, contrairement à la définition mathématique des nombres réels, les nombres flottants ont un nombre de décimales limité et par conséquent une précision limitée. On reviendra sur ce problème au chapitre 2).

Il y a quatre types de données entières (byte, short, int et long) et deux types de flottants (float et double). Ces types diffèrent par la quantité d'espace mémoire nécessaire pour stocker une valeur du type, et donc par les différentes valeurs qu'il est possible de représenter. La figure 5 reprend chacun de ces types avec la quantité de mémoire utilisée et les valeurs minimales et maximales représentables.

Type Bits Minimum Maximum
byte 8 -128 127
short 16 -32 768 32 767
int 32 -2 147 483 648 2 147 483 647
long 64 -9 223 372 036 854 775 808 9 223 372 036 854 775 807
float 32 -3.4e+38 (7 chiffres significatifs) 3.4e+38 (7 chiffres significatifs)
double 64 -1.7e+308 (15 chiffres significatifs) 1.7e+308 (15 chiffres significatifs)
Occupation mémoire et valeurs minimale et maximale représentables pour les types primitifs numériques de Java.

Comme vous pouvez le constater, tous les types numériques sont signés, c'est-à-dire qu'ils possèdent un signe et peuvent donc prendre des valeurs positives ou négatives.

Il est important de bien choisir le type de donnée à utiliser afin de ne pas gaspiller de la mémoire. En effet, stocker les résultats de mille lancés de dés dans mille byte est préférable à mille int puisqu'on prend quatre fois moins de place. Néanmoins, vu que la quantité de mémoire augmente considérablement, on se contentera la plupart du temps des int et double, ce qui permet souvent des calculs plus rapides, en pratique.

Il est néanmoins important de connaitre la différence entre ces types au cas où vous devriez utiliser du code écrit par d'autres programmeurs ou pour écrire des programmes destinés à des systèmes disposant de peu de mémoire (par exemple des systèmes embarqués comme des robots Lego® Mindstorms, des Raspberry Pi, des micro-contrôleurs, etc.).

Littéral de type numérique

Pour rappel, un littéral est une valeur explicite utilisée dans le code source d'un programme. On représente les entiers simplement en donnant leur valeur sous forme décimale, binaire, octale ou hexadécimale. Ces valeurs sont considérées par Java comme des valeurs de type int. On peut aussi avoir des littéraux de type long ; il suffit de faire suivre le nombre par la lettre l ou L.

Pour spécifier un nombre sous forme binaire, on le commence par 0b. Pour la forme octale, on utilise 0 comme premier chiffre. Enfin, pour la forme hexadécimale, on commence par 0x ou 0X et on peut utiliser indifféremment les lettres a à f en majuscule ou en minuscule. Voici plusieurs littéraux qui représentent tous l'entier 45, avec le type int pour les quatre premier et long pour les quatre dernier :

En ce qui concerne les nombres flottants, ils sont considérés par défaut comme étant des valeurs de type double. On peut ajouter f ou F derrière le nombre pour qu'il soit de type float. On peut également écrire un nombre flottant en notation scientifique en le faisant suivre de e ou E suivi de la valeur de l'exposant qui peut être positif ou négatif. Voici plusieurs littéraux représentant le nombre flottant 25,5, avec le type double pour les deux premiers et float pour les deux derniers :

On peut également utiliser la lettre d ou D pour qu'un nombre soit considéré comme un double. Ceci est utile pour des entiers que l'on veut voir comme des flottants. Ainsi, le littéral 25D représente le nombre flottant 25,0 et est de type double. Attention qu'on utilise le point comme séparateur décimal, comme en anglais, et pas la virgule comme en français.

Enfin, lorsqu'on veut écrire des littéraux pour des grands nombres, on peut utiliser comme on le souhaite le tiret de soulignement pour regrouper les chiffres pour des raisons de lisibilité. On pourra donc par exemple écrire le littéral suivant :

qui représente le nombre $2147483647$.

Caractère

Les caractères sont un autre type fondamental en Java. Comment sont-ils représentés dans la mémoire de l'ordinateur ? Ils sont encodés d'une certaine manière. Il faut tout d'abord choisir combien de bits on veut utiliser pour représenter un caractère, ce nombre définissant le nombre total de caractères représentables. Ensuite, il faut une table qui fasse le lien entre une séquence de bits et le caractère qu'il représente : une table de caractères.

Un exemple de table de caractères assez courant dans les pays anglophones est l'ASCII (American Standard Code for Information Interchange). Chaque caractère est encodé sur 7 bits, et peut donc prendre une valeur comprise entre 0 et 127. On peut donc encoder 128 caractères différents à l'aide de cette table de caractères.

La figure 6 montre les 128 caractères représentables avec ASCII. Il s'agit d'une table à double entrées : pour retrouver la valeur d'un caractère, on prend la valeur tout à gauche de sa ligne, puis la valeur tout en haut de sa colonne et à l'intersection, on obtient la valeur du caractère en hexadécimal. Par exemple, le caractère N a pour valeur 4E en hexadécimal, ce qui correspond à 78 en décimal.

Table de caractères iso-646
La table de caractères ASCII (iso-646).

Les caractères sur fond vert sont des caractères de contrôle, qu'on appelle parfois aussi caractères invisibles ou caractères non-imprimables, car ils n'ont pas de symbole précis pour les représenter. Ils peuvent néanmoins être stockés comme toute autre valeur. On a par exemple le saut de ligne ( CR ) ou la tabulation horizontale ( HT ).

Comme on demande toujours plus de flexibilité, ASCII a été étendu sur 8 bits (iso-8859-1 ou iso-latin-1) augmentant le nombre de caractères représentables à 256. Parmi les caractères ajoutés par rapport à ASCII, il y a notamment les lettres accentuées non utilisées par les anglophones, mais bien par d'autres Européens de l'Ouest, comme les francophones.

Cependant, malgré cette extension, on ne peut représenter tous les caractères existants. On pense de suite aux langues asiatiques, arabes, cyrilliques, etc. qui utilisent des symboles. C'est pourquoi a été créé le format Unicode (http://www.unicode.org), qui a été choisi par les concepteurs de Java.

Le type primitif char permet de représenter des caractères au format Unicode, en utilisant 16 bits pour les représenter. Comme on le verra dans le chapitre suivant, on va pouvoir utiliser les caractères comme des nombres entiers non-signés compris entre 0 et 65535.

Littéral de type caractère

Un littéral de type caractère est simplement le caractère voulu entouré de guillemets simples (il ne faut pas confondre le guillemet simple ( ' ), également appelé apostrophe, avec le guillemet ouvrant utilisé par les anglais ( `)). Mais il est dès lors difficile de représenter les caractères de contrôle ou même encore des caractères non disponibles sur le clavier, comme le caractère marque déposée ( ), par exemple (les littéraux char sont limités à ceux en UTF-16). Il y a donc des séquences spéciales appelées séquences d'échappement qui permettent de représenter certains caractères particuliers. Ces dernières sont reprises sur la figure 7. La nouvelle ligne fait passer le curseur à la ligne suivante et le retour chariot fait revenir le curseur au début de la ligne courante.

Séquence Unicode Caractère
\n 0x000A nouvelle ligne
\r 0x000D retour chariot
\t 0x0009 tabulation
\b 0x0008 backspace
\f 0x000C saut de page (form feed)
\XXX le caractère dont la valeur en octal est XXX
\uXXXX le caractère dont la valeur en hexadécimal est XXXX
Séquences d'échappement pour les caractères Java.

Attention, sachez que vous ne pouvez pas utiliser \u000A et \u000D pour les caractères nouvelle ligne et retour chariot : vous devez utiliser \n et \r sans quoi vous serez face à une erreur de compilation (c'est parce que le traitement des séquences d'échappement Unicode se fait avant la compilation du code source du programme). Voici trois littéraux qui représentent le caractère N :

Booléen

Le dernier type primitif permet de représenter des données booléennes, c'est-à-dire des données qui ne peuvent prendre que les deux valeurs différentes vrai et faux. On utilise par exemple le type booléen pour indiquer si une condition particulière est vraie ou non. On peut aussi l'utiliser pour exprimer une situation qui comporte deux états différents, comme un interrupteur enclenché ou non.

Il n'y a que deux littéraux booléens, représentant simplement les valeurs vrai et faux :

Comme on l'a vu à la section précédente, on ne peut pas utiliser ces littéraux comme identificateur.