Java中的内部静态与非静态异常类

时间:2019-12-18 11:02:04

标签: java generics exception

我确实注意到有关静态和非静态内部异常类的奇怪行为。

例如,以下代码将无法编译:

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

但是下面的代码将编译:

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

为什么这种方式?

可以肯定的是,由于类型擦除,我们不能有泛型异常,但是上面的内容不是泛型异常类,而是在泛型类内部。但是,如果它是静态的,则允许它,但是如果它是非静态的,则不允许它?

接下来的问题是,仅由于Generic的类型擦除功能(如此处提到的那样)而不允许泛型异常: https://www.mscharhag.com/java/java-exceptions-and-generic-types 还是有其他原因?

1 个答案:

答案 0 :(得分:2)

  

可以肯定的是,由于类型擦除,我们不能有泛型异常,但是上面的内容不是泛型异常类,而是在泛型类内部。

您的内部类(第一个摘要),因为它的封闭类是泛型类,而封闭类是内部类的一部分。如果没有相应的封闭类实例,则无法创建内部类实例。

关于泛型类为何不能扩展Exception的原因:

  

如果泛型类是Throwable(第11.1.1节)的直接或间接子类,则这是编译时错误。

     

由于Java虚拟机的catch机制仅适用于非通用类,因此需要此限制。

JLS 8.1.2

即catch子句无法区分MyClass<String>.MyInnerExceptionMyClass<Integer>.MyInnerException,因此不允许通用异常类。