Question

Considérez ce code:

class test {
   public static void main(String[] args) {
      test inst_test = new test();
      int i1 = 2000;
      int i2 = 2000;
      int i3 = 2;
      int i4 = 2;
      Integer Ithree = new Integer(2); // 1
      Integer Ifour = new Integer(2); // 2
      System.out.println( Ithree == Ifour );
      inst_test.method( i3 , i4 );
      inst_test.method( i1 , i2 );
   }
   public void method( Integer i , Integer eye ) {
      System.out.println(i == eye );
   }
}

Il imprime:

false
true
false

Je comprends le premier false, l'opérateur == vérifie uniquement si deux références travaillent sur le même objet, qui dans ce cas ne sont pas.

Le true et false suivants ont me gratter la tête. Pourquoi Java envisager i3 et i4 égaux mais i1 et i2 différent? Tous deux ont été enveloppés d'entier, ne devrait pas deux évaluer false? Y at-il une raison pratique de cette incohérence?

Était-ce utile?

La solution

Autoboxing des primitives en objets (comme dans vos appels vers method utilise un cache de petites valeurs. De la section spécification du langage Java 5.1.7 :

  

Si la valeur p étant boxed est vrai,   faux, un octet, un produit de carbonisation dans la plage   \ U0000 à \ u007f, ou un int ou court   entre -128 et 127, puis laissez   r1 et r2 soient les résultats des deux   conversions de boxe de p. C'est toujours   le cas où r1 == r2.

La partie de la discussion de la spécification immédiatement après c'est trop intéressant. Notamment une machine virtuelle Java peut mettre en cache plus valeurs si elle veut - vous ne pouvez pas être sûr des résultats de le faire:

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);

Autres conseils

Quand autoboxing, entiers compris entre -128 et 127 sont mises en cache, et le même objet d'emballage est retourné. La même chose avec les valeurs booléennes et des valeurs de type char entre \ u0000 et \ u007F

est ce que vous obtenez la plupart du temps, mais il dépend de la mise en œuvre JVM.

Ceci est parce que la boxe fait des entiers en dessous d'une certaine valeur (128, je pense) réfère à un objet préconstruit, et des valeurs plus élevées de nouveaux objets.

autoboxing utilisations Integer.valueOf (i) , non new Integer (i), pour construire un objet de classe Integer.

Comme les autres l'ont dit, valueOf () utilise un cache, la plupart du temps pour l'efficacité de l'espace.

Ne pas utiliser == sur les types de référence, il est presque toujours une erreur.

classe entière contient un cache de certains cas fréquemment utilisés. La plage de valeurs varie généralement de JVM à JVM (est parfois aussi configurable), mais en général, le code correspondant est quelque chose comme:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

(Code de soleil JDK 1.6)

est comme chaîne interner, car il sert à économiser de la mémoire et permet l'égalité de test en utilisant une référence (par exemple == à la place de égal )

Je suppose que l'emballage tente de minimiser le nombre d'objets entiers et ne crée qu'un seul objet représentant 2 trop économiser de la mémoire.

Rappelez-vous de ne jamais utiliser == sur les objets que vous ne savez jamais ce qui se passe.

Autoboxing utiliser un mécanisme de mise en cache. En général, vous ne devriez jamais compter sur ==, utilisez toujours equals pour vérifier l'égalité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top