36 votes

Java String.valueOf (null) renvoie NPE, mais Object a = null; String.valueOf (a) renvoie 'null'

Existe-t-il une explication de type de conception de langage logique pour le comportement suivant (Java 7 et les éditions antérieures, je le soupçonne également):

     Object  a = null;
    String as = String.valueOf(a);              // as is assigned "null"
    System.out.println(as+":"+as.length());     // prints: "null:4"
    System.out.println ( String.valueOf(null)); // NPE
 

42voto

Tom Points 7654

Dans l'énoncé System.out.println(String.valueOf(null)); il y a un appel de méthode public static String valueOf(char data[]), dont le code source est comme suit:

public static String valueOf(char data[]) {
  return new String(data);
}

C'est pourquoi vous obtenez NPE

D'autre part, dans l'énoncé Object a = null; String as = String.valueOf(a); il y a un appel de méthode public static String valueOf(Object obj), dont le code source est comme suit:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

C'est pourquoi vous obtenez la valeur"null" à la place de NPE


Un peu de théorie à partir de Java Language Specification: 15.12.2.5 le Choix de la Méthode Spécifique

Si plus d'un membre de la méthode est à la fois accessible et applicable à un appel de méthode, il est nécessaire de choisir une afin de fournir le descripteur de la méthode d'exécution de l'expédition. Le langage de programmation Java utilise la règle la plus spécifique de la méthode choisie.

Un char[] est de type Object, mais pas tous, Object sont de type char[]. Type char[] est plus spécifique de l'Objet et comme décrit dans le Langage Java cahier des charges, l' String.valueOf(char[]) de surcharge est choisi dans ce cas.

MODIFIER

Il est également intéressant de mentionner que Ian Roberts mentionné (dans son commentaire ci-dessous):

Il est important de noter que c'est une erreur de compilation si il n'est pas seul la surcharge est plus spécifique que tous les autres, si il y avait un valueOf(String) méthode de ainsi que valueOf(Object)et valueOf(char[]) puis un appel à la non typée String.valueOf(null) d'être ambigu

15voto

Aviram Segal Points 6055

La première invocation est à String#valueOf(Object) , la seconde à String#valueOf(char[])

La méthode surchargée est choisie en fonction du type statique de l'argument, c'est pourquoi la première fonctionne et les secondes obtiennent un NPE.

Si vous appelez System.out.println ( String.valueOf((Object)null)); cela fonctionnera

7voto

Buhake Sindi Points 38654

C'est à cause de ce code en String classe:

public static String valueOf(char data[]) {
return new String(data);
}

Votre code (qui jette NullPointerException) des appels mentionnés ci-méthode et, par conséquent, l' data champ est - null. En fait, cet appel est lancé par l' String classe sur le constructeur.

À l'aide du JDK 6, l'exception est comme suit:

java.lang.NullPointerException
    at java.lang.String.<init>(String.java:177)
    at java.lang.String.valueOf(String.java:2840)
    at org.bfs.data.SQLTexter.main(SQLTexter.java:364)

Comme pour votre ligne:

System.out.println(as+":"+as.length());     // prints: "null:4"

Cela fonctionne comme la méthode ci-dessous est appelé:

public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

De toute évidence, a est de type Object si l' String.valueOf(Object) méthode est appelée.

Si vous souhaitez appeler String.valueOf(Object obj) méthode, transtypage de votre null comme suit:

System.out.println (String.valueOf((Object)null));

Vous êtes en train de vivre la surcharge de méthode (où il y a plusieurs méthode avec le même nom et la signature de la méthode, mais ont différents paramètres de la méthode). Dans votre cas (où les NPE se produit), la JVM détermine la méthode à appeler pour les plus spécifiques de type statique. Si le type est déclaré, puis le plus spécifique de la méthode est la méthode avec le même type de paramètre de la variable déclarée, d'autre, un plus spécifique de la méthode de la règle est utilisée par la JVM pour trouver la méthode à appeler.

J'espère que cette aide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X