¿Por qué int num = Integer.getInteger ( “123”) arroja NullPointerException?
-
30-09-2019 - |
Pregunta
El siguiente código lanza NullPointerException
:
int num = Integer.getInteger("123");
Es mi compilador invocando getInteger
en nula, ya que de estática? Eso no tiene ningún sentido!
¿Qué ocurre?
Solución
El cuadro grande
Hay dos cuestiones en juego aquí:
-
Integer getInteger(String)
no hace lo que usted cree- Devuelve
null
en este caso
- Devuelve
- la asignación de
Integer
aint
causa de auto-unboxing- Desde el
Integer
esnull
,NullPointerException
se lanza
- Desde el
Para analizar (String) "123"
a (int) 123
, se puede utilizar, por ejemplo, int Integer.parseInt(String)
.
Referencias
Integer
referencias API
En Integer.getInteger
Esto es lo que la documentación tiene que decir acerca de lo que hace este método:
public static Integer getInteger(String nm)
: Determina el valor entero de la propiedad del sistema con el nombre especificado. Si no hay ninguna propiedad con el nombre especificado, si el nombre especificado está vacío onull
, o si la propiedad no tiene el formato numérico correcto, entonces se devuelvenull
.
En otras palabras, este método no tiene nada que ver con el análisis de un String
a un valor int/Integer
, sino que más bien tiene que ver con System.getProperty
método.
Es cierto que esto puede ser una gran sorpresa. Es desafortunado que la biblioteca tiene sorpresas como esta, pero le enseña una valiosa lección:. Siempre consultar la documentación para confirmar lo que lo hace un método
Coincindentally, una variación de este problema se presentó en el retorno de los Puzzlers: Schlock y admiración (TS-5186) , Josh Bloch y documento de la Sesión técnica JavaOne 2009 de Neal Gafter. Aquí está la diapositiva de conclusión:
El Moral
- Extraño y métodos terribles están al acecho en las bibliotecas
- Algunos tienen nombres que suenan inocuas
- Si su código se comporta mal
- Asegúrese de que está llamando a los métodos adecuados
- Lea la documentación de la biblioteca
- Para los diseñadores de API
- No viole el principio de mínima sorpresa
- No viola la jerarquía de abstracción
- No utilice nombres similares a comportamientos diferentes
Para completar, hay también estos métodos que son análogos a Integer.getInteger
:
preguntas relacionadas
- más sorprendente Violación del principio de la mínima sorpresa
- más torpe método / engañosa en base API Java?
En autounboxing
El otro problema, por supuesto, es cómo el NullPointerException
se tira. Para centrarse en este tema, podemos simplificar el fragmento de la siguiente manera:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Aquí hay una cita de Java eficaz 2ª edición, artículo 49: Prefiero tipos primitivos a los primitivos enmarcadas:
En resumen, el uso de las primitivas en preferencia a caja primitiva cada vez que tenga la elección. Los tipos primitivos son más simples y más rápido. Si tiene que usar primitivas en caja, tenga cuidado! Autoboxing reduce el nivel de detalle, pero no el peligro, de la utilización de las primitivas en caja. Cuando el programa compara dos primitivas en caja con el operador
==
, se hace una comparación de identidad, que es casi seguro que no lo desea. Cuando el programa hace cálculos de tipo mixto que implican primitivas en caja y sin caja, que hace unboxing, y cuando el programa hace unboxing, se puede lanzarNullPointerException
. Por último, cuando sus cajas de programas valores primitivos, que puede dar lugar a creaciones de objetos costosos e innecesarios.
Hay lugares donde hay más remedio que utilizar primitivas en caja, por ejemplo, genéricos, pero por lo demás usted debe considerar seriamente si la decisión de utilizar las primitivas en caja está justificada.
preguntas relacionadas
- Cuál es el diferencia entre un entero y un entero en Java / C #?
- ¿por qué autoboxing en Java me permite tener 3 valores posibles para un booleano?
- ¿Está garantizado que new Integer (i) == i en Java? (SÍ !!!)
- Al comparar dos enteros en Java hace auto unboxing ocurrir? (NO !!!)
- Java Noob:? Genéricos más objetos sólo (sí, por desgracia )
Otros consejos
http://konigsberg.blogspot.com /2008/04/integergetinteger-are-you-kidding-me.html :
getInteger 'Determina el valor entero de la propiedad del sistema con el nombre especificado.'
¿Quieres esto:
Integer.parseInt("123")
Por favor, compruebe la documentación del método String es una propiedad del sistema que determina el valor entero de la propiedad del sistema con el nombre especificado. "123" no es el nombre de cualquier propiedad del sistema, como se discutió aquí .
Si desea convertir esta cadena para int
, a continuación, utilizar el método que se
int num = Integer.parseInt("123")
.