Perché int num = Integer.getInteger ( “123”) lanciano NullPointerException?
-
30-09-2019 - |
Domanda
Il seguente codice getta NullPointerException
:
int num = Integer.getInteger("123");
Il mio compilatore invocando getInteger
sul nulla visto che è statica? Questo non ha alcun senso!
Che cosa sta succedendo?
Soluzione
The Big Picture
Ci sono due questioni in gioco qui:
-
Integer getInteger(String)
non fa quello che pensi lo fa- Si ritorna
null
in questo caso
- Si ritorna
- l'assegnazione da
Integer
aint
fa sì che l'auto-unboxing- Dato che il
Integer
ènull
,NullPointerException
è gettato
- Dato che il
Per analizzare (String) "123"
a (int) 123
, è possibile utilizzare per esempio int Integer.parseInt(String)
.
Bibliografia
Integer
riferimenti API
On Integer.getInteger
Ecco quello che la documentazione hanno da dire su ciò che questo metodo non:
public static Integer getInteger(String nm)
: determina il valore intero della proprietà di sistema con il nome specificato. Se non v'è alcuna proprietà con il nome specificato, se il nome specificato è vuoto onull
, o se la proprietà non ha il formato numerico corretto, alloranull
viene restituito.
In altre parole, questo metodo non ha nulla a che fare con l'analisi di un String
per un valore int/Integer
, ma piuttosto, ha a che fare con System.getProperty
metodo.
È vero che questo può essere una sorpresa. E 'un peccato che la biblioteca ha sorprese come questo, ma lo fa si insegna una lezione importante:. Sempre guardare la documentazione per confermare ciò che fa un metodo
Coincindentally, una variante di questo problema è stato descritto in il ritorno dello Puzzlers: schlock and Awe (TS-5186) , Josh Bloch e il 2009 la presentazione JavaOne sessione tecnica di Neal GDopo. Ecco la presentazione conclusiva:
The Moral
- Strano e metodi terribili si nascondono nelle biblioteche
- Alcune hanno nomi dal suono innocuo
- Se i tuoi comporta male codice
- Assicurarsi che si sta chiamando i metodi giusti
- Leggi la documentazione della libreria
- Per i progettisti API
- Non violare il principio di minima sorpresa
- Non violare l'astrazione gerarchia
- Non utilizzare nomi simili per molto diversi comportamenti
Per completezza, ci sono anche questi metodi analoghi a Integer.getInteger
:
Domande correlate
- più sorprendente Violazione del principio del minimo stupore
- maggior parte imbarazzante / metodo fuorviante in Java API Base?
On autounboxing
L'altra questione, naturalmente, è come il NullPointerException
si butta. Per mettere a fuoco il problema, siamo in grado di semplificare il frammento come segue:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Ecco una citazione da Effective Java 2nd Edition, Articolo 49: Preferisco tipi primitivi di primitive in scatola:
In sintesi, l'uso primitive a preferenza di boxed primitiva ogni volta che si ha la scelta. I tipi primitivi sono più semplici e più veloci. Se è necessario utilizzare primitive in scatola, fate attenzione! Autoboxing riduce il livello di dettaglio, ma non il pericolo, di utilizzare primitive in scatola. Quando il programma mette a confronto due primitive in scatola con l'operatore
==
, lo fa un confronto identità, che è quasi certamente non quello che volete. Quando il programma fa di tipo misto calcoli che coinvolgono primitive boxed e unboxed, lo fa unboxing, e quando il programma fa unboxing, si può buttareNullPointerException
. Infine, quando i contenitori di programma valori primitivi, può tradursi in creazioni di oggetti costosi e inutili.
Ci sono luoghi dove si ha altra scelta che utilizzare primitive in scatola, per esempio farmaci generici, ma per il resto si dovrebbe considerare seriamente se la decisione di utilizzare le primitive in scatola è giustificata.
Domande correlate
- Qual è la differenza tra un int e un intero in Java / C #?
- Perché autoboxing in Java mi permette di avere 3 possibili valori per un valore booleano?
- E 'garantito che new Integer (i) == Ho in Java? (SI !!!)
- Quando si confrontano due numeri interi in Java fa auto- unboxing verificarsi? (NO !!!)
- Java NOOB:? Generici sugli oggetti solo (sì, purtroppo )
Altri suggerimenti
http://konigsberg.blogspot.com /2008/04/integergetinteger-are-you-kidding-me.html :
getInteger 'Determina il valore intero della proprietà di sistema con il nome specificato.'
Si vuole in questo modo:
Integer.parseInt("123")
Si prega di verificare la documentazione del metodo String è una proprietà di sistema che determina il valore intero della proprietà di sistema con il nome specificato. "123" non è il nome di qualsiasi proprietà di sistema, come discusso qui .
Se si desidera convertire questa stringa int
, quindi utilizzare il metodo come
int num = Integer.parseInt("123")
.