UKOnline

Créer un objet

Maintenant qu'on a bien compris l'intuition qui se trouve derrière la notion d'objet, on va commencer par voir comment créer des objets en Java. Tout comme pour les valeurs de type primitif, il faut utiliser des variables qui sont le moyen utilisé dans un programme pour manipuler et stocker des données. Vous verrez une évidente similitude entre le traitement des données primitives et des objets.

Rappel sur les variables

On a vu qu'il existait deux différents types de données : celles de type primitif et celles de type objet. Pour pouvoir stocker ces données et effectuer des opérations, il faut utiliser des variables. Il y en a donc de deux types : les variables de type primitif et les variables de type objet.

Une variable de type primitif contient une et une seule donnée primitive : un entier, un flottant, un caractère ou un booléen. En ce qui concerne les variables de type objet, elles contiennent des objets. La différence est que l'objet n'est pas stocké dans la variable. Ce qui s'y trouve, c'est une référence vers l'objet, qui lui est stocké ailleurs dans la mémoire. Ce concept de référence, illustré sur la figure 3, est très important et on le comprendra plus précisément au chapitre suivant.

Types de variable
Variable de type primitif et de type objet.

Déclaration et création

Tout calcul, toute opération, tout se fait via les variables et donc, si on veut utiliser un objet, il faut commencer par déclarer une variable. Pour rappel, déclarer une variable, c'est lui donner un nom et dire de quel type elle est. Dans le cas des variables de type objet, le type correspond au nom de classe qui précise le type de l'objet que la variable va contenir. Voici par exemple la déclaration d'une variable de type objet dont le nom est mypair et qui pourra contenir un objet de type Pair, c'est-à-dire une paire d'entiers :

Cette ligne de code ne fait donc que déclarer une nouvelle variable, mais il n'y a actuellement rien dedans. On va pouvoir affecter une nouvelle valeur à la variable en utilisant l'opérateur d'affectation ( = ). Ce qu'on va mettre dans la variable, c'est une référence vers un nouvel objet et pour ce faire, il faut utiliser l'opérateur de création d'objet ( new ). Voyons tout de suite un exemple :

Deux choses se passent lorsque l'instruction ci-dessus est exécutée par la machine virtuelle Java. L'opérateur new, qui prend un opérande à sa droite, crée un nouvel objet. Cette opération s'appelle création d'un objet d'une classe ou tout simplement instanciation d'une classe. Le nouvel objet ainsi créé est appelé instance de la classe Pair. L'opérateur new renvoie la référence de l'objet créé, et celle-ci est affectée à la variable mypair grâce à l'opérateur d'affectation ( = ). Comme avec les variables de type primitif, on peut bien entendu faire la déclaration et l'initialisation de la variable en une seule instruction :

Lorsqu'on fait le tout en une seule instruction, il faut bien se rendre compte que trois étapes, illustrées sur la figure 4, se produisent :

  1. la déclaration d'une nouvelle variable ;
  2. la création d'un nouvel objet en mémoire ;
  3. et l'affectation d'une référence vers l'objet dans la variable.
Création nouvel objet
Déclaration de variable, création d'un nouvel objet et affectation d'une référence vers l'objet créé dans la variable.

Paramètres de création

Pour créer notre nouvel objet de type Pair, on a dû fournir les deux valeurs de la paire que l'on voulait créer (à savoir 17 et 29). C'est normal puisqu'on voulait précisément créer la paire (17, 29). Ces valeurs sont appelées paramètres de création de l'objet. Voyons maintenant un autre exemple, on veut créer un objet de type Date, qui représente une date. Plus précisément, on veut créer un objet représentant le 13 aout 2008. Voici l'instruction qu'il faut utiliser :

La figure 5 montre tout ce qui se trouve en mémoire une fois cette instruction exécutée. On a l'objet qui a été créé en mémoire et qui correspond au 31 aout 2008. Une référence vers cet objet se trouve stockée dans la variable déclarée. Vous voyez donc bien que contrairement aux données primitives qui se trouvent dans la variable, on a ici l'objet qui est quelque part dans la mémoire, mais pas dans la variable, celle-ci ne contenant qu'une référence vers l'objet.

Création nouvel objet Date
Un objet de type Date dans la mémoire.

Pour pouvoir créer un objet de type Date, on a dû fournir trois paramètres qui représentent respectivement l'année, le mois et le jour. Si on exécute l'instruction System.out.println (today);, voici ce qui sera affiché à l'écran :

Wed Aug 13 00:00:00 CEST 2008

Et oui, le 13 aout 2008 était bien un mercredi (Wed) et on était à l'heure d'été (CEST, Central European Summer Time) ! On peut donc afficher un objet à l'écran avec System.out.println, comme on a déjà fait pour les données primitives.

On peut maintenant se poser une question légitime : comment savoir combien de paramètres il faut fournir pour pouvoir créer un objet ? De plus, comment savoir quels paramètres il faut fournir, ce qu'ils représentent et l'ordre dans lequel il faut les spécifier ? Il faut se rendre sur la documentation en ligne dont nous reparlerons à la section 7 sur la spécification de l'API Java.

Pour construire un objet de type Date, il faut spécifier trois paramètres. Le premier représente l'année, mais on doit fournir l'année de laquelle on soustrait 1900. Le second correspond au mois sachant que 0 correspond à janvier, 1 à février... Enfin, le dernier paramètre correspond simplement au jour du mois.

Créer plusieurs objets

Comme on l'a déjà introduit lors de l'analogie avec les GSM, on peut créer plusieurs objets différents à partir d'une même classe. Ceux-ci seront donc tous du même type, mais ce seront bel et bien des objets distincts. Si on veut pouvoir manipuler chacun des objets, il faudra une variable par objet. On verra plus loin que ce n'est pas du tout une obligation. Créons par exemple trois objets de type Pair :

La première instruction déclare trois variables p1, p2 et p3, toutes de type Pair. Ensuite, on va créer trois nouveaux objets de type Pair (il y a trois fois l'opérateur new) et affecter une référence vers ces objets aux trois variables précédemment déclarées. La figure 6 montre tout ce qui se trouve en mémoire, après exécution de ces quatre lignes de code.

Plusieurs objets
Trois objets de type Pair.

On peut faire quelques observations importantes sur ce petit exemple. La première observation concerne les paramètres de création d'un objet, ce sont simplement des expressions qui sont placées entre parenthèses et séparées par des virgules. Tous les objets ne nécessitent pas de paramètres de création, dans ce cas, on n'a que les parenthèses. On peut par exemple créer un objet Date correspondant à aujourd'hui ainsi :

Ensuite, il faut bien se rendre compte qu'on a créé trois objets distincts, et différents. Mais parmi ces trois objets, il y en a deux qui représentent la même paire d'entiers, à savoir (17, 29). Les objets référencés par les variables p1 et p2 sont différents mais ont le même état.

Comparer deux objets

Les opérateurs == et != qu'on a vus au chapitre 2 permettent de tester si les contenus de deux variables sont identiques ou différents. En ce qui concerne les variables de type objet, ces opérateurs testent donc que les objets référencés sont identiques et ne testent pas si les états de ceux-ci sont identiques. Prenons par exemple l'instruction suivante :

L'exécution de cette instruction affiche false à l'écran puisque les objets référencés par les variables p1 et p3 sont différents, bien qu'ils ont le même état et représentent donc la même paire, à savoir (17, 29).

On verra comment faire pour comparer les états de deux objets à la section suivante. Ce qu'il faut bien retenir, c'est que les opérateurs == et != permettent de vérifier si deux variables réfèrent le même objet ou non, et ne prend pas du tout en compte l'état de l'objet.

Objet sans référence dans une variable

Lorsqu'on crée un nouvel objet, on n'est pas obligé de stocker la référence renvoyée par l'opérateur new dans une variable. Il faut tout d'abord savoir que l'opération new définit une expression, mais peut également être utilisée comme une instruction. Il est donc, par exemple, possible d'écrire l'instruction suivante :

Celle-ci en particulier ne sert pas à grand chose, mais sachez que parfois, une telle instruction peut avoir un intérêt. Néanmoins, une telle pratique est tout à fait déconseillée, car ne plus avoir une référence vers un objet, c'est ne plus jamais pouvoir l'utiliser; il est donc hors-contrôle.

L'opération new étant une expression, on peut la retrouver partout là où une expression est utilisable, notamment lorsqu'on utilise l'instruction System.out.println. On peut donc écrire :

L'objet est donc uniquement utilisé pour être affiché à l'écran et il est ensuite impossible de l'utiliser pour faire autre chose. On verra à la section suivante d'autres exemples où une telle pratique peut être justifiée.