4

I have a hard time to understand why the following code compiles, while it is not a subclass of exception:

class Test 
{
    public void run() throws IOException 
    {
        System.out.println("Test");
    }
}

class SubTest extends Test 
{
    //not a subclass of IOException, still compiles 
    public void run() throws RuntimeException 
    {
        System.out.println("Test from sub");
    }
}

class Sub2Test extends Test 
{
    //not a subclass of IOException, does not compile
    public void run() throws Exception  
    {
        System.out.println("Test from sub");
    }
}

I understand RuntimeException is an unchecked exception, but I thought the rule was that it must be a subclass of the parent exception?

xingbin
  • 27,410
  • 9
  • 53
  • 103
Douma
  • 2,682
  • 14
  • 23

2 Answers2

8

Imagine there is a caller which calls Test#run. In the declaration of Test#run, it says it might throw IOException, so the caller knows it can catch and handle it:

Test test = // it could be instance of SubTest of Sub2Test
try {
   test.run();
} catch (IOException e) {

}

Then it's ok if SubTest does not throw IOException, the caller will not miss anything.

But if you throw some checked Exception like Sub2Test, since the caller does not know it until runtime, the called is not able to catch and handle it. So it should not be compiled.

xingbin
  • 27,410
  • 9
  • 53
  • 103
3

"I understand RuntimeException is an unchecked exception, but I thought the rule was that it must be a subclass of the parent exception?"

That is the general rule, as specified in the JLS in section §11.2. Compile-Time Checking of Exceptions, which states (emphasis mine)

The throws clause of an overriding method may not specify that this method will result in throwing any checked exception which the overridden method is not permitted, by its throws clause, to throw (§8.4.8.3).

But that only applies to checked exceptions, and it also explicitly states that

The unchecked exception classes (§11.1.1) are exempted from compile-time checking.

So the compiler is going to ignore the fact that RuntimeException isn't a subclass of IOException.

azurefrog
  • 10,785
  • 7
  • 42
  • 56