La réponse courte
Le point essentiel est le suivant :
-
==
entre deux types de référence est toujours une comparaison de référence
- Le plus souvent, par exemple dans le cas de
Integer
y String
vous devriez utiliser equals
au lieu de
-
==
entre un type de référence et un type numérique primitif est toujours une comparaison numérique.
- Le type de référence fera l'objet d'une conversion au déballage.
- Unboxing
null
jette toujours NullPointerException
- Bien que Java dispose de nombreux traitements spéciaux pour
String
il n'est en fait PAS un type primitif.
Les déclarations ci-dessus sont valables pour toute valide Code Java. Dans ces conditions, il n'y a aucune incohérence dans l'extrait que vous avez présenté.
La longue réponse
Voici les sections pertinentes de JLS :
Si les opérandes d'un opérateur d'égalité sont tous deux de type référence ou de type null l'opération est alors une égalité d'objets.
Ceci explique ce qui suit :
Integer i = null;
String str = null;
if (i == null) { // Nothing happens
}
if (str == null) { // Nothing happens
}
if (str == "0") { // Nothing happens
}
Les deux opérandes sont des types de référence, et c'est pourquoi la fonction ==
est une comparaison d'égalité de référence.
Ceci explique également ce qui suit :
System.out.println(new Integer(0) == new Integer(0)); // "false"
System.out.println("X" == "x".toUpperCase()); // "false"
Para ==
pour être une égalité numérique, au moins un des opérandes doit être de type numérique :
Si les opérandes d'un opérateur d'égalité sont les deux de type numérique, ou on est de type numérique et l'autre est convertible au type numérique, la promotion numérique binaire est effectuée sur les opérandes. Si le type promu des opérandes est int
o long
alors un test d'égalité des nombres entiers est effectué ; si le type promu est float or
double`, alors un test d'égalité en virgule flottante est effectué.
Notez que la promotion numérique binaire effectue la conversion des ensembles de valeurs et la conversion de l'unboxing.
Ceci explique :
Integer i = null;
if (i == 0) { //NullPointerException
}
Voici un extrait de Effective Java 2e édition, point 49 : Préférer les primitives aux primitives encadrées :
En résumé, utilisez les primitives de préférence aux primitives encadrées chaque fois que vous avez le choix. Les types primitifs sont plus simples et plus rapides. Si vous devez utiliser des primitives encadrées, faites attention ! L'auto-boxage réduit la verbosité, mais pas le danger, de l'utilisation de primitives encadrées. Lorsque votre programme compare deux primitives encadrées avec l'option ==
opérateur, il effectue une comparaison d'identité, ce qui n'est certainement pas ce que vous voulez. Lorsque votre programme effectue des calculs de type mixte impliquant des primitives encadrées et non encadrées, il effectue un unboxing, et lorsque votre programme effectue un unboxing, il peut jeter NullPointerException
. Enfin, lorsque votre programme met en boîte des valeurs primitives, cela peut entraîner des créations d'objets coûteuses et inutiles.
Il y a des endroits où vous n'avez pas d'autre choix que d'utiliser des primitives encadrées, par exemple les génériques, mais autrement vous devriez sérieusement considérer si une décision d'utiliser des primitives encadrées est justifiée.
Références
Questions connexes
Questions connexes
0 votes
Vous obtiendrez une NullPointerException si vous faites str.equals("0").
0 votes
L'opérateur == a déjà été utilisé pour éviter les NPE en toutes circonstances. Pour moi, ce n'est qu'un exemple de plus qui démontre à quel point l'introduction de l'auto-boxing en Java était une mauvaise idée. Il n'est tout simplement pas adapté pour de nombreuses raisons et n'offre rien qui n'ait déjà été fait auparavant. Il ne fait que raccourcir le code tout en masquant ce qui se passe réellement.
0 votes
Mes pensées sont à 180 degrés différentes. Ils n'auraient pas dû inclure les primitives utilisées objets partout. Puis laisser le compilateur optimiser et utiliser les primitives. Il n'y aurait alors aucune confusion.