RuntimeException和Exception比较-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

RuntimeException和Exception比较

简介: RuntimeException和Exception比较

RuntimeException和Exception比较

自定义异常是继承RuntimeException还是继承Exception

Java Exception分为两种

  • 一种是不可检查异常uncheked exception,可检查异常在代码中显示的捕获,如果不捕获,编译期会报错。
  • 另一种是可检查异常checked exception,不可检查异常编译期不会检测,此类异常是运行时异常。

区别

  • RuntimeException是Exception的子类,但是虚拟机在处理异常的时候对他们做了区分。
  • 自定义异常如果继承RuntimeException,这样的异常spring可以进行事务回滚。
例:一个方法报异常,另一个方法回滚
在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
throw new RuntimeException();
}
  • TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常了
在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常了
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
  • 自定义异常如果继承Exception,这样的异常spring不支持事务回滚。但是可以显示在方法上声明@Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚。
例:一个方法报异常,另一个方法不会回滚
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
}
try catch这种把整个包裹起来,这种业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出,全被捕获并“吞掉”,导致spring异常抛出触发事务回滚策略失效。

继承Execption类的优缺点

  • 优点:异常总能被捕获,抛出的异常必须呗try-catch显示的捕获处理。
  • 缺点:因为异常必须被捕获或者要么继续向上层抛出,表现出:要么满屏的try-catch或者整个链路方法的后面全是throws Exception不美观,也导致方法耦合严重,一旦最内层方法不抛出异常了,外层方法全要修改。

继承RuntimeExecption类优缺点

  • 优点:抛出的异常可以不处理。
  • 缺点:对于必须处理的异常如果被声明成了RuntimeException,比如涉及到金额,调用方未捕获异常继续处理,就会导致业务出错。

如何选择

  • 减少程序耦合,自定义为RuntimeException,但是和团队约定好:某某异常一定要在哪一层捕获。 如果某个异常不想处理,无关紧要,但是要做好日志记录。
  • 当你是程序级别接口提供者,一定要抛出Exception,这样调用方即使不约定也一定会捕获这个异常。 涉及数据库事务一定要声明RuntimeException,提供服务级接口一定抛出Exception。
  • 例如我要写一个java api,这个api中会调用一个极其操蛋的远端服务,这个远端服务经常超时和不可用。所以我决定以抛出自定义异常的形式向所有调用这个api的开发人员周知这一操蛋的现实,让他们在调用这个api时务必考虑到远端服务不可用时应该执行的补偿逻辑(比如尝试调用另一个api)。此时自定义的异常类就应继承Exception,这样其他开发人员在调用这个api时就会收到编译器大大的红色报错:【你没处理这个异常!】,强迫他们处理。
  • 又如,我要写另一个api,这个api会访问一个非常非常稳定的远端服务,除非有人把远端服务的机房炸了,否则这个服务不会出现不可用的情况。而且即便万一这种情况发生了,api的调用者除了记录和提示错误之外也没有别的事情好做。但出于某种不可描述的蛋疼原因,我还是决定要定义一个异常对象描述“机房被炸”这一情况,那么此时定义的异常类就应继承RuntimeException,因为我的api的调用者们没必要了解这一细微的细节,把这一异常交给统一的异常处理层去处理就好了。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: