throw null

14

This compiles (and throws NPE):

public class Weird {
public static void main(String[] args) {
throw null;
}
}

Anyone know why?

Comments

14 Responses to “throw null”
  1. Anonymous says:

    I hope the question isn’t “why does it throw NPE” because I know the answer to that :-)

    This caught me off guard since there are a lot of good things enforced by the compiler/JLS (like unreachable code, uninitialized variables, etc). At least it is smart enough to reject the literal code “null.toString()” . I write that all the time :-)

  2. David Rupp says:

    From the Java Language Specification, 3rd ed (http://java.sun.com/docs/books/jls/download/langspec-3.0.pdf):

    “A throw statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the throw completes abruptly for that reason. If evaluation of the Expression completes normally, producing a non- null value V, then the throw statement completes abruptly, the reason being a throw with value V. If evaluation of the Expression completes normally, producing a null value, then an instance V’ of class NullPointerException is created and thrown instead of null. The throw statement then completes abruptly, the reason being a throw with value V’.”

  3. bruce says:

    JLS 14.18 – my emphasis

    “A throw statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the throw completes abruptly for that reason. If evaluation of the Expression completes normally, producing a non-null value V, then the throw statement completes abruptly, the reason being a throw with value V. If evaluation of the Expression completes normally, producing a null value, then an instance V’ of class NullPointerException is created and thrown instead of null. The throw statement then completes abruptly, the reason being a throw with value V’.”

  4. Bob Lee says:

    I’ve always thought this was a nice alternative to “throw new NullPointerException()” but unfortunately the obscurity outweighs the benefits.

  5. Weiqi Gao says:

    This doesn’t compile with JDK 1.4. I ran across this last year:

    http://www.weiqigao.com/blog/2007/04/20/brian_coyner_throwing_null.html

    Unfortunately, the Brian Coyner post I referenced is no longer online.

  6. Bob, why would you want to throw NPE yourself? I would understand IllegalArgumentException, but NPE…

  7. Alex says:

    Thanks smart people! You each get a gold star.

  8. Bob Lee says:

    @Eugene: I throw NPE all the time. That’s the convention used in the JDK as well.

  9. In my opinion the NullpointerException could be thrown when the JVM tries to call methods on the null reference, as it was a real Throwable instance. Possibly at the fillInStackTrace() method.

    This produces the same output (and explains what I think happens):

    public class Weird {

    public static void main(String[] args) {
    ((Throwable)null).fillInStackTrace();
    }

    }

  10. contrapunctus says:

    it compiles because null can simply cast into System.Exception:)

  11. @Eugene: You manually throw an NPE so that the NPE happends in the right place. Lets say I have a constructor with 1 parameter, “String foo”, and part of the contract is that foo isn’t null. But in the constructor, I just store foo, I don’t do anything with it – but in almost any other method, I dereference foo.

    I could just write ‘this.foo = foo’ in my constructor and be safe in the knowledge that almost any further usage of my object will result in NPEs automatically, but this is bad coding. The ‘bug’ is setting foo to null in the first place, THATS where your debugging efforts should start (when I call new Doohickey(bar), where bar is null, that’s the bug, not when I later call doohickey.xyzzy() – the NPE stack trace of that event is useless).

  12. Eric Burke says:

    The comments are funny…arguing about whether to throw NPE or IAE is silly, because *both* are acceptable. The fact is, the documentation for these exceptions leaves much open to interpretation. It is perfectly valid to argue that a null parameter is an illegal argument, and that completely agrees with the JavaDoc comments for IAE. You can also find examples and documentation that suggest NPE is appropriate. This is a classic code style argument all over again. Trust me folks, the most important thing is to fail fast, it really doesn’t matter if you choose IAE or NPE. Either way, your program will abort and which of these two exceptions you choose won’t make it any harder to diagnose the problem.

  13. Neal Gafter says:

    Although null is assignable to every reference type, the type of null is not itself a reference type. It was our intent that the requirement that the expression in a throw statement be a reference type was to be removed from the third edition of the JLS, but that change never actually made it into the published version. Thus, this is a javac compiler bug which I introduced in SE 5.