回答1:

继承Exception还是继承RuntimeException是由异常本身的特点决定的,而不是由是否是自定义的异常决定的。

例如我要写一个java api,这个api中会调用一个极其操蛋的远端服务,这个远端服务经常超时和不可用。所以我决定以抛出自定义异常的形式向所有调用这个api的开发人员周知这一操蛋的现实,让他们在调用这个api时务必考虑到远端服务不可用时应该执行的补偿逻辑(比如尝试调用另一个api)。此时自定义的异常类就应继承Exception,这样其他开发人员在调用这个api时就会收到编译器大大的红色报错:【你没处理这个异常!】,强迫他们处理。

又如,我要写另一个api,这个api会访问一个非常非常稳定的远端服务,除非有人把远端服务的机房炸了,否则这个服务不会出现不可用的情况。而且即便万一这种情况发生了,api的调用者除了记录和提示错误之外也没有别的事情好做。但出于某种不可描述的蛋疼原因,我还是决定要定义一个异常对象描述“机房被炸”这一情况,那么此时定义的异常类就应继承RuntimeException,因为我的api的调用者们没必要了解这一细微的细节,把这一异常交给统一的异常处理层去处理就好了。

回答2:

直接看规范吧 Chapter 11. Exceptions

  • Exception is the superclass of all the exceptions from which ordinary programs may wish to recover.

    The class RuntimeException is a direct subclass of Exception. RuntimeException is the superclass of all the exceptions which may be thrown for many reasons during expression evaluation, but from which recovery may still be possible.

    RuntimeException and all its subclasses are, collectively, the run-time exception classes.

The unchecked exception classes are the run-time exception classes and the error classes.

The checked exception classes are all exception classes other than the unchecked exception classes. That is, the checked exception classes are Throwable and all its subclasses other than RuntimeException and its subclasses and Error and its subclasses.

规范里说明了,Java Exception分为两种, unchecked exceptionchecked exception 显然,前者是运行时异常继承自RuntimeException,后者受控异常继承自Exception。

回答3:

对抛出的异常,checked exception要与方法耦合,尤其是接口中定义的方法影响比较大,使用起来不够灵活。不抛出异常,就得满屏的try-catch。

我现在的做法是除非抛出的异常需要调用层显式处理,否则自定义异常都继承RuntimeException,在最上层的调用统一做一次try-catch。这样一来方法的声明和使用简洁了很多。

其实,我觉得最重要的还是团队的约定。

回答4:

尽量继承RuntimeException。这么做可以降低代码间的耦合性,你想,如果继承Exception(或者其它受查异常),万一原来抛出异常的那个方法不再抛出异常了呢?岂不是接口、以及所有的上层调用方法中的try-catch都得改?

而且太多受查异常很容易把代码搞乱

参考:https://www.zhihu.com/question/51970444