3

A few of my methods in Java throw exceptions such as NoSuchElementException, IllegalArgumentException, etc. But when using these methods, these exceptions appear to be unchecked. In other words, caller of my methods is not required to do a try/catch on my methods that throw those exceptions. I read around it seems that Exceptions by default are "checked" and only Errors are the ones "unchecked". But somehow, the exceptions I throw are also unchecked. It is weird.

How can I ensure that when my method throws an exception, the caller MUST catch the exception at compile time? Simply said, how can I throw a checked exception?

Thanks!

Carven
  • 14,988
  • 29
  • 118
  • 161

6 Answers6

7

Only RuntimeException and its subclasses are unchecked. (Well, Error and its subclasses are as well, but you shouldn't be messing with Errors.) All you need to do to throw a checked exception is ensure that it doesn't extend RuntimeException.

cHao
  • 84,970
  • 20
  • 145
  • 172
4

See this hack, it might help (hope it's not OT).

public class Test {

    // No throws clause here
    public static void main(String[] args) {
        doThrow(new SQLException());
    }

    static void doThrow(Exception e) {
        Test.<RuntimeException> doThrow0(e);
    }

    @SuppressWarnings("unchecked")
    static <E extends Exception> void doThrow0(Exception e) throws E {
        throw (E) e;
    }
}
pevik
  • 4,523
  • 3
  • 33
  • 44
3

Whether an exception is checked or not checked is NOT how you throw it or declare it, it is only dependent on whether the exception you choose is derived from RuntimeException or not. The ones you list above, all are derived from RuntimeException and so clients of your method do not need to catch them.

MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66
3

All sub-classes of Throwable are checked except sub-classes of Error and RuntimeException. (You can sub-class Throwable directly)

The compiler checks these Exception, however they have no special place at runtime. i.e. you can throw a checked Exception without the compiler knowing and it will behave normally.

e.g.

public static void throwChecked(Throwable t) /* no throws clause */ {
    Thread.currentThread().stop(t);
}

public static void main(String... args) /* no throws clause */ {
    throwChecked(new Throwable());
}

This compiles and prints the Throwable as you might expect.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • This method is deprecated more than ten years ago and will be removed in future releases. Shouldn't ever be used. https://docs.oracle.com/javase/9/docs/api/java/lang/Thread.html#stop-java.lang.Throwable- – Miha_x64 Oct 22 '17 at 09:07
  • @Miha_x64 its been disabled in Java 8. There are other ways of doing the same thing and this answer should be updated. – Peter Lawrey Oct 22 '17 at 10:41
1

I think you should take a step back and learn the theory behind why to throw a checked exception vs an unchecked exception. The Java tutorial on exceptions is a good resource.

From the page entitled Unchecked Exceptions — The Controversy:

Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way.

Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26
0

Exceptions that extends RuntimeException do not have to be declared.

You can declare the method: throws Exception or even throws Throwable and that will have to be handled (though it is not advised).

pevik
  • 4,523
  • 3
  • 33
  • 44
amit
  • 175,853
  • 27
  • 231
  • 333