Der folgende Code wirft NullPointerException:
int num = Integer.getInteger("123");
Ruft mein Compiler getIntegernull auf, da er statisch ist? Das macht keinen Sinn!
Was ist los?
Der folgende Code wirft NullPointerException:
int num = Integer.getInteger("123");
Ruft mein Compiler getIntegernull auf, da er statisch ist? Das macht keinen Sinn!
Was ist los?
Antworten:
Hier spielen zwei Probleme eine Rolle:
Integer getInteger(String) tut nicht das, was du denkst
nullin diesem FallIntegerbis intbewirkt das automatische Entpacken
Integerheißt null, NullPointerExceptiongeworfen wirdAnalysieren (String) "123"zu (int) 123können Sie zB verwenden int Integer.parseInt(String).
Integer API-ReferenzenInteger.getIntegerIn der Dokumentation wird Folgendes zu dieser Methode gesagt:
public static Integer getInteger(String nm): Bestimmt den ganzzahligen Wert der Systemeigenschaft mit dem angegebenen Namen. Wenn es keine Eigenschaft mit dem angegebenen Namen gibt, wenn der angegebene Name leernullist oder wenn die Eigenschaft nicht das richtige numerische Format hat,nullwird zurückgegeben.
Mit anderen Worten, diese Methode hat nichts mit dem Parsen von a Stringzu einem int/IntegerWert zu tun, sondern mit der System.getPropertyMethode.
Zugegeben, das kann eine ziemliche Überraschung sein. Es ist bedauerlich, dass die Bibliothek solche Überraschungen bietet, aber sie lehrt Sie eine wertvolle Lektion: Schauen Sie immer in der Dokumentation nach, um zu bestätigen, was eine Methode tut.
Zufälligerweise wurde eine Variante dieses Problems in Return of the Puzzlers vorgestellt: Schlock und Awe (TS-5186) , Josh Bloch und Neal Gafters Präsentation der JavaOne Technical Session 2009. 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
- Verstoße nicht gegen das Prinzip des geringsten Erstaunens
- Verletzen Sie nicht die Abstraktionshierarchie
- Verwenden Sie keine ähnlichen Namen für völlig unterschiedliche Verhaltensweisen
Der Vollständigkeit halber gibt es auch diese Methoden, die analog sind zu Integer.getInteger:
Das andere Problem ist natürlich, wie das NullPointerExceptiongeworfen wird. 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, Punkt 49: Bevorzugen Sie primitive Typen gegenüber primitiven Boxen:
Zusammenfassend lässt sich sagen, dass Sie Primitive gegenüber Boxed-Primitiven bevorzugen, wenn Sie die Wahl haben. Primitive Typen sind einfacher und schneller. Wenn Sie Grundelemente in Schachteln verwenden müssen, seien Sie vorsichtig! Autoboxing reduziert die Ausführlichkeit, aber nicht die Gefahr der Verwendung von Grundelementen in Schachteln. Wenn Ihr Programm zwei Grundelemente mit dem
==Operator vergleicht, führt es einen Identitätsvergleich durch, der mit ziemlicher Sicherheit nicht Ihren Wünschen entspricht. Wenn Ihr Programm Berechnungen vom gemischten Typ mit primitiven Box- und Unboxed-Grundelementen ausführt, wird das Unboxing ausgeführt, und wenn Ihr Programm das Unboxing ausführt, kann es ausgelöst werdenNullPointerException. Wenn Ihr Programm primitive Werte enthält, kann dies zu kostspieligen und unnötigen Objekterstellungen führen.
Es gibt Orte, an denen Sie keine andere Wahl haben, als Box-Primitive zu verwenden, z. B. Generika. Andernfalls sollten Sie ernsthaft überlegen, ob eine Entscheidung zur Verwendung von Box-Primitiven gerechtfertigt ist.
Integer.getInteger(s)also ungefähr gleichbedeutend mit 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 abrufen.
Integer.decodestattdessen verwendet Integer.parseInt, was nach einem führenden Wert sucht 0xoder 0die Zahl als hexadezimal bzw. oktal analysiert.
NullPointerException? : programmers.stackexchange.com/questions/158908/…
Von http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :
getInteger 'Bestimmt den ganzzahligen Wert der Systemeigenschaft mit dem angegebenen Namen.'
Du willst das:
Integer.parseInt("123")
Bitte überprüfen Sie die Dokumentation der Methode getInteger () . Bei dieser Methode ist der StringParameter eine Systemeigenschaft, die den ganzzahligen Wert der Systemeigenschaft mit dem angegebenen Namen bestimmt. "123" ist nicht der Name einer Systemeigenschaft, wie hier erläutert . Wenn Sie diesen String in konvertieren möchten int, verwenden Sie die Methode als
int num = Integer.parseInt("123").