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