1. Introduction
En Java, il existe deux familles de données. La première — les types primitifs : int, char, double, boolean, etc. Ils sont simples et rapides : la valeur est stockée directement en mémoire. La seconde — les types référence, c’est‑à‑dire les objets : la variable stocke une référence vers l’endroit où l’objet se trouve en mémoire.
Parfois, il faut utiliser un primitif comme un objet. Or les primitifs ne sont pas des objets. Dans ces cas, des classes enveloppes spéciales aident.
Les types enveloppes sont des classes qui contiennent en leur sein la valeur d’un primitif et permettent de la manipuler comme un objet. Par exemple, pour int — la classe Integer, pour double — Double, pour char — Character, pour boolean — Boolean. Ces classes fournissent des méthodes : Integer.parseInt(), Double.isInfinite(), Character.isLetter(), Boolean.parseBoolean(), etc.
Exemple d’obtention d’un objet Integer à partir d’un primitif int :
// Primitif
int a = 10;
// Objet enveloppe
Integer b = Integer.valueOf(10);
La variable a contient directement le nombre 10. La variable b, elle, contient une référence vers un objet qui, en interne, renferme 10.
2. Pourquoi a‑t‑on besoin des enveloppes
Un primitif est toujours une valeur concrète : on ne peut pas lui affecter null. Un objet peut ne pas exister et porter une valeur vide — c’est pratique pour signifier « inconnu » ou « absent ».
Un primitif n’a pas de méthodes. On ne peut pas appeler sur un nombre quelque chose comme x.toString(). Une enveloppe fournit ces possibilités : Integer.parseInt("123") convertit une chaîne en nombre, et on peut convertir un nombre en chaîne avec toString().
En résumé : les enveloppes sont nécessaires là où il faut un objet — possibilité de stocker null, d’appeler des méthodes, de passer des valeurs à une API qui n’accepte que des objets (par exemple, des collections de type List<Integer>).
Liste complète des classes enveloppes
| Type primitif | Classe enveloppe |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. Boxing et unboxing
Lorsque vous créez manuellement un objet enveloppe, vous prenez un primitif et vous l’« encapsulez » dans un objet :
int primitive = 42;
Integer wrapper = Integer.valueOf(primitive); // boxing
Pour récupérer la valeur primitive — effectuer un « unboxing » — on utilise, par exemple, intValue() :
Integer wrapper = Integer.valueOf(42);
int primitive = wrapper.intValue(); // unboxing
Encapsulation automatique (autoboxing)
Le compilateur ajoutera lui‑même l’appel à valueOf() si vous affectez un primitif à une variable enveloppe :
int a = 10;
Integer b = a; // autoboxing (Integer.valueOf(a))
Désencapsulation automatique (unboxing)
Le cas inverse — quand un objet enveloppe est utilisé là où un primitif est requis :
Integer c = 20;
int d = c; // unboxing (c.intValue())
int a = 10; // primitif
Integer b = a; // autoboxing
Integer c = Integer.valueOf(20);
int d = c; // unboxing
4. Pièges
Comparaison des enveloppes. L’opérateur == compare les références des objets, pas leurs valeurs :
Integer m = 200;
Integer n = 200;
System.out.println(m == n); // false, car ce sont des objets différents
Java met en cache les enveloppes des nombres dans l’intervalle de -128 à 127, si bien que == renverra parfois true et parfois false. Pour comparer les valeurs, utilisez toujours equals() :
Integer x = 100;
Integer y = 100;
System.out.println(x == y); // true, valeur dans le cache
System.out.println(x.equals(y)); // true, comparaison par la valeur
NullPointerException lors de l’unboxing. Si l’enveloppe vaut null et que vous tentez de la désencapsuler, vous obtiendrez une exception :
Integer value = null;
int primitive = value; // Erreur ! NullPointerException
Performances et mémoire. Les enveloppes sont plus lentes que les primitifs et consomment davantage de mémoire. Dans les portions de code critiques et lors de la manipulation de grands tableaux de nombres, préférez les primitifs.
5. Exemples
Exemples avec Integer et Double
Conversion d’une chaîne en nombre :
String text = "123";
int number = Integer.parseInt(text);
System.out.println(number); // 123
Vérification des valeurs particulières des nombres à virgule flottante :
double d = 1.0 / 0;
System.out.println(Double.isInfinite(d)); // true
double nan = 0.0 / 0.0;
System.out.println(Double.isNaN(nan)); // true
Exemples avec Character
char stocke un seul caractère ; l’enveloppe Character fournit des vérifications pratiques :
char ch = 'A';
Character wrapper = ch; // autoboxing
System.out.println(Character.isLetter(ch)); // true
System.out.println(Character.isDigit(ch)); // false
System.out.println(Character.toLowerCase(ch)); // 'a'
Exemples avec Boolean
Le primitif boolean ne vaut que true/false. L’enveloppe Boolean permet en plus de stocker null :
Boolean flag = null; // autorisé
flag = Boolean.TRUE; // constante spéciale
System.out.println(flag); // true
Conversion de chaînes en booléens :
String s1 = "true";
String s2 = "false";
boolean b1 = Boolean.parseBoolean(s1);
boolean b2 = Boolean.parseBoolean(s2);
System.out.println(b1); // true
System.out.println(b2); // false
GO TO FULL VERSION