RSS Feed for This PostCurrent Article

Java Checked Exception and RuntimeException - throw Exception from static block ?

Recently I was asked how to catch an exception in a static block and throw it to the calling class. E.g. see the class below

public class MyException extends Exception{
}

public class Sample {

static {
try {
method1();
} catch (InterruptedException e) {
throw new MyException();
}
}

protected static void method1() throws InterruptedException {
Thread.sleep(1000);
}
}

You will get a compilation error saying that MyException is not handled.

To fully understand this, you must know Java checked exceptions and run time exceptions.

Java provides two main exception types: runtime exceptions and checked exceptions. All checked exceptions extend from java.lang.Exception, while runtime exceptions extend from either java.lang.RuntimeException or java.lang.Error.

For run time exceptions

  • method signature does not need to declare runtime exceptions
  • caller to a method that throws a runtime exception is not forced to catch the runtime exception
  • Runtime exceptions extend from RuntimeException or Error

For checked exceptions:

  • method must declare each checked exception it throws
  • caller to a method that throws a checked exception must either catch the exception or throw the exception itself
  • Checked exceptions extend from Exception

Checked exceptions indicate an exceptional condition from which a caller can conceivably recover. Runtime exceptions indicate a programmatic error from which a caller cannot normally recover.

Checked exceptions force you to catch the exception and to do something about it. You should always catch a checked exception once you reach a point where your code can make a meaningful attempt at recovery. However, it is best not to catch runtime exceptions. Instead, you should allow runtime exceptions to bubble up to where you can see them.

In order to throw exeption from static block, you have to change MyException to inherit from RuntimeException. In my opinion, this is still not a elegant way.

public class MyException extends RuntimeException {
}

public class Sample {

static {
try {
method1();
} catch (InterruptedException e) {
throw new MyException();
}
}

protected static void method1() throws InterruptedException {
Thread.sleep(1000);
}
}


Trackback URL


RSS Feed for This Post3 Comment(s)

  1. Niklas Mehner | Oct 12, 2007 | Reply

    Throwing an exception in a static initializer is a very bad idea. Given the class:

    public class StaticClass {
    static {
    Object o = null;
    o.toString();
    }
    public static void someMethod() {}
    }

    and using it in the following way:
    try {
    StaticClass.someMethod();
    } catch (Throwable t) {
    t.printStackTrace();
    }
    try {
    StaticClass.someMethod();
    } catch (Throwable t) {
    t.printStackTrace();
    }

    you get an ExceptionInInitializerError when invoking it for the first time(caused by a NullPointerException). So you get the information you need to fix the problem.

    But on the second invocation you get a java.lang.NoClassDefFoundError: StaticClass. And this does not help you at all.

    So if you happen to miss the first exception (which might happen if you have a lot of logging) you will have a big problem finding out, what actually went wrong.

    So imho static initializers should be avoided as much as possible.

    If you change the StaticClass to:

    public class StaticClass {
    private StaticClass instance;

    public StaticClass() {
    Object o = null;
    o.toString();
    }
    public void someMethod() {}

    public synchronized StaticClass getInstance() {
    if (instance == null) {
    instance = new StaticClass()
    }
    return instance;
    }
    }

    You avoid that problem. Also the code will recover if the failure is a temporary one (”file not found” or something like that). In the first version you have to restart the VM to fix the problem.

  2. admin | Oct 12, 2007 | Reply

    Yes. I agreed. Throwing exception in static block is not a good idea :)

  3. prashant | Oct 12, 2007 | Reply

    Hi,

    Good little tiny post.

RSS Feed for This PostPost a Comment