RuntimeException和Exception比较

简介: RuntimeException和Exception比较

RuntimeException和Exception比较

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

Java Exception分为两种

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

区别

  • RuntimeException是Exception的子类,但是虚拟机在处理异常的时候对他们做了区分。
  • 自定义异常如果继承RuntimeException,这样的异常spring可以进行事务回滚。
例:一个方法报异常,另一个方法回滚在catch语句中最后增加thrownewRuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exceptione) {
thrownewRuntimeException();
}
  • TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常了
在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常了try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exceptione) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
  • 自定义异常如果继承Exception,这样的异常spring不支持事务回滚。但是可以显示在方法上声明@Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚。
例:一个方法报异常,另一个方法不会回滚try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exceptione) {
}
trycatch这种把整个包裹起来,这种业务方法也就等于脱离了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的调用者们没必要了解这一细微的细节,把这一异常交给统一的异常处理层去处理就好了。
目录
相关文章
|
3天前
|
C++
C++异常处理try和throw以及catch的使用
C++异常处理try和throw以及catch的使用
|
9月前
|
消息中间件 Java 中间件
业务中 自定义异常用 Exception 还是 RuntimeException? 为什么?
今天和同事 聊了下异常 相关的事,整理在此 目前公司中使用的 自定义异常是 extend RuntimeException
73 1
|
12月前
|
Java API Spring
RuntimeException和Exception的区别
RuntimeException和Exception的区别
104 0
|
Java 程序员 编译器
异常(Exception)
异常(Exception)
79 0
异常(Exception)
|
Java 程序员 编译器
Java异常——throw、throws及自定义异常
Java异常——throw、throws及自定义异常
110 0
|
安全 Java 数据库连接
Java中的异常处理详解(try、catch、finally、throw、throws)
Java中的异常处理详解(try、catch、finally、throw、throws)
266 1
|
Linux C# Windows
【C#】简单解决PathTooLong的Exception
原文:【C#】简单解决PathTooLong的Exception 前提 windows系统路径的最大长度限制是260个字符(听说.Net 4.6.2,取消了这个限制),而Linux或者Unix系统的好像是4K个字符。
975 0
|
Java
throws 与 throw
/* * 有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。 * 或者说,我处理不了,我就不处理了。 * 为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
1055 0