283
String x = (String) null;

Why there is no exception in this statement?

String x = null;
System.out.println(x);

It prints null. But .toString() method should throw a null pointer exception.

1
  • what exception are you talking about, compiler ? Commented Sep 10, 2013 at 15:54

10 Answers 10

391

You can cast null to any reference type without getting any exception.

The println method does not throw null pointer because it first checks whether the object is null or not. If null then it simply prints the string "null". Otherwise it will call the toString method of that object.

Adding more details: Internally print methods call String.valueOf(object) method on the input object. And in valueOf method, this check helps to avoid null pointer exception:

return (obj == null) ? "null" : obj.toString();

For rest of your confusion, calling any method on a null object should throw a null pointer exception, if not a special case.

2
  • 1
    @JunedAhsan what special cases would cause it not to throw an NPE?
    – Holloway
    Commented Nov 25, 2014 at 15:50
  • @Trengot Check one mentioned in Peter answer below. Commented Nov 25, 2014 at 23:14
164

You can cast null to any reference type. You can also call methods which handle a null as an argument, e.g. System.out.println(Object) does, but you cannot reference a null value and call a method on it.

BTW There is a tricky situation where it appears you can call static methods on null values.

Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.
4
  • 14
    Wow. If asked, I would be 100% sure that it would throw an exception. A tricky case indeed.
    – Magnilex
    Commented Feb 17, 2015 at 15:53
  • 2
    @Magnilex: Absolutely! this is a typical OCPJP exam trick question.
    – ccpizza
    Commented Mar 17, 2016 at 17:15
  • 3
    Isn't this because compiler in bytecode "optimizes" it to t.yield() -> Thread.yeld() anyway? Similar to how final int i = 1; while (i == 1) is optimized to while(true)
    – SGal
    Commented Feb 1, 2018 at 12:45
  • @SGal It's even better because the second optimization is AFAIK not mandatory while the first one kinda is. Commented Nov 30, 2019 at 12:19
45

This is by design. You can cast null to any reference type. Otherwise you wouldn't be able to assign it to reference variables.

2
  • 1
    thanks! this note regarding to the assigning null to reference variables is really helpful!
    – Max
    Commented Jan 8, 2020 at 5:24
  • Makes sense. Every time null is being assigned to a reference it is being implicitly cast to that type.
    – Vaibhav
    Commented Mar 15 at 16:54
26

Casting null values is required for following construct where a method is overloaded and if null is passed to these overloaded methods then the compiler does not know how to clear up the ambiguity hence we need to typecast null in these cases:

class A {
  public void foo(Long l) {
    // do something with l
  }
  public void foo(String s) {
    // do something with s      
  }
}
new A().foo((String)null);
new A().foo((Long)null);

Otherwise you couldn't call the method you need.

2
  • In most case the casting is implicit, e.g. String bar = null; casts the null value to String. So far I only had to cast null explicitly in a test where a method was overloaded and I wanted to test its behavior with null input. Still, good to know, I was about to write a similar answer before I found yours.
    – Vlasec
    Commented Apr 13, 2016 at 14:47
  • Fun fact: l instanceof Long and s instanceof String will return false in these cases. Commented Mar 22, 2018 at 12:17
8

Println(Object) uses String.valueOf()

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Print(String) does null check.

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}
8

Many answers here already mention

You can cast null to any reference type

and

If the argument is null, then a string equal to "null"

I wondered where that is specified and looked it up the Java Specification:

The null reference can always be assigned or cast to any reference type (§5.2, §5.3, §5.5).

If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).

3

As others have written, you can cast null to everything. Normally, you wouldn't need that, you can write:

String nullString = null;

without putting the cast there.

But there are occasions where such casts make sense:

a) if you want to make sure that a specific method is called, like:

void foo(String bar) {  ... }
void foo(Object bar) {  ... }

then it would make a difference if you type

foo((String) null) vs. foo(null)

b) if you intend to use your IDE to generate code; for example I am typically writing unit tests like:

@Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
    new MyClassUnderTest((Whatever) null);
}

I am doing TDD; this means that the class "MyClassUnderTest" probably doesn't exist yet. By writing down that code, I can then use my IDE to first generate the new class; and to then generate a constructor accepting a "Whatever" argument "out of the box" - the IDE can figure from my test that the constructor should take exactly one argument of type Whatever.

3

This language feature is convenient in this situation.

public String getName() {
  return (String) memberHashMap.get("Name");
}

If memberHashMap.get("Name") returns null, you'd still want the method above to return null without throwing an exception. No matter what the class is, null is null.

2

Print:

Print an object. The string produced by the String.valueOf(Object) method is translated into bytes

ValueOf:

if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.

It wil simply return a string with value "null" when the object is null.

2

This is very handy when using a method that would otherwise be ambiguous. For example: JDialog has constructors with the following signatures:

JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)

I need to use this constructor, because I want to set the GraphicsConfiguration, but I have no parent for this dialog, so the first argument should be null. Using

JDialog(null, String, boolean, Graphicsconfiguration) 

is ambiguous, so in this case I can narrow the call by casting null to one of the supported types:

JDialog((Frame) null, String, boolean, GraphicsConfiguration)
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.