Autoboxing et autounboxing en Java

Conversion automatique des types primitifs

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

Contrairement au PHP, où "tout est possible", Java impose quelques contraintes. Par exemple, on ne peut pas mettre directement un type primitif dans une collection. D'où le besoin d'employer dans ces situations la technique appelée autoboxing.

Regardons l'exemple évoqué au tout début :

afficher le code

Au moment de compilation on recevra plusieurs erreurs :

Autoboxing.java:8: unexpected type found : int required: reference HashMap mapInt = new HashMap(); ^ Autoboxing.java:8: unexpected type found : int required: reference HashMap mapInt = new HashMap(); ^ Autoboxing.java:8: unexpected type found : int required: reference HashMap mapInt = new HashMap(); ^ Autoboxing.java:8: unexpected type found : int required: reference HashMap mapInt = new HashMap(); ^ 4 errors

Comment remédier à cela ? Il faut utiliser autoboxing qui traduit notre type primitif int en une référence de la classe Integer. Depuis la version 1.5 du Java, cette opération est automatiquement gérée par la machine virtuelle. Cela veut dire qu'on n'est pas obligés de spécifier map.put(new Integer(3), "three"). On peut alors directement utiliser le chiffre 3 en tant que la clé de la map : map.put(3, "three"). Constatons cela sur l'exemple du début corrigé :

afficher le code

L'écran affichera alors :

Generated map is {1=one, 2=two, 3=three}

L'opération inverse à l'autoboxing s'appelle unboxing. Elle repose sur le fait de récupérer le type primitif à partir d'un objet, comme dans ce code :

afficher le code

Le rendu sur l'écran sera :

Generated map is {two=2, one=1, three=3} Got one : 1

Il faut avoir en tête que l'autoboxing ne s’applique pas avec l'initialisation des objets. Regardons cela sur l'exemple de comparaison :

afficher le code

Le résultat de ces deux tests sera différent :

Is i equals to j ? true Is k equals to l ? false

Dans le premier cas l'autoboxing sera appliquée via l'appel de la méthode Integer.valueOf(). Cela provoquera la comparaison des valeurs et au final le résultat true du test. L'exemple suivant ne fera pas d'appel à l'autoboxing. Ici, il s'agit d'une comparaison des références. Vu que les deux pointent vers deux objets différents, le résultat doit être false.

Problèmes avec autoboxing en Java

Un des désavantages de l'autoboxing est une grande influence sur les performances du code. En faut chaque "initialisation magique" crée une nouvelle instance de la classe correspondante à l'enveloppeur du type primitif en Java.

L'utilisation de l'autoboxing peut également poser quelques soucis. Ces problèmes peuvent être causés non pas seulement par la technique décrite dans cet article, mais également par une inattention. Analysons cela sur ce cas de figure :

afficher le code

Le résultat affiché sera :

Setting primitive type 2 Setting Integer reference 2

On voit que les méthodes appelées ne sont pas les mêmes. Dans l'environnement de production, si l'on suppose que ces deux fonctions font des choses différentes, une inattention pourrait provoquer des problèmes. Une situation qui peut semer la confusion, à éviter.

télécharger les fichiers d'exemple
Bartosz KONIECZNY Informations sur le langage

Une question ? Une remarque ?

*

*

Un conseil Symfony1

Quelle méthode il faut utiliser afin de récupérer les paramètres d'une route dans la classe sfRoute ?

Imaginons la situation où l'on veut créer une nouvelle classe pour gérer les routes URL de notre application. Afin de faire cela, on devrait hériter de la classe sfRoute.

Les paramètres d'une requête peuvent être lus grâce à la méthode matchesUrl() de sfRoute. Par exemple :
public function matchesUrl($url, $context = array()) {
  $parameters = parent::matchesUrl($url, $context);
  if(count($parameters) > 1) {
    echo 'Vous pouvez faire ce que vous voulez avec les paramètres reçus';
  }
}