The issue is that String.valueOf method is overloaded:
Java Specification Language mandates that in these kind of cases, the most specific overload is chosen:
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-an Object, but not all Object is-a char[]. Therefore, char[] is more specific than Object, and as specified by the Java language, the String.valueOf(char[]) overload is chosen in this case.
String.valueOf(char[]) expects the array to be non-null, and since null is given in this case, it then throws NullPointerException.
The easy "fix" is to cast the null explicitly to Object as follows:
System.out.println(String.valueOf((Object) null));
// prints "null"
Related questions
Moral of the story
There are several important ones:
- Effective Java 2nd Edition, Item 41: Use overloading judiciously
- Just because you can overload, doesn't mean you should every time
- They can cause confusion (especially if the methods do wildly different things)
- Using good IDE, you can check which overload is selected at compile time
- With Eclipse, you can mouse-hover on the above expression and see that indeed, the
valueOf(char[]) overload is selected!
- Sometimes you want to explicitly cast
null (examples to follow)
See also
On casting null
There are at least two situations where explicitly casting null to a specific reference type is necessary:
- To select overloading (as given in above example)
- To give
null as a single argument to a vararg parameter
A simple example of the latter is the following:
static void vararg(Object... os) {
System.out.println(os.length);
}
Then, we can have the following:
vararg(null, null, null); // prints "3"
vararg(null, null); // prints "2"
vararg(null); // throws NullPointerException!
vararg((Object) null); // prints "1"
See also
Related questions