Le code suivant jette NullPointerException
:
int num = Integer.getInteger("123");
Mon compilateur invoque-t-il getInteger
sur null car il est statique? Cela n'a aucun sens!
Que ce passe-t-il?
Le code suivant jette NullPointerException
:
int num = Integer.getInteger("123");
Mon compilateur invoque-t-il getInteger
sur null car il est statique? Cela n'a aucun sens!
Que ce passe-t-il?
Réponses:
Il y a deux problèmes en jeu ici:
Integer getInteger(String)
ne fait pas ce que tu penses qu'il fait
null
dans ce casInteger
à int
provoque un déballage automatique
Integer
est null
, NullPointerException
est jetéPour analyser (String) "123"
à (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 avec 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 ounull
, ou si la propriété n'a pas le format numérique correct, alorsnull
est retourné.
En d'autres termes, cette méthode n'a rien à voir avec l'analyse String
d'une int/Integer
valeur, mais plutôt avec la System.getProperty
méthode.
Certes, cela peut être une surprise. Il est malheureux que la bibliothèque ait de telles surprises, mais elle vous apprend une leçon précieuse: recherchez toujours la documentation pour confirmer ce que fait une méthode.
Par coïncidence, une variante de ce problème a été présentée dans Return of the Puzzlers: Schlock and Awe (TS-5186) , Josh Bloch et Neal Gafter's 2009 JavaOne Technical Session présentation. Voici la dernière diapositive:
Le moral
- Des méthodes étranges et terribles se cachent dans les bibliothèques
- Certains ont des noms anodins
- Si votre code se comporte mal
- Assurez-vous d'appeler les bonnes méthodes
- Lire la documentation de la bibliothèque
- Pour les concepteurs d'API
- Ne violez pas le principe du moindre étonnement
- Ne violez pas la hiérarchie d'abstraction
- N'utilisez pas de noms similaires pour des comportements extrêmement différents
Pour être complet, il existe également ces méthodes qui sont analogues à Integer.getInteger
:
L'autre problème, bien sûr, est de savoir comment le NullPointerException
est jeté. Pour nous concentrer sur ce problème, nous pouvons simplifier l'extrait de code comme suit:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Voici une citation de Effective Java 2nd Edition, article 49: Préférez les types primitifs 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, soyez prudent! L'autoboxing 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'
==
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 en boîte et sans boîte, il effectue un déballage, et lorsque votre programme effectue un déballage, il peut lancerNullPointerException
. Enfin, lorsque votre programme contient 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 des génériques, mais sinon vous devriez sérieusement envisager si une décision d'utiliser des primitives encadrées est justifiée.
Integer.getInteger(s)
Est donc à peu près équivalent à Integer.parseInt(System.getProperty(s))
? Je pense que je préfère le second, même s'il est plus détaillé, car il met en évidence le fait que vous extrayez des informations des propriétés du système.
Integer.decode
place de Integer.parseInt
, qui recherche un début 0x
ou 0
pour analyser le nombre en hexadécimal ou octal, respectivement.
NullPointerException
? : programmers.stackexchange.com/questions/158908/…
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 avec le nom spécifié.'
Tu veux ça:
Integer.parseInt("123")
Veuillez consulter la documentation de la méthode getInteger () . Dans cette méthode, le String
paramètre est une propriété système qui détermine la valeur entière de la propriété système avec le nom spécifié. "123" n'est le nom d'aucune propriété système, comme indiqué ici . Si vous souhaitez convertir cette chaîne en int
, utilisez la méthode comme
int num = Integer.parseInt("123")
.