5

I did notice a weird behaviour about the static and non-static inner exception classes.

For example the below code will not compile:

public class MyClass<T> {
  private class MyInnerException extends Exception { // won't compile    
    ..
  }
}

But the below code will compile:

public class MyClass<T> {
  private static class MyInnerException extends Exception { // will compile    
    ..
  }
}

Why is this behaving this way?

One thing is for sure that we cannot have Generic exceptions due to type erasure but then the above is not a Generic exception class but it is inside the Generic class. But if it is static it is allowed but if it is non-static it is not allowed?

Follow up question, is generic exception not allowed just because of the type erasure feature of Generic like it mentioned here: https://www.mscharhag.com/java/java-exceptions-and-generic-types Or there is some other reason to it?

Deepak Kumar
  • 843
  • 1
  • 7
  • 19

1 Answers1

2

One thing is for sure that we cannot have Generic exceptions due to type erasure but then the above is not a Generic exception class but it is inside the Generic class.

Your inner class (the first snippet) is a generic class, since its enclosing class is a generic class, and the enclosing class is part of the inner class. You cannot create an instance of an inner class without a corresponding instance of the enclosing class.

As to why generic classes cannot extend Exception:

It is a compile-time error if a generic class is a direct or indirect subclass of Throwable (ยง11.1.1).

This restriction is needed since the catch mechanism of the Java Virtual Machine works only with non-generic classes.

(JLS 8.1.2)

i.e. catch clauses cannot distinguish between MyClass<String>.MyInnerException and MyClass<Integer>.MyInnerException, and therefore generic exception classes are not allowed.

Community
  • 1
  • 1
Eran
  • 387,369
  • 54
  • 702
  • 768