java - traducir - ¿Por qué String.valueOf(null) arroja una NullPointerException?
string.valueof android (4)
de acuerdo con la documentación, el método String.valueOf(Object obj)
devuelve:
si el argumento es
null
, entonces una cadena igual a"null"
; de lo contrario, seobj.toString()
el valor deobj.toString()
.
Pero ¿cómo es que cuando intento hacer esto?
System.out.println("String.valueOf(null) = " + String.valueOf(null));
arroja NPE en su lugar? (¡Inténtalo tú mismo si no crees!)
Exception in thread "main" java.lang.NullPointerException at java.lang.String.(Unknown Source) at java.lang.String.valueOf(Unknown Source)
¿Cómo es que esto está pasando? ¿Me está mintiendo la documentación? ¿Es este un error importante en Java?
El problema es que el método String.valueOf
está sobrecargado :
El lenguaje de especificación de Java exige que, en este tipo de casos, se elija la sobrecarga más específica :
JLS 15.12.2.5 Elegir el método más específico
Si más de un método de miembro es accesible y aplicable a una invocación de método, es necesario elegir uno para proporcionar el descriptor para el envío del método en tiempo de ejecución. El lenguaje de programación Java usa la regla de que se elige el método más específico .
Un char[]
es un Object
, pero no todo el Object
es un char[]
. Por lo tanto, char[]
es más específico que Object
, y según lo especificado por el lenguaje Java, la String.valueOf(char[])
se elige en este caso.
String.valueOf(char[])
espera que la matriz no sea null
, y dado que en este caso se da null
, arroja NullPointerException
.
La "solución" fácil es convertir el null
explícitamente en Object
siguiente manera:
System.out.println(String.valueOf((Object) null));
// prints "null"
Preguntas relacionadas
- ¿Cómo funciona la distinción de ambigüedad polimorfa?
- ¿Qué sobrecarga se seleccionará para nulo en Java?
Moraleja de la historia
Hay varios importantes:
- Effective Java 2nd Edition, Item 41: Usa la sobrecarga juiciosamente
- El hecho de que puedas sobrecargar, no significa que debes hacerlo todo el tiempo
- Pueden causar confusión (especialmente si los métodos hacen cosas muy diferentes)
- Usando un IDE bueno, puede verificar qué sobrecarga se selecciona en tiempo de compilación
- Con Eclipse, puede pasar el mouse sobre la expresión anterior y ver que efectivamente , se ha seleccionado la sobrecarga
valueOf(char[])
.
- Con Eclipse, puede pasar el mouse sobre la expresión anterior y ver que efectivamente , se ha seleccionado la sobrecarga
- A veces quieres lanzar explícitamente
null
(ejemplos a seguir)
Ver también
En casting null
Hay al menos dos situaciones en las que es necesario emitir explícitamente null
a un tipo de referencia específico:
- Para seleccionar la sobrecarga (como se muestra en el ejemplo anterior)
- Para dar
null
como un único argumento a un parámetro vararg
Un ejemplo simple de este último es el siguiente:
static void vararg(Object... os) {
System.out.println(os.length);
}
Entonces, podemos tener lo siguiente:
vararg(null, null, null); // prints "3"
vararg(null, null); // prints "2"
vararg(null); // throws NullPointerException!
vararg((Object) null); // prints "1"
Ver también
- Java Language Guide / varargs : para comprender cómo se implementa
Preguntas relacionadas
El problema es que llama a String.valueOf(char[])
y no a String.valueOf(Object)
.
La razón de esto es que Java siempre elegirá la versión más específica de un método sobrecargado que funcione con los parámetros proporcionados. null
es un valor válido para un parámetro Object
, pero también es un valor válido para un parámetro char[]
.
Para hacer que Java use la versión Object
, pase el null
través de una variable o especifique un lanzamiento explícito a Object:
Object o = null;
System.out.println("String.valueOf(null) = " + String.valueOf(o));
// or
System.out.println("String.valueOf(null) = " + String.valueOf((Object) null));
Si miras el javadoc para los métodos String.valueOf()
verás que en realidad establece que si pasas un valor nulo al método lo hará a través de una NullPointerException
. Además, si su IDE lo hará, puede ver el código fuente de esos métodos y verá que hay un código que apunta específicamente a la posibilidad de que la entrada sea nula y arroja una NullPointerException
.
Un error, numerado 4867608 se archivó para este camino en 2003, que se resolvió como "no arreglará" con esta explicación.
No podemos cambiar esto debido a restricciones de compatibilidad. Tenga en cuenta que es el método público static String valueOf (char data []) el que termina siendo invocado y no menciona el reemplazo de "null" por argumentos nulos.
@ ###. ### 2003-05-23