selon la documentation, la méthode String.valueOf(Object obj)
renvoie:
si l'argument est
null
, alors une chaîne égale à"null"
; sinon, la valeur deobj.toString()
est renvoyée.
Mais comment se fait-il que j'essaye de faire ceci:
System.out.println("String.valueOf(null) = " + String.valueOf(null));
il jette NPE à la place? (essayez vous-même si vous ne croyez pas!)
Exception dans le fil "principal" Java.lang.NullPointerException Sur Java.lang.String. (Source inconnue) Sur Java.lang.String.valueOf (Source inconnue)
Comment cela se fait-il? Est-ce que la documentation me ment? Est-ce un bug majeur en Java?
Le problème est que la méthode String.valueOf
Est surchargée:
Le langage de spécification Java stipule que, dans ce type de cas, la surcharge la plus spécifique est choisie:
Si plusieurs méthodes membres sont à la fois accessibles et applicables à une invocation de méthode, vous devez en choisir une pour fournir le descripteur de la répartition de la méthode d'exécution. Le langage de programmation Java utilise la règle selon laquelle la méthode la plus spécifique est choisie.
Un char[]
is-anObject
, mais pas tous Object
is-achar[]
. Par conséquent, char[]
Est plus spécifique que Object
, et comme spécifié par le langage Java, la fonction String.valueOf(char[])
surcharge est choisi dans ce cas.
String.valueOf(char[])
s'attend à ce que le tableau ne soit pas_null
, et puisque null
est donné dans ce cas, il jette alors NullPointerException
.
Le "correct" facile consiste à convertir explicitement le null
en Object
comme suit:
System.out.println(String.valueOf((Object) null));
// prints "null"
Il y en a plusieurs importantes:
valueOf(char[])
est sélectionnée!null
(exemples à suivre)null
Il existe au moins deux situations dans lesquelles il est nécessaire de convertir explicitement null
vers un type de référence spécifique:
null
en tant qu'argument unique à un paramètre varargUn exemple simple de ce dernier est le suivant:
static void vararg(Object... os) {
System.out.println(os.length);
}
Ensuite, nous pouvons avoir les éléments suivants:
vararg(null, null, null); // prints "3"
vararg(null, null); // prints "2"
vararg(null); // throws NullPointerException!
vararg((Object) null); // prints "1"
Le problème est que vous appelez String.valueOf(char[])
et pas String.valueOf(Object)
.
La raison en est que Java choisira toujours la version la plus spécifique d'une méthode surchargée qui fonctionne avec les paramètres fournis. null
est une valeur valide pour un Object
paramètre, mais c’est aussi une valeur valide pour un char[]
paramètre.
Pour créer Java, utilisez la version Object
, transmettez-y null
via une variable ou spécifiez une conversion explicite en objet:
Object o = null;
System.out.println("String.valueOf(null) = " + String.valueOf(o));
// or
System.out.println("String.valueOf(null) = " + String.valueOf((Object) null));
Un bug, numéroté 4867608 a été archivé pour cette méthode en 2003, qui a été résolu comme "ne résoudra pas" avec cette explication.
Nous ne pouvons pas changer cela en raison de contraintes de compatibilité. Notez que c'est la méthode statique publique String valueOf (char data []) qui est invoquée et qu'elle ne mentionne pas le remplacement de "null" par des arguments null.
@ ###. ### 2003-05-23