Pourquoi int num = Integer.getInteger ("123") lance-t-il une exception NullPointerException?

Réponses:

212

La grande image

Il y a deux problèmes en jeu ici:

  • Integer getInteger(String) ne fait pas ce que tu penses qu'il fait
    • Il revient nulldans ce cas
  • l'affectation de Integerà intprovoque un déballage automatique
    • Depuis le Integerest null, NullPointerExceptionest jeté

Pour analyser (String) "123"à (int) 123, vous pouvez utiliser par exemple int Integer.parseInt(String).

Références

Integer Références API


Sur Integer.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 ou null, ou si la propriété n'a pas le format numérique correct, alors nullest retourné.

En d'autres termes, cette méthode n'a rien à voir avec l'analyse Stringd'une int/Integervaleur, mais plutôt avec la System.getPropertymé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:

Questions connexes


Sur l'autounboxing

L'autre problème, bien sûr, est de savoir comment le NullPointerExceptionest 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 lancer NullPointerException. 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.

Questions connexes

lubrifiants polygènes
la source
11
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.
MatrixFrog
5
Dès que j'ai posté ce commentaire, j'ai réalisé que je pouvais simplement regarder la source réelle de la classe Integer! J'étais sur la bonne voie, sauf qu'il utilise à la Integer.decodeplace de Integer.parseInt, qui recherche un début 0xou 0pour analyser le nombre en hexadécimal ou octal, respectivement.
MatrixFrog
Pour ceux qui se demandent pourquoi NullPointerException? : programmers.stackexchange.com/questions/158908/…
ROMANIA_engineer
2
@Oracle pouvez-vous déprécier java.lang.Integer.getInteger (String) s'il vous plaît?
mjaggard
6

Veuillez consulter la documentation de la méthode getInteger () . Dans cette méthode, le Stringparamè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").

Sonal Patil
la source