What is the difference between "(Object)null" and "null" in Java?

JavaNullNullpointerexception

Java Problem Overview


Take a look at the following example:

class nul
{
  public static void main (String[] args)
  {
    System.out.println (String.valueOf((Object)null));
    System.out.println (String.valueOf(null));
  }
}

The first println writes null but the second throws a NullPointerException.

Why is only the second line worth an exception? And what is the difference between the two nulls? Is there a real null and a fake null in Java?

Java Solutions


Solution 1 - Java

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);
}

Solution 2 - Java

There are lots of overloaded String.valueOf methods in Java. Further, in Java null has any and all types so that anything (that isn't a primitive) can be null.

So, when you call (String.valueOf((Object)null) you call the valueOf method that takes an Object as use explicitly cast null to Object.

In the second example you don't explicitly cast the null to any particular type so in fact you call the valueOf method with a char[] which throws an NPE.

From the JLS §15.12.2

> The second step searches the type determined in the previous step for > member methods. This step uses the name of the method and the types of > the argument expressions to locate methods that are both accessible > and applicable, that is, declarations that can be correctly invoked on > the given arguments. > > 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.

In this case char[] is more specific than Object so it is called when no explicit cast of null is made.

Solution 3 - Java

Although I accepted already an answer I would like to add the exact answer to the question, because the two answers concentrate on explaining the trap I walked into.

The difference between (Object)null and null is that the type of the first is forced to Object but the type of the second is not, as one could think, forced to Object. Instead it could also be an array instead of an object.

So the conclusion is: pass (Object)null instead of null as an argument to a method to be sure to get exactly the method working on objects instead of any other method working on arrays.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncevingView Question on Stackoverflow
Solution 1 - JavaRohit JainView Answer on Stackoverflow
Solution 2 - JavaBoris the SpiderView Answer on Stackoverflow
Solution 3 - JavacevingView Answer on Stackoverflow