Le code suivant génère un NPE pour moi :
int num = Integer.getInteger("123");
mon compilateur invoque-t-il getInteger sur null puisqu'il est statique ? cela n'a aucun sens !
Quelqu'un peut-il expliquer ce qui se passe ?
Merci.
Le code suivant génère un NPE pour moi :
int num = Integer.getInteger("123");
mon compilateur invoque-t-il getInteger sur null puisqu'il est statique ? cela n'a aucun sens !
Quelqu'un peut-il expliquer ce qui se passe ?
Merci.
Il y a deux problèmes en jeu ici :
Integer getInteger(String)
ne fait pas ce que vous pensez qu'il fait
null
dans ce casInteger
a int
provoque un déblocage automatique
Integer
es null
, NullPointerException
est jetéPour analyser (String) "123"
a (int) 123
vous pouvez utiliser par exemple int Integer.parseInt(String)
.
Integer
Références APIInteger.getInteger
Voici ce que la documentation a à dire sur ce que fait cette méthode :
public static Integer getInteger(String nm)
: Détermine la valeur entière de la propriété système portant le nom spécifié. S'il n'y a pas de propriété avec le nom spécifié, si le nom spécifié est vide ou s'il n'y a pas de propriété avec le nom spécifié.null
ou si la propriété n'a pas le format numérique correct, alorsnull
est renvoyé.
En d'autres termes, cette méthode n'a rien à voir avec l'analyse syntaxique d'un fichier de type String
à un int/Integer
mais il s'agit plutôt d'une question de System.getProperty
méthode.
Il est vrai que cela peut être une surprise. Il est malheureux que la bibliothèque réserve de telles surprises, mais cela vous apprend une leçon précieuse : consultez toujours la documentation pour confirmer ce que fait une méthode.
Par coïncidence, une variation de ce problème a été présenté dans Le retour des casse-têtes : Schlock et Awe (TS-5186) , la présentation de Josh Bloch et Neal Gafter lors de la session technique JavaOne 2009. Voici la diapositive de conclusion :
La morale
- Des méthodes étranges et terribles se cachent dans les bibliothèques
- Certains ont des noms à consonance inoffensive
- Si votre code se comporte mal
- Assurez-vous que vous appelez les bonnes méthodes
- Lire la documentation de la bibliothèque
- Pour les concepteurs d'API
- Ne pas violer le principe du moindre étonnement
- Ne pas violer la hiérarchie d'abstraction
- N'utilisez pas de noms similaires pour des comportements très différents.
Pour être complet, il y a aussi ces méthodes qui sont analogues à Integer.getInteger
:
L'autre question, bien sûr, c'est de savoir comment les NullPointerException
est jeté. Pour nous concentrer sur ce problème, nous pouvons simplifier l'extrait comme suit :
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Voici une citation de Effective Java 2nd Edition, Item 49 : Prefer primitive types to boxed primitives :
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'élément
==
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 lancerNullPointerException
. 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.
De http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :
getInteger "Détermine la valeur entière de la propriété système portant le nom spécifié.
Tu veux ça :
Integer.parseInt("123")
Veuillez vérifier la documentation de la méthode getInteger() . Dans cette méthode, le String
Le paramètre est une propriété système qui détermine la valeur entière de la propriété système portant le nom spécifié. "123" n'est pas le nom d'une propriété système, comme nous l'avons vu. aquí . Si vous voulez convertir cette chaîne en int
puis utiliser la méthode suivante int num = Integer.parseInt("123")
.
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.