Null is throwable

Today I found a cute code snippet on Alex‘s Blog and Euxx:

1public class Weird {
2
3    public static void main(String[] args) {  
4         throw null;
5    }  
6
7}

It compiles and trows a NullPointerException:

Exception in thread "main" java.lang.NullPointerException
	at Weird.main(Weird.java:4)

I think that it is strange that this stuff compiles: the compiler could easily catch this as usual static type checking (so, if you want to throw a null reference you should be forced to explicitly cast it to java.lang.Throwable). Normally, throwing a non throwable object is not allowed like in following case:

1public class Weird {
2
3    public static void main(String[] args) {  
4         throw new Object();
5    }  
6
7}  

Compilation output:

Weird.java:4: incompatible types
found   : java.lang.Object
required: java.lang.Throwable
         throw new Object();
               ^
1 error

As Eugeene correctly points:

The JLS specification states that “The null reference can always be cast to any reference type”, but then in above example compiler does not require main method to throw throwable.

You can throw an instance of Throwable that could have been created before, and that a certain point could be null. Like in this case (uncommenting line 5):

1public class Weird {
2
3    public static void main(String[] args) throws Throwable {           
4         Throwable x = new Throwable();
5         // x = null;
6         throw x;
7    }  
8
9} 

But here you have to specify that main throws Throwable in the method signature, as expected. One could justify that, because as null can be casted to Throwable, it could also be casted to RuntimeException, so that you don’t need to declare that the main throws something. But the reality is that no Throwable, nor RuntimeException nor just any Exception is thrown: null is thrown “as is”, and that doesn’t need to be declared in the method signature. Casting null to Throwable before throwing gives a compile time error:

1public class Weird {
2
3    public static void main(String[] args) {  
4         throw (Throwable)null;
5    }  
6
7} 
Weird.java:4: unreported exception java.lang.Throwable; must be caught or declared to be thrown
         throw (Throwable)null;
         ^
1 error

So… null can be thrown as is, and does not require to be declared in the signature. The compiler doesn’t complain. But why is producing NullPointerException?

I think that the JVM tries to use the null reference as any other Throwable object when it is thrown. So the JVM fills the stacktrace on the thrown reference, that being null produces a NullPointerException. Something like this:

1public class Weird {  
2
3    public static void main(String[] args) {  
4         ((Throwable)null).fillInStackTrace();
5    }  
6
7}  

The output is the same as the fist code snippet: NullPointerException at line 4. This is what I suppose happens at runtime in the JVM. Assuming that, I suppose that throwing null is more expensive than throwing a new NullPointerException.

Personally I think that the compiler should prevent the “throw null” to compile, as this has no sense: never useful, always harmful.
The compile time Exception checking already force programmer to declare checked exception on the method signature (for the JVM there are no differences between checked or unchecked exception); when possible the compiler should prevent programming errors, and I think this is the case.
AFAIK, nothing in the JLS says that null can be thrown, even if null can be casted to any reference type.


2 Responses to “Null is throwable”  

  1. 1 Alex Miller

    You should check the responses on my blog – this is covered by the JLS. Has nothing to do with casting but rather how the expression being thrown is evaluated.

  2. 2 Luigi

    Saw that, interesting discussion. Thanks for sharing that code.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>



Calendar

June 2008
M T W T F S S
« May   Jul »
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Follow me

twitter flickr LinkedIn feed

Subscribe by email

Enter your email address:

Archives


Categories

Tag Cloud


Listening