The issue is that String.valueOf method is overloaded:
String.valueOf(Object)String.valueOf(char[])
Java Specification Language mandates that in these kind of cases, the most specific overload is chosen:
JLS 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-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
- How does polymorph ambiguity distinction work?
- Which overload will get selected for null in Java?
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!
- With Eclipse, you can mouse-hover on the above expression and see that indeed, the
- Sometimes you want to explicitly cast
null(examples to follow)
See also
- Polymorphism vs Overriding vs Overloading
- Method Overloading. Can you overuse it?
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
nullas 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
- Java Language Guide/varargs - to understand how it's implemented
Related questions
- Why null cast?
- Difference between double… and double[] in formal parameter type declaration
The issue is that String.valueOf method is overloaded:
String.valueOf(Object)String.valueOf(char[])
Java Specification Language mandates that in these kind of cases, the most specific overload is chosen:
JLS 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-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
- How does polymorph ambiguity distinction work?
- Which overload will get selected for null in Java?
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!
- With Eclipse, you can mouse-hover on the above expression and see that indeed, the
- Sometimes you want to explicitly cast
null(examples to follow)
See also
- Polymorphism vs Overriding vs Overloading
- Method Overloading. Can you overuse it?
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
nullas 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
- Java Language Guide/varargs - to understand how it's implemented
Related questions
- Why null cast?
- Difference between double… and double[] in formal parameter type declaration
The problem is that you're calling String.valueOf(char[]) and not String.valueOf(Object).
The reason for this is that Java will always choose the most specific version of an overloaded method that works with the provided parameters. null is a valid value for an Object parameter, but it's also a valid value for a char[] parameter.
To make Java use the Object version, either pass in null via a variable or specify an explicit cast to Object:
Object o = null;
System.out.println("String.valueOf(null) = " + String.valueOf(o));
// or
System.out.println("String.valueOf(null) = " + String.valueOf((Object) null));
apex - Why does valueOf not work with NULLs sometimes? - Salesforce Stack Exchange
Why "null" String is returned in String.valueOf instead of java null? - Stack Overflow
Java String.valueOf(null) throws NPE, but Object a = null; String.valueOf(a) returns 'null' - Stack Overflow
java - Why String.valueOf(null) is causing null pointer exception? - Stack Overflow
You are looking for Objects#toString(java.lang.Object,java.lang.String)
The call
Objects.toString(obj, null)
returns null when object is null.
Because String.valueOf() returns a String representation, which for a null is "null".
The developer shouldn't be checking the return value at all, since it's meant for display purposes, not for checking whether a reference was null or not.
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 asvalueOf(Object)andvalueOf(char[])then a call to the untypedString.valueOf(null)would be ambiguous
The first invocation is to String#valueOf(Object), the second is to String#valueOf(char[])
The overloaded method is chosen according to the argument's static type, this is why the first works and the seconds get an NPE.
If you invoke System.out.println ( String.valueOf((Object)null)); it will work
boolean creatok = users.create (Objects.toString(name, ""), Objects.toString(desc, ""));
I think you should use conditions, if you want to avoid 'if' clauses, use a ternary operator
boolean creatok = users.create(name == null? "" : String.valueOf(name), name == null? "" : String.valueOf(name));