Throwing Null

Andy Balaam – November 25, 2018

At OpenMarket we care a lot about getting our code right, and we like to know our tools and this subject has had us all involved in lively debate.

So, what do you think the following Java program prints out?

class ThrowNull {
  class A extends RuntimeException {}

  public static void main(String[] args) {
    try {
      throw (A)null;
    }
    catch (A a) {
      System.out.println("a");
    }
    catch (Exception e) {
      System.out.println("e");
    }
    catch (Throwable t) {
      System.out.println("t");
    }
  }
}

It’s throwing something of type A, right?

But does Java remember the type at runtime when it checks the type of the thing being thrown?

OK, I’m going to give you enough time to guess.  Choose your option:

  1. “b”
  2. “e”
  3. “t”
  4. Something else

Chosen?

The answer is 2 – the program prints “e”.

Why?

It took a bit of investigation and I followed some blind alleys before we figured it out: I initially decided Java used the type information at compile time (because if we just throw null with no mention of A, the compiler refuses to allow us a catch clause for A) but then threw it away at runtime, and somehow considered null to be an instance of Exception, but not of A.

My colleague Pete sits next to me here at OpenMarket, and one thing about Pete you can count on, is that if there’s a discussion like this going on, he is definitely going to turn in his chair and give me a teacherly look, then immediately get drawn into it and figure out the right answer.

Within 2.6 seconds of me musing about this problem, Pete was on the case hacking my example program until the answer was clear.

Actually, it’s simpler than it first looks.  Pete’s new program might help explain:

public class ExceptionNull {
  class DumbException extends RuntimeException {}

  public static void main(String[] args) {
    try {
      DumbException dumbo = null;
      throw dumbo;
    } 
    catch (DumbException dumb) {
      dumb.printStackTrace();
    } 
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

When you throw null, at runtime, Java stops you, and throws a NullPointerException instead, and this is what is caught in the catch (Exception e) block.

Whether or not this is helpful behaviour is open to question.

Some might say if we allow types that could never be null we might be prevented from writing such horrible programs, but what would be the fun in that?

What do you think?  Should Java do something different, or is this the best way to handle the situation?

What does this Java program print?
1) “a”
2) “e”
3) “t”
4) Something else pic.twitter.com/mivyrJEQEq

— Andy Balaam (@andybalaam) July 25, 2018

See all tech blog posts

Related Content