In statement System.out.println(String.valueOf(null));
there is a call of method public static String valueOf(char data[])
, which source code is as follows:
public static String valueOf(char data[]) {
return new String(data);
}
That is why you get NPE
On the other hand, in statement Object a = null; String as = String.valueOf(a);
there is a calls of method public static String valueOf(Object obj)
, which source code is as follows:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
That is why you get "null" instead of NPE
A bit of theory from Java Language Specification: 15.12.2.5 Choosing the Most Specific Method
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
A char[]
is of type Object
, but not all Object
are of type char[]
. Type char[]
is more specific than Object and as described in the Java Language Specification, the String.valueOf(char[])
overload is chosen in this case.
EDIT
It is also worth mentioning what Ian Roberts mentioned (in his comment below):
It's important to note that it's a compile error if there is no single
overloading that is more specific than all the others - if there were
a valueOf(String)
method as well as valueOf(Object)
and
valueOf(char[])
then a call to the untyped String.valueOf(null)
would be ambiguous