40 votes

Les objets enveloppants entiers partagent les mêmes instances uniquement dans la valeur 127?

Ici, ils sont la même instance:

 Integer integer1 = 127;
Integer integer2 = 127;
System.out.println(integer1 == integer2);  // outputs "true"
 

Mais ici, il y a différentes instances:

 Integer integer1 = 128;
Integer integer2 = 128;
System.out.println(integer1 == integer2);  // outputs "false"
 

Pourquoi les objets wrapper ne partagent-ils la même instance que dans la valeur 127?

35voto

axtavt Points 126632

Parce qu'il est spécifié par Java Langage de Spécification.

JLS 5.1.7 Boxe de Conversion:

Si la valeur p être enfermé dans une boîte est - true, false, un byte, ou un char dans la gamme \u0000 de \u007f, ou un int ou short nombre compris entre -128 et 127 (inclus), puis laissez - r et 1 être les résultats de deux de boxe conversions d' . C'est toujours le cas qu' r.

Idéalement, la boxe une valeur primitive 2, serait toujours un rendement identique de référence. Dans la pratique, cela peut ne pas être réalisable en utilisant les techniques de mise en œuvre. Les règles ci-dessus sont un compromis pragmatique. La finale de la clause ci-dessus exige que certaines valeurs communes, toujours encadré dans impossibles à distinguer les objets. La mise en œuvre peut mettre en cache ces, paresseusement ou volontaire. Pour les autres valeurs, cette formulation n'autorise pas toutes les hypothèses sur l'identité de la boîte valeurs sur le programmeur de la partie. Cela permettrait (mais pas besoin), le partage de certaines ou de toutes ces références.

Cela garantit que, dans la plupart des cas, le comportement sera le désirer, sans imposer indûment les performances, en particulier sur les petits appareils. Moins de mémoire limitée implémentations pourrait, par exemple, la mise en cache tous et p de valeurs, ainsi que r et 1 des valeurs dans la plage de -32K à +32K.

12voto

lucho Points 2320

La source de java.lang.Integer:

 public static Integer valueOf(int i) {
        final int offset = 128;
        if (i >= -128 && i <= 127) { // must cache
            return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
    }
 

À votre santé!

7voto

Peter Lawrey Points 229686

BTW vous pouvez raccourcir votre code à

 System.out.println("Integer 127 == " + ((Integer) 127 == (Integer) 127));
System.out.println("Integer 128 == " + ((Integer) 128 == (Integer) 128));

for(int i=0;i<5;i++) {
    System.out.println(
     "Integer 127 system hash code " + System.identityHashCode((Integer) 127)
     + ", Integer 128 system hash code "+System.identityHashCode((Integer) 128));
}
 

empreintes

 Integer 127 == true
Integer 128 == false
Integer 127 system hash code 1787303145, Integer 128 system hash code 202703779
Integer 127 system hash code 1787303145, Integer 128 system hash code 1584673689
Integer 127 system hash code 1787303145, Integer 128 system hash code 518500929
Integer 127 system hash code 1787303145, Integer 128 system hash code 753416466
Integer 127 system hash code 1787303145, Integer 128 system hash code 1106961350
 

Vous pouvez voir que 127 est le même objet à chaque fois, alors que l'objet pour 128 est différent.

1voto

Kru Points 2419

Parce que les petites valeurs de la plage [-128, 127] sont mises en cache et que les plus grandes ne le sont pas.

Pour insérer des entiers, Java utilise http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#valueOf%28int%29.

1voto

Daniel Kutik Points 4188

En plus des autres réponses, je souhaite ajouter que == compare uniquement les références d'objet. Utilisez .equals() place:

 Integer integer1=128;
Integer integer2=128;
if(integer1.equals(integer2))
  System.out.println(true);
else
  System.out.println(false);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X