Der folgende Code wirft NullPointerException
:
int num = Integer.getInteger("123");
Wird mein Compiler aufgerufen getInteger
auf null, da es statisch ist? Das macht keinen Sinn!
Was ist los?
Benutzer282886
Der folgende Code wirft NullPointerException
:
int num = Integer.getInteger("123");
Wird mein Compiler aufgerufen getInteger
auf null, da es statisch ist? Das macht keinen Sinn!
Was ist los?
polygenelubricants
Hier spielen zwei Probleme eine Rolle:
Integer getInteger(String)
macht nicht das, was du denkst
null
in diesem FallInteger
zu int
bewirkt ein automatisches Unboxing
Integer
ist null
, NullPointerException
ist geworfenAnalysieren (String) "123"
zu (int) 123
Sie können z int Integer.parseInt(String)
.
Integer
API-ReferenzenInteger.getInteger
Hier ist, was die Dokumentation darüber zu sagen hat, was diese Methode tut:
public static Integer getInteger(String nm)
: Ermittelt den ganzzahligen Wert der Systemeigenschaft mit dem angegebenen Namen. Wenn es keine Eigenschaft mit dem angegebenen Namen gibt, wenn der angegebene Name leer ist odernull
oder wenn die Eigenschaft nicht das richtige numerische Format hat, dannnull
ist zurück gekommen.
Mit anderen Worten, diese Methode hat nichts mit dem Parsen von a zu tun String
zu einem int/Integer
Wert, sondern hat damit zu tun System.getProperty
Methode.
Zugegeben, das kann eine ziemliche Überraschung sein. Es ist bedauerlich, dass die Bibliothek solche Überraschungen bereithält, aber sie lehrt Sie eine wertvolle Lektion: Schlagen Sie immer in der Dokumentation nach, um zu bestätigen, was eine Methode tut.
Zufälligerweise wurde eine Variation dieses Problems in vorgestellt Rückkehr der Puzzler: Schlock und Ehrfurcht (TS-5186), Präsentation auf der JavaOne Technical Session 2009 von Josh Bloch und Neal Gafter. Hier ist die abschließende Folie:
Die Moral
- In Bibliotheken lauern seltsame und schreckliche Methoden
- Einige haben harmlos klingende Namen
- Wenn sich Ihr Code schlecht verhält
- Stellen Sie sicher, dass Sie die richtigen Methoden aufrufen
- Lesen Sie die Bibliotheksdokumentation
- Für API-Designer
- Verletzen Sie nicht das Prinzip des geringsten Erstaunens
- Verletzen Sie nicht die Abstraktionshierarchie
- Verwenden Sie keine ähnlichen Namen für sehr unterschiedliche Verhaltensweisen
Der Vollständigkeit halber gibt es auch diese analogen Methoden Integer.getInteger
:
Die andere Frage ist natürlich, wie die NullPointerException
wird geworfen. Um uns auf dieses Problem zu konzentrieren, können wir das Snippet wie folgt vereinfachen:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Hier ist ein Zitat aus Effective Java 2nd Edition, Item 49: Prefer primitive types to boxed primitives:
Zusammenfassend sollten Sie Primitiven immer dann bevorzugen, wenn Sie die Wahl haben. Primitive Typen sind einfacher und schneller. Wenn Sie geschachtelte Primitive verwenden müssen, seien Sie vorsichtig! Autoboxing reduziert die Ausführlichkeit, aber nicht die Gefahr, Boxed Primitives zu verwenden. Wenn Ihr Programm zwei eingerahmte Primitive mit dem vergleicht
==
Betreiber, führt er einen Identitätsvergleich durch, was mit ziemlicher Sicherheit nicht das ist, was Sie wollen. Wenn Ihr Programm gemischte Berechnungen mit Boxed- und Unboxed-Primitiven durchführt, führt es ein Unboxing durch, und wenn Ihr Programm ein Unboxing durchführt, kann es werfenNullPointerException
. Wenn Ihr Programm schließlich primitive Werte verschachtelt, kann dies zu kostspieligen und unnötigen Objekterstellungen führen.
Es gibt Stellen, an denen Sie keine andere Wahl haben, als Boxed Primitives zu verwenden, zB Generika, aber ansonsten sollten Sie ernsthaft überlegen, ob eine Entscheidung für Boxed Primitives gerechtfertigt ist.
Damit Integer.getInteger(s)
entspricht in etwa Integer.parseInt(System.getProperty(s))
? Ich glaube, ich bevorzuge die zweite, obwohl sie ausführlicher ist, weil sie die Tatsache hervorhebt, dass Sie Informationen aus den Systemeigenschaften ziehen.
– Tyler
26. Juni 2010 um 19:54 Uhr
Sobald ich diesen Kommentar gepostet hatte, wurde mir klar, dass ich mir einfach die eigentliche Quelle der Integer-Klasse ansehen konnte! Ich war auf dem richtigen Weg, außer dass es nutzt Integer.decode
anstatt Integer.parseInt
die nach einem führenden sucht 0x
oder 0
um die Zahl als hexadezimal bzw. oktal zu analysieren.
– Tyler
26. Juni 2010 um 19:59 Uhr
Für die, die fragen Warum NullPointerException
?: programers.stackexchange.com/questions/158908/…
– RUMÄNIEN_Ingenieur
28. Dezember 2015 um 13:07 Uhr
@Oracle können Sie java.lang.Integer.getInteger(String) bitte verwerfen?
– mjaggard
9. Oktober 2018 um 11:11 Uhr
Kyren Johnstone
Von http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html:
getInteger ‘Ermittelt den ganzzahligen Wert der Systemeigenschaft mit dem angegebenen Namen.’
Du willst das:
Integer.parseInt("123")
Sonal Patil
Bitte überprüfen Sie die Dokumentation der Methode getInteger(). Bei dieser Methode wird die String
parameter ist eine Systemeigenschaft, die den ganzzahligen Wert der Systemeigenschaft mit dem angegebenen Namen bestimmt. “123” ist nicht der Name irgendeiner Systemeigenschaft, wie besprochen Hier. Wenn Sie diesen String konvertieren möchten int
dann verwenden Sie die Methode als
int num = Integer.parseInt("123")
.
Verwenden Sie stattdessen Integer.getValue(). Dieser Blogbeitrag ist eine gute Erklärung, warum: königsberg.blogspot.in/2008/04/…
– Pranaysharma
26. April 2015 um 12:10 Uhr