biggerScala biggerScala - 2 months ago 7
Java Question

Why do neither of the following code snippets generate a NullPointerException?

public class Main {

public static void main(String[] args) {

C c = null;

System.out.println(c); //obviously not null, no npe, prints as null

c.d();

}
}


class C{

static String z;

static { z = "elvistic"; }

static void d(){

System.out.println("I am "+z);
}
}


Some code gave me cause to puzzle, came across by accident when coding. I have coded a simple example above, with a static block just to demonstrate the class/object runs.

At runtime, obviously, if
d
were an instance method, we would receive a
NullPointerException
, but why does this work given that the object reference is "kind of" null even on a static method?

Also, why don't we get a
NullPointerException
on the
println
call?

Given that static methods are stored in PermGen is there still heap allocation without the 'new' operator here?

I am aware we simply could do a
C.d()
- in the latter case the first question becomes immaterial (nullity) but I'd still like to know where the static object is stored.

Thanks!

Answer

In Java, the syntax

obj.staticMethod()

where obj is some object reference and staticMethod is a static method inside the class is completely identical to

TheTypeOfObj.staticMethod()

and therefore won't trigger a NullPointerException in the case where the object reference is null.

As to your question about why the println doesn't trigger a NullPointerException, the println function is specifically designed so that trying to print a null object reference just outputs null rather than triggering a NullPointerException by invoking toString() on a null reference. I assume this decision was made to simplify debugging (it's nice to see that your object was null when you logged it!). If you'd like an official reference on that, note that the documentation for PrintStream#println(Object) says

This method calls at first String.valueOf(x) to get the printed object's string value

and the documentation for that method says that

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