web-dev-qa-db-fra.com

Pourquoi String.valueOf (null) lève-t-il une exception NullPointerException?

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 de obj.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?

117
user282886

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:

JLS 15.12.2.5 Choix de la méthode la plus spécifique

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"

Questions connexes


Morale de l'histoire

Il y en a plusieurs importantes:

  • Effectif Java 2e édition, élément 41: utilisez judicieusement la surcharge
    • Tout simplement parce que vous pouvez surcharger, ne signifie pas que vous devriez à chaque fois
    • Ils peuvent causer de la confusion (surtout si les méthodes font des choses très différentes)
  • En utilisant un bon IDE, vous pouvez vérifier quelle surcharge est sélectionnée au moment de la compilation
    • Avec Eclipse, vous pouvez survoler l’expression ci-dessus avec la souris et voir que en effet, la surcharge valueOf(char[]) est sélectionnée!
  • Parfois, vous souhaitez explicitement lancer null (exemples à suivre)

Voir également


À la coulée 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:

  • Pour sélectionner la surcharge (comme indiqué dans l'exemple ci-dessus)
  • Donner null en tant qu'argument unique à un paramètre vararg

Un 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"

Voir également

Questions connexes

192
polygenelubricants

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));
16
Joachim Sauer

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

5
cbare