Les types en Java
Introduction
Rappelons que tout programme utilise des variables. La variable est un conteneur mémoire où est stockée une information. Le programme vient lire ou écrire dans ses variables au gré de ses traitements. La nature de la variable conditionne l’information qu’elle pourra contenir. Une variable de type simple peut, par exemple, contenir une information booléenne 1 ou 0 pour oui ou non. Une variable plus complexe peut définir une personne avec plusieurs attributs, eux-mêmes de types différents (chaînes de caractères, dates, valeurs numériques, etc.). Avec Java (comme d’ailleurs avec C, C++ ou C#), une variable doit être déclarée avec un type qu’elle gardera pendant toute sa vie à l’intérieur de l’application. La variable doit également porter un nom. Le compilateur vérifie vos instructions en fonction du type des variables impliquées et vous renvoie des erreurs si vous tentez de faire des traitements impossibles comme écrire les informations d’une personne dans une variable booléenne...
En Java, la notion de variable est très souvent attachée aux instances d’objets, et notamment à leurs champs ou états (attributs au sens UML). Les variables sont également échangées lors d’appels à des méthodes ou encore...
Les types primitifs
Les types primitifs font manquer à eux seuls le label 100 % Objet pour Java. Ce sont « juste » des containers de tailles spécifiques qui stockent des valeurs « primitives » et ne disposent pas de méthodes. Les types « primitifs » comprennent les huit types basiques présentés dans le tableau ci-dessous :
Type |
Taille en bits |
Gamme de valeurs |
boolean |
Dépend du système |
true ou false |
char |
16 bits |
0 à 65535 |
byte |
8 bits |
-128 à 127 |
short |
16 bits |
-32768 à 32767 |
int |
32 bits |
-2^31 à 2^31-1 |
long |
64 bits |
-2^63 à 2^63-1 |
float |
32 bits |
-3.40282347E+38 à 3.40282347E+38 |
double |
64 bits |
-1.79769313486231570E+308 à 1.79769313486231570E+308 |
Nous allons voir plus loin que tous les objets héritent de la même classe racine java.lang.Object. Cet héritage implicite peut être très pratique, car il offre au développeur un jeu de méthodes de base commun à toutes les instances d’objets. Comme c’est dommage que les types primitifs ne disposent pas de cette fonctionnalité, Java nous propose des classes appelées wrappers qui encapsulent chaque type primitif. Ces classes font partie du package java.lang et trouver leurs noms est très simple : il suffit, la plupart du temps, de reprendre celui du type primitif...
Les types référence
Contrairement aux types primitifs, les types référence stockent des références sur des données. Ces données sont écrites dans une zone mémoire dénommée le heap (tas). Elles sont accessibles depuis d’autres instances de classes. Leurs vies s’arrêteront quand on ne s’en servira plus. Tant qu’il existe au moins une référence active sur la zone de données, celle-ci sera maintenue. Dès qu’il n’existe plus de référence, la zone est considérée comme inutile et sa destruction est alors gérée automatiquement par un module du système run time appelé garbage collector.
Un type référence peut ne rien référencer (ou pas encore). Dans ce cas, il contient null.
L’instanciation d’une classe s’effectue uniquement par le mot-clé new.
Une variable de type référence caractérise une instance de classe ; à savoir l’adresse où se trouve l’objet. Comme nous l’avons vu, l’objet mixe attributs et méthodes et il détient donc des données plus complexes que celles contenues par des types primitifs.
Nous aurons l’occasion de revenir sur le sujet des références et l’approfondir mais jetons un œil sur quelques règles...
Pour nous aider...
Pendant cette promenade initiatique dans le domaine de la POO, nous allons construire des petites applications de tests en mode console.
En langage Java, le mot-clé assert permet de vérifier qu’une condition est vraie pendant l’exécution de votre code. En utilisant cette méthode, vous n’intervenez pas sur le déroulement du programme en tant que tel ; vous vérifiez juste que ce qui est prévu à tel endroit du code arrive bien. Si la condition est fausse, un message d’erreur sera affiché pour vous en informer.
Un assert n’est pas un traitement conditionnel orientant le flux vers tel ou tel sous-programme. Quand un assert se « réveille » il devrait vous mettre sur la piste d’un défaut (bug) dans votre programme.
Syntaxe d’utilisation du mot-clé assert
assert( <condition> );
Exemple d’utilisation du mot-clé assert
Pour vérifier l’utilisation du mot-clé assert, nous allons reprendre le projet helloworld et lui ajouter quelques lignes.
public static void main(String[] args) {
// Le passage obligé...
System.out.println("Hello World");
// Vérification...
La superclasse java.lang.Object
La classe Object est la classe racine (classe de base) des classes Java existantes et des classes que vous allez créer (la notion d’héritage a déjà été un peu abordée dans les premiers chapitres). L’héritage d’Object est implicite et donc, sa déclaration est inutile. Toutes les classes héritent de ses méthodes et l’idée est de les substituer en les adaptant à la logique de la classe que vous développez. Par exemple, dans la classe Object, il existe une méthode toString qui retourne une chaîne représentant l’objet. Le fait d’implémenter cette méthode dans votre classe va déconnecter celle de la classe de base et va vous permettre de renvoyer une chaîne décrivant votre objet dans la forme que vous souhaitez. Par exemple, si votre application gère une liste d’objets de type Personne, alors vous pourrez construire dans la méthode toString une chaîne reprenant les attributs principaux de chaque instance comme le nom, l’identifiant, etc. et appeler cette méthode pendant les phases de mise au point pour afficher l’information dans la fenêtre Console.
Voyons les méthodes de java.lang.Object que nous allons pouvoir substituer ou utiliser dans nos propres classes.
1. equals
public boolean equals(Object o);
Le fonctionnement de base de cette méthode (donc le comportement appelé si vous ne la redéfinissez pas dans votre classe) est analogue à celui de l’opérateur ==. Donc, le test le plus basique est la comparaison des références (finalement les adresses) des deux objets. Pour le vérifier, nous allons mettre en action le mot-clé assert.
// Création d'une variable référence nommée tr1
// sur un objet de type TestReference
TestReference tr1; // pour l'instant tr1 vaut null
// Allocation d'un objet et stockage de son adresse
// dans la variable tr1
tr1 = new TestReference(); ...
La classe java.lang.String
Il existe une classe très « intégrée » à la grammaire Java : la class String (qui fait partie du package java.lang).
Cette classe encapsule une collection de caractères Unicode eux-mêmes encapsulés par le type java.lang.Character. String est de type référence (donc alloué sur le heap) mais, pour des raisons de commodités, l’utilisation de l’opérateur new pour l’instancier n’est pas la méthode la plus communément utilisée. En effet, il suffit d’assigner une chaîne durant la déclaration d’un objet String pour l’instancier.
String s = "Vive la programmation JAVA :)";
La chaîne littérale peut être le résultat d’une construction.
String hello = "Bonjour nous sommes le "
+ Calendar.getInstance().get(Calendar.DAY_OF_YEAR)
+ "e jour de l'année";
System.out.print(hello);
Voici la sortie console correspondante pour un 14 janvier :
Bonjour nous sommes le 14e jour de l'année
Lors de la déclaration de la chaîne littérale le caractère \ (antislash) est pris par défaut comme séquence d’échappement.
Par exemple, \r\n signifie « retour chariot »...
Exercice
1. Énoncé
Créez une application de type Console qui va servir de support aux questions suivantes.
Créez une variable de type int nommée iayant pour valeur 10.
Créez une variable de type java.lang.Integer nommée j ayant pour valeur le contenu de i.
Créez une variable de type java.lang.Integer nommée k ayant pour valeur le contenu de i.
Affichez i,jet k.
Ajoutez 1 à i.
Affichez i, j et k.
Vérifiez avec un assert que Integer est de type Object.
Affichez les hashcode de j et de k.
2. Corrigé
Sélectionnez le menu File puis l’option New Project....
Nommez votre projet LabTypesJava, choisissez un répertoire de travail se terminant par un sous-répertoire nommé LabTypesJava, puis saisissez com.eni en tant que Base package.
Cliquez sur Create.
Le contenu du fichier source généré par l’assistant contient déjà une méthode main qui est le point d’entrée du programme et dans laquelle nous allons développer notre code.
La méthode main peut recevoir des informations passées en ligne de commandes par la console. Ces paramètres sont copiés dans un tableau de String dénommé args.
Voici le code commenté de ce premier exercice :
package com.eni;
public class Main {
public static void main(String[] args) { ...