Search code examples
javaexceptionrunnablethrow

Jdk failed to compile my code that throws exception inside Runnable


I'm trying to throw exception from within a Runnable object, like this:

  class ExceptionRunnable implements Runnable {
    @Override
    public void run() throws Exception {
      throw new Exception("ExceptionRunnable");
    }
  }

Compilation error: xxx.ExceptionRunnable.run() doesn't implement java.lang.Runnable.run(). The overriden run() doesn't throw java.lang.InterruptedException.

This is really odd, I'm throwing a new Exception in the run function, but compiler said I didn't throw anything. I'm using jdk1.8 on windows.

How to handle this?


Solution

  • When compiling your code:

    class ExceptionRunnable implements Runnable {
        @Override
        public void run() throws Exception {
            throw new Exception("ExceptionRunnable");
        }
    }
    

    The compiler shows the following error:

    java: run() in ExceptionRunnable cannot implement run() in java.lang.Runnable
      overridden method does not throw java.lang.Exception
    

    Why? Because the method you're overriding - Runnable.run() - has this signature (note the absence of a throws clause):

    void run()
    

    To fix the first issue then, change your code from this:

    public void run() throws Exception {
    

    to this, so that the signatures match:

    public void run() {
    

    After making that change, you will uncover the next compiler error:

    java: unreported exception java.lang.Exception; must be caught or declared to be thrown
    

    This is saying that your own code is throwing an Exception which is both not caught and not declared in the throws clause. You've already found that you can't add it to the throws clause though – that's what you initially tried to do. So the other option would be to catch the exception in your run() method, like below:

    @Override
    public void run() {
        try {
            throw new Exception("ExceptionRunnable");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    Another option would be to throw a RuntimeException, like below, but you should only do this with intention, fully understanding what it means to introduce unchecked exceptions into your code.

    @Override
    public void run() {
        throw new RuntimeException("ExceptionRunnable");
    }