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?

È stato utile?

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
  • l'assegnazione da Integer a int fa sì che l'auto-unboxing
    • Dato che il Integer è null, NullPointerException è gettato

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 o null, o se la proprietà non ha il formato numerico corretto, allora null 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


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ò buttare NullPointerException. 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

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").

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top