10 mar 2010

Savez vous autoboxer à la mode de chez nous

Catégorie : Non classéJohnny Beuve @ 15 h 25 min

L’autoboxing permet de transformer automatiquement une variable de type primitif en un objet du type du wrapper correspondant. L’unboxing est l’opération inverse. Cela permet par exemple de faire la chose suivante


Integer i = 100;
Integer x = 100;

if (i == x) {
System.out.println("(i = 100) == (x = 100)");
}

Ce qui donne :

(i = 100) == (x = 100)

Ce n’est donc pas l’adresse mémoire des deux Integers qui est comparée. Les Objets Integers x et i sont transformés en primitives, la valeur de ces primitives est ensuite comparée.

Regardons l’exemple suivant :


Integer i = 10000;
Integer x = 10000;

if (i != x) {
System.out.println("(i = 10000) != (x = 10000)");
}
if (i == x) {
System.out.println("(i = 10000) == (x = 10000)");
}

Ce qui donne :

(i = 10000) != (x = 10000)

Comment cela est il possible?

Utiliser l’opérateur == avec des Wrappers est valide sur des Booleans, Bytes, Characters de \u0000 à \u007f (127 en décimal), Shorts et Integers de -128 à 127. Il y a donc cette limite (-128..127) à respecter ce qui rend l’utilisation de l’opérateur == sur des wrappers risquée.

Mais regardons encore un peu plus en détail cet exemple


Integer i = 10000;
int x = 10000;

if (i != x) {
  System.out.println("(i = 10000) != (x = 10000)");
}
if (i == x) {
  System.out.println("(i = 10000) == (x = 10000)");
}

Ce qui donne :

(i = 10000) == (x = 10000)

On constate que lorsqu’un des opérandes est une primitive l’unboxing est réalisé.

Résumons :

  • L’opérateur == avec des Wrappers est valide sur des :
    • Booleans,
    • Bytes,
    • Characters de \u0000 à \u007f (127 en décimal),
    • Shorts et Integers de -128 à 127.
  • Lorsqu’un des opérandes est une primitive la comparaison est correctement réalisée.

Mais rien ne vaut un test unitaire pour illustrer ce comportement   :


/*
* Unit Test on == operator with wrapper
*/
package wrappers.brouillon;
import org.junit.Test;
import static org.junit.Assert.*;

/**
*
* @author jo
*/
public class AutoBoxingAlaModeTest {

public AutoBoxingAlaModeTest() {
}

public boolean doEqualsWithWrappers(Integer i, Integer x) {
    if (i == x) {
      return true;
    }
    return false;
  }

public boolean doEqualsWithWrapperAndPrimitive(Integer i, int x) {
    if (i == x) {
      return true;
    }
    return false;
  }

@Test
public void equalOperatorOnWrappers() {
  Integer int1000IObject = 1000;
  Integer int1000XObject = 1000;
  Integer int1000XPrimitif = 1000;

  Integer int100IObject = 100;
  Integer int100XObject = 100;

  assertEquals("Deux Integers avec les mêmes valeurs comprises entre -127 et 128  sont ==",
    true, doEqualsWithWrappers(int100IObject, int100XObject));
  assertEquals("Deux Integers avec les mêmes valeurs non comprises entre -127 et 128 sont !=",
    false, doEqualsWithWrappers(int1000IObject, int1000XObject));
  assertEquals("Un Integer et une primitive avec les mêmes valeurs non comprises entre -127 et 128  sont ==",
    true, doEqualsWithWrapperAndPrimitive(int1000IObject, int1000XPrimitif));
  }
}

Mots-clefs :

Comments are closed.