• Aucun résultat trouvé

Comment retenir les objets : les handles

Nous avons donc vu que nous pouvions créer un objet facilement à l'aide de l'opérateur new et du constructeur de l'objet. Nous pouvons utiliser immé-diatement l'objet ainsi créé. Si nous voulons pouvoir l'utiliser plus tard, il faut, avant de confier cet objet à Java, s'assurer que nous pourrons le récu-pérer. Pour cela, il suffit de pouvoir l'identifier. Dans le langage courant, il est fréquent d'utiliser des artifices pour identifier les objets. Si vous avez un chien, vous pouvez le désigner par "mon chien". Si vous avez un chien noir et un chien blanc, vous pourrez les identifier par "mon chien noir" et "mon chien blanc". Mais parviendrez-vous à vous faire obéir en disant "Mon chien blanc, couché !". Il est beaucoup plus simple de leur donner à chacun un identificateur unique. Dans ce cas précis, il s'agira d'un nom. Ainsi vous pourrez, par exemple, appeler votre chien noir "Médor" et votre chien blanc

"Azor" et leur donner des ordres individuels. (Toute comparaison a ses li-mites, et vous objecterez peut-être qu'il est parfaitement possible de dresser un chien pour qu'il obéisse à un ordre tel que "Mon chien blanc, couché !"

et pas à "Mon chien noir, couché !". C'est tout simplement que votre chien aura appris que son nom est "Mon chien blanc".)

Dans le langage courant, les personnes, les animaux domestiques et cer-tains objets (les bateaux, les villes, les pays, les fleuves, etc.) sont identifiés à l'aide d'un nom propre. D'autres objets sont identifiés par un moyen diffé-rent : numéro d'immatriculation, titre (pour une œuvre littéraire ou musi-cale), etc. En Java, tous les objets sont logés à la même enseigne : ils sont identifiés à l'aide d'un handle. Le mot handle signifie poignée, en français, ce qui est tout à fait évocateur, puisqu'il sert à manipuler l'objet correspon-dant. Cependant, il n'est pas entré dans le langage courant des program-meurs, et nous utiliserons donc le terme d'origine, au masculin, comme l'usage s'est établi, au risque de froisser les puristes de la langue française.

On assimile parfois le handle au nom de l'objet. Cette assimilation est in-correcte. En effet, la notion de nom évoque généralement l'unicité et la spécificité. On dit "mon nom" et non "mes noms", alors qu'il est évident que nous en avons plusieurs. Par ailleurs, nous pensons comme si notre nom nous était spécifique, ce qui n'est pas le cas (nous avons des homony-mes). De plus, nous avons du mal à imaginer que chaque objet (une cuiller, une aiguille à coudre, une pomme, une idée, etc.) puisse avoir un nom.

En Java, les objets peuvent avoir plusieurs handles. Autant que vous le souhaitez. En revanche, un handle ne peut correspondre qu'à un seul objet simultanément. Il n'y a pas d'homonyme, ou plutôt, il n'y a pas de situation dans laquelle l'homonymie crée une ambiguité (sauf, évidemment, dans l'es-prit du programmeur !). Un handle peut toutefois parfaitement changer d'ob-jet. Dans la terminologie de Java, on dit que le handle pointe vers l'objet correspondant. Il est donc possible de modifier l'affectation d'un handle pour le faire pointer vers un autre objet. Il faut simplement que le type du nouvel objet soit compatible avec le handle. En effet, chaque fois que vous créerez un handle, vous devrez indiquer vers quel type d'objet il peut pointer.

Création des handles

Rien n'est plus simple que de créer un handle d'objet. Il suffit pour cela de le déclarer en indiquant vers quelle classe d'objets il est susceptible de pointer.

Par exemple, pour créer le handle alpha pouvant pointer vers une instance d'Employe, nous écrirons :

Employe alpha;

Vers quoi pointe ce handle ? Pour l'instant, vers rien. En effet, nous avons déclaré le handle, ce qui suffit à le faire exister. En revanche, nous ne l'avons pas initialisé, c'est-à-dire que nous ne lui avons pas attribué sa valeur ini-tiale. Pour l'instant, il ne pointe donc vers rien.

Attention : Notre apprentissage se fait petit à petit. Il faut donc commen-cer par des approximations. Nous verrons un peu plus loin que, dans commen- cer-tains cas, les handles sont automatiquement initialisés par Java.

Modifier l'affectation d'un handle

Nous allons aborder ici un des pièges de Java. Pour modifier l'affectation d'un handle, c'est-à-dire pour le faire pointer vers un objet (ou vers un autre objet, s'il était déjà initialisé), il faut utiliser un opérateur. Il aurait été natu-rel d'utiliser un opérateur tel que pointe vers, ou -->, mais malheureuse-ment, les concepteurs de Java, qui étaient évidemment des programmeurs, ont préféré propager l'usage établi du signe égal. Nous allons voir que cet

usage est totalement incohérent. De plus, il nous oblige à utiliser un autre opérateur pour la vraie égalité, ce qui est tout de même un comble ! Nous avons vu qu'un objet pouvait être créé à l'aide de son constructeur et de l'opérateur new. Nous ne pouvons affecter un premier handle à un objet nouvellement créé qu'au moment de sa création. En effet, si nous écrivons les lignes :

Employe alpha;

new Employe();

il n'y a ensuite aucun moyen d'établir un lien entre le handle créé à la pre-mière ligne et l'objet créé à la seconde. Il faut donc effectuer l'affectation en même temps que la création, de la façon suivante :

Employe alpha;

alpha = new Employe();

Ce qui ne signifie en aucun cas que le handle alpha soit égal à l'objet créé, mais simplement qu'il pointe vers cet objet. Il pourra donc servir à manipu-ler cet objet.

Java nous permet même de condenser ces deux lignes en une seule sous la forme :

Employe alpha = new Employe();

Si nous utilisons cette technique (sous l'une de ces deux formes) dans notre programme, nous pouvons obtenir le même résultat tout en conservant la possibilité de réutiliser notre objet :

public class Test3 {

public static void main(String[] argv) { Employe alpha = new Employe();

alpha.afficherMatricule();

alpha.afficherMatricule();

} }

class Employe { int matricule;

static int nombre;

Employe() {

matricule = ++nombre;

}

void afficherMatricule() {

System.out.println("Matricule " + matricule);

} }

Modifiez le programme Test2.java comme indiqué dans le listing ci-des-sus et enregistrez-le dans le fichier Test3.java. (Nous avons introduit d'autres modifications pour améliorer la sortie. Nous reviendrons plus loin sur leur signification.)

Compilez et exécutez ce programme. Vous pouvez constater qu'il nous a été possible d'afficher deux fois le matricule pour un même objet, ce qui aurait été tout à fait impossible sans l'utilisation d'un handle. Il nous aurait évi-demment été possible d'utiliser deux fois la ligne :

(new Employe()).afficherMatricule();

(new Employe()).afficherMatricule();

mais le résultat n'aurait pas du tout été le même. Si vous n'êtes pas con-vaincu, essayez ! Vous obtiendrez le résultat suivant :

Matricule 1 Matricule 2

En effet, la deuxième ligne crée un deuxième objet, différent du premier, et qui reçoit donc le numéro matricule suivant.

Résumé

Dans ce chapitre, vous avez appris comment les objets sont créés et com-ment on peut utiliser des handles pour les manipuler. Au chapitre suivant, nous approfondirons notre étude des handles, après avoir présenté les pri-mitives, que nous avons d'ailleurs déjà utilisées dans nos exemples. Vous devez vous rappeler les choses suivantes :

• Les objets sont des instances de classes.

Les objets peuvent être créés à volonté à l'aide de l'opérateur new et des constructeurs.

• Un handle peut être créé en le déclarant, c'est-à-dire en indiquant son nom, précédé du nom de la classe des objets auxquels il peut être af-fecté.

Un handle qui n'a pas reçu d'affectation pointe vers null.

• Pour faire pointer un handle vers un objet, on utilise l'opérateur = en plaçant, à gauche, le handle, et à droite du signe = une référence à l'objet vers lequel il doit pointer.

Exercice

A titre d'exercice, essayez de reconstruire le programme Test3.java sans consulter le livre. Modifiez la méthode main() pour créer deux instances d'Employe ayant chacune un handle différent. Appelez la méthode afficherMatricule() pour afficher le matricule de chaque instance. Affec-tez ensuite le handle du deuxième objet au premier, puis essayez de nou-veau d'afficher les matricules des deux objets. Est-ce possible ? Qu'est de-venu le deuxième objet ? Les réponses sont dans le chapitre suivant.

A

u chapitre précédent, nous avons commencé l'étude des handles. Nous avons également utilisé sans les étudier en détail des éléments d'un type nouveau permettant de manipuler des nombres entiers. Avant de poursuivre notre étude des handles, nous devons nous arrêter sur ces éléments diffé-rents que l'on appelle primitives. Mais, pour comprendre la nécessité des primitives, il faut dire quelques mots de la façon dont les données sont conservées en mémoire.

Les données manipulées par un programme peuvent résider dans les regis-tres du processeur. Avec certains langages (l'assembleur, par exemple), il est possible de manipuler les registres du processeur. Ce n'est pas le cas en Java.