300 votes

Lors de la comparaison de deux nombres entiers en Java, l'auto-unboxing se produit-il ?

Je sais que si vous comparez un Integer primitif encadré avec une constante telle que :

Integer a = 4;
if (a < 5)

a sera automatiquement débloqué et la comparaison fonctionnera.

Cependant, que se passe-t-il lorsque vous comparez deux nombres entiers encadrés et que vous voulez comparer soit l'égalité, soit un nombre inférieur/ supérieur à ?

Integer a = 4;
Integer b = 5;

if (a == b)

Est-ce que cela aura pour effet de vérifier s'il s'agit du même objet, ou est-ce que le système se débloquera automatiquement dans ce cas ?

Qu'en est-il :

Integer a = 4;
Integer b = 5;

if (a < 5)

401voto

Jon Skeet Points 692016

Non, == entre les nombres entiers, longs, etc. égalité de référence - c'est-à-dire

Integer x = ...;
Integer y = ...;

System.out.println(x == y);

ce qui permettra de vérifier si x et y se référer à la même objet plutôt que égal objets.

Alors

Integer x = new Integer(10);
Integer y = new Integer(10);

System.out.println(x == y);

est garanti d'imprimer false . L'internage de "petites" valeurs autoboxées peut conduire à des résultats délicats :

Integer x = 10;
Integer y = 10;

System.out.println(x == y);

Ceci imprimera true en raison des règles de la boxe ( JLS section 5.1.7 ). C'est toujours l'égalité de référence qui est utilisée, mais les références véritablement sont égal.

Personnellement, j'utiliserais :

if (x.intValue() == y.intValue())

ou

if (x.equals(y))

Cette dernière est légèrement moins efficace - il n'y a pas de surcharge de Integer.equals(Integer) il devra donc effectuer une vérification de type au moment de l'exécution, tandis que la première utilise le fait que nous savons déjà que les deux objets sont Integer s.

Heureusement, compareTo connaît les types, donc :

if (x.compareTo(y) < 0)

devrait encore être efficace. Bien sûr, c'est le domaine de la micro-optimisation et vous devriez utiliser le code que vous trouvez le plus clair - après vous être assuré qu'il est correct :)

Comme vous le dites, pour toute comparaison entre un type de wrapper ( Integer , Long etc) et un type numérique ( int , long etc.) la valeur du type de wrapper est non emballé et le test est appliqué aux valeurs primitives concernées.

Cela se produit dans le cadre de la promotion numérique binaire ( JLS section 5.6.2 ). Consultez la documentation de chaque opérateur individuel pour savoir s'il est appliqué. Par exemple, dans la documentation de == et != ( JLS 15.21.1 ) :

Si les opérandes d'un opérateur d'égalité sont tous deux de type numérique, ou l'un est de type numérique et l'autre est convertible (§5.1.8) en type numérique, la promotion numérique binaire est utilisée. numérique, une promotion numérique binaire est binaire est effectuée sur les opérandes (§5.6.2).

et pour <, <=, > et >= ( JLS 15.20.1 )

Le type de chacun des opérandes d'un opérateur de comparaison numérique doit être le suivant opérateur de comparaison numérique doit être un type qui est convertible (§5.1.8) en un type numérique primitif, ou une erreur de compilation. Binaire numérique est effectuée sur les opérandes (§5.6.2). Si le type promu des opérandes est int ou long, alors la comparaison avec un entier signé est effectuée ; si ce type promu est float ou double, la comparaison avec des est effectuée.

Notez que rien de tout cela n'est considéré comme faisant partie de la situation dans laquelle ni Le type est un type numérique.

49voto

Adam Lewis Points 173

== testera toujours l'égalité des objets. Il est cependant facile de se faire avoir :

Integer a = 10;
Integer b = 10;

System.out.println(a == b); //prints true

Integer c = new Integer(10);
Integer d = new Integer(10);

System.out.println(c == d); //prints false

Vos exemples avec des inégalités fonctionneront puisqu'elles ne sont pas définies sur les objets. Cependant, avec les == l'égalité des objets sera toujours vérifiée. Dans ce cas, lorsque vous initialisez les objets d'une primitive boxée, le même objet est utilisé (pour a et b). C'est une optimisation acceptable puisque les classes de boîtes primitives sont immuables.

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