La comparaison de la classe wrapper avec la primitive utilisant equals () donne un comportement étrange

Considérez ci-dessous la capture de code. nous utilisons equals() pour comparer des objects qui sont significativement équivalents ou non? Ici, les deux valeurs sont significativement égales, mais pourquoi longWrapper.equals(0) renvoie-t-il false ? Et lorsque j’ai comparé la valeur avec l’opérateur == , elle renvoie la valeur true .

  Long longWrapper = 0L; long longPrimitive = 0; System.out.println(longWrapper == 0L); // true System.out.println(longWrapper == 0); //true System.out.println(longWrapper == longPrimitive); //true System.out.println(longWrapper.equals(0L)); //true System.out.println(longWrapper.equals(0)); //false System.out.println(longWrapper.equals(longPrimitive)); //true 

longWrapper.equals(0) renvoie false , car 0 est automatiquement associé à Integer , et non à Long . Comme les deux types sont différents, .equals() renvoie false .

Dans l’intervalle, longWrapper == 0 est true , car la valeur de longwrapper est décochée à 0 et 0 == 0 sans prendre en compte les types primitifs réels.

C’est parce que 0 n’est pas un long – c’est un int, et les wrappers ne convertissent pas Integer en Long

System.out.println(0L == 0) a la valeur True .

so longWrapper == 0 lequel unboxed et le résultat est True .

Et en Long.equals écrit comme –

 781 public boolean More ...equals(Object obj) { 782 if (obj instanceof Long) { 783 return value == ((Long)obj).longValue(); 784 } 785 return false; 786 } 

so System.out.println(longWrapper.equals(0)); renvoie false car 0 sera encadré dans Integer et if (obj instanceof Long) est false.

Lorsque vous comparez 0 == 0L , vous comparez un littéral int à un littéral long . L’ int obtient une promotion long , puis leurs valeurs sont comparées. Puisque les deux sont des zéros, le résultat est true .

Lorsque vous ajoutez la sélection automatique au mélange, les choses sont légèrement différentes. Une primitive est toujours automatiquement associée à son type wrapper. Ici, 0 , qui est un littéral int , est automatiquement associé à une instance d’encapsuleur java.lang.Integer . Puisque java.lang.Long et java.lang.Integer sont des classes différentes, les equals entre elles doivent renvoyer false .

Celui-là:

 System.out.println(longWrapper == 0); 

compare avec == , il décompresse votre Long et vous comparez deux primitives, qui sont toutes deux égales à zéro.

Celui-là:

 System.out.println(longWrapper.equals(0)); 

compare avec des equals , de sorte qu’il inscrit le ( int ) zéro en Integer . Un object Long n’est jamais égal à un object Integer , même s’ils ont le même numéro.

Je pense que c’est parce que le 0 dans la méthode equals est un Integer. Lorsque vous définissez longPrimitive avec 0, ce 0 est converti en valeur longue. la méthode equals accepte tous les objects et pour cette raison, le 0 rest un entier et n’est pas converti. Je suppose que dans la méthode equals, il existe un appel si l’object donné est une instance de longue durée et, puisque ce 0 est un entier, il est faux. J’espère que ceci vous aide

La méthode equals de Long explique pourquoi

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/lang/Long.java#Long.equals%28java.lang.Object%29

Il y a ligne

  if (obj instanceof Long) { 

longWrapper.equals (0) le paramètre deviendrait de type Integer.

Par ailleurs longWrapper.equals (longPrimitive) encapsulera le pamètre en Long.

De la classe Long.java :

 public boolean equals(Object obj) { if (obj instanceof Long) { return value == ((Long)obj).longValue(); } return false; } 

Ainsi, lorsque vous comparez un Long à un int utilisant égal, la condition if échoue et la méthode renvoie false .

Les autres méthodes retournent true raison de l’ autoboxing et du unboxing