277
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.

anubhava
  • 761,203
  • 64
  • 569
  • 643
Vicky
  • 3,230
  • 3
  • 18
  • 21

10 Answers10

381

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.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
162

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.
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 14
    Wow. If asked, I would be 100% sure that it would throw an exception. A tricky case indeed. – Magnilex Feb 17 '15 at 15:53
  • 2
    @Magnilex: Absolutely! this is a typical OCPJP exam trick question. – ccpizza Mar 17 '16 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 Feb 01 '18 at 12:45
  • @SGal It's even better because the second optimization is AFAIK not mandatory while the first one kinda is. – Paul Stelian Nov 30 '19 at 12:19
44

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

André Stannek
  • 7,773
  • 31
  • 52
  • 1
    thanks! this note regarding to the assigning null to reference variables is really helpful! – Max Jan 08 '20 at 05:24
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.

David Budworth
  • 11,248
  • 1
  • 36
  • 45
Mewel
  • 1,279
  • 15
  • 21
  • 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 Apr 13 '16 at 14:47
  • Fun fact: `l instanceof Long` and `s instanceof String` will return `false` in these cases. – Attila Tanyi Mar 22 '18 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);
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
rocketboy
  • 9,573
  • 2
  • 34
  • 36
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).

Arigion
  • 3,267
  • 31
  • 41
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.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
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.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
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)
Marten Jacobs
  • 199
  • 1
  • 9