The first invocation will call the String.valueOf(Object)
method, as you have explicitly typecasted null
to Object
reference. Conversely, the second one will invoke the overloaded String.valueOf(char[])
method, as char[]
is more specific than Object
for a null
argument.
There are other overloaded versions of this method that accept primitive parameters, but those are not a valid match for a null
argument.
From JLS §15.12.2:
There may be more than one such method, in which case the most
specific one is chosen. The descriptor (signature plus return type) of
the most specific method is one used at run time to perform the method
dispatch.
A method is applicable if it is either applicable by subtyping
(§15.12.2.2), applicable by method invocation conversion (§15.12.2.3),
or it is an applicable variable arity method (§15.12.2.4).
[...]
If several applicable methods have been identified during one of the
three phases of applicability testing, then the most specific one is
chosen, as specified in section §15.12.2.5.
Now check the source code of both the methods:
// This won't throw NPE for `obj == null`
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
// This will throw `NPE` for `data == null`
public static String valueOf(char data[]) {
return new String(data);
}