论坛首页 Java企业应用论坛

Java如何处理异常

浏览 3982 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2011-08-18  
异常
受检异常
 FileNotFoundException
 ClassNotFoundException
 SQLException
 IOException
非受检异常
 RunTimeException
 Error
原则:受检异常,如果自身不能处理就往上抛

如果资源的打开,资源的使用,资源的关闭都封装处理,那么可以抛出运行时异常RunTimeException.[Spring的DAO封装].
如果资源的打开,资源的使用,资源的关闭在方法中未处理完成,那么可以抛出受检异常FileNotFound.[java的io文件操作]


抛出受检异常还是非受检异常?
对可恢复的情况使用受检异常,对编程错误使用运行时异常或错误[未受检异常].
未受检异常:如果程序抛出未受检异常或者错误,往往就属于不可恢复的情形,继续执行下去有害无益.[你实现在所有未受检的抛出结构都应该是运行时异常的子类.]

那么何时使用受检异常?
1. 如果正确地使用API并不能阻止这种异常条件的产生。[正确的使用DAO调用,不能阻止异常条件的产生,不使用受检异常][DataAccessException]
2. 一旦产生异常,使用API的程序员可以立即采取有用的动作,这种负担就被认为是正当的.[比如服务层调用失败应该受检异常,某个服务调用失败可能不会影响其他服务的调用][XXXException]

自定义的异常应该是受检还是未受检?
有一条原则是避免不必要的使用受检异常.受检异常可以声明它抛出这些异常,并让它们传播出来.[异常传播]

那么一般我们在设计接口的时候会考虑异常吗?肯定不会,因为接口是提供给外部调用的,接口的实现保持原子性,所以对资源的操作[打开,使用,关闭]都封装在接口的实现中.那么为了避免接口污染,不抛出异常.

例子:
Spring封装的dao操作已经把Exception封装为DataAccessException,此异常为运行时异常,不是受检异常,代码会非常的优雅.当然并不是所有的DAO操作异常都抛出
DataAccessException,而是先抛出它的子类: DataIntegrityViolationException[主键重复异常], TypeMismatchDataAccessException[类型错误]等等异常,采用异常子类来封装多异常类也是不错的选择.
那么使用Spring开发,DAO层的接口可以非常清晰
/**
* 根据服务id获取服务信息
**/
Public ServiceDO getServiceById(Long id);

那么Service层提供的接口也不需要考虑异常,因为DAO已经封装了数据库的交互,保持了DAO操作的原子性,所以Service层接口也会相当的简单.
/**
* 根据服务id获取服务信息
**/
Public ServiceDO getServiceById(Long id);

有人可能会问,这个DAO的接口与Service的接口一模一样,你不觉得蛋痛吗?
这是个问题啊,但是在领域模型中,这是不一样的概念.不知道下面有没有大侠有更好的解决方案[求教.]

我不建议这么做,嘿嘿,有人可能会问你在挑战Spring。在具体的业务逻辑操作,比如你可能会在N多地方调用getServiceById(Long Id).如果错误信息只有在DAO层抛出,你知道哪个业务调用出错了,所以采用异常往外抛的话,你会看到一条线.
DAOException[…],ServiceException[…],Action[…].一条很清晰的异常链.如此的话,你的DAO接口,Service接口设计就要如下:
/**
* 根据服务id获取服务信息
**/
Public ServiceDO getServiceById(Long id) throws DAOException;

如果采用这种方式抛出异常,那么在DAO层,Service层都必须封装Exception,无原无故多这些try..catch实在是蛋痛,不知道有没有哪位大侠有更好的建意。





   发表时间:2011-08-21  
要不要抛出异常看你的系统是如何设计,对异常是如何管理的

我们的系统会把系统分为两个基本大类
1、用户可恢复的异常。比如输入的数据不符合业务逻辑,或者要修改的数据以被其它用户修改,用户通过修改输入内容,或者重新获取要修改的数据就可以继续完成业务操作的。

2、用户无法恢复的异常。通过上述用户操作仍然无法正常完成业务操作的异常。

在开发过程中,虽然有很多api抛出的异常都是非运行时异常,但是因为这些异常对最终用户没有意义,用户无法通过自己的努力从这些异常中恢复过来,所以我们将这些异常捕获后 打印相关log,再转换成运行时异常抛出。
0 请登录后投票
   发表时间:2011-08-22  
怎么处理异常要看业务逻辑的吧。
比如说前台输入错误导致的后台转换异常,这种肯定是要经过一定的处理然后在前台进行提示的,所谓的可恢复异常。
再有类似数据库出错的时候的异常--资源异常,这种异常属于不可自动恢复,往往需要手工介入,所以需要发通知,需要一个注册和通知机制。
再有一些非常严重的bug,比如内存泄漏,网络服务器down机等等,私人觉着应该有通知和自动切换机制,保证业务的连续性。
当然在处理异常的时候主要考虑的还是业务的完整性。任何异常发生了都应该首先保证业务状态,以备恢复或者直接进行业务回滚。
0 请登录后投票
   发表时间:2011-08-22  
rainbowsix 写道
要不要抛出异常看你的系统是如何设计,对异常是如何管理的

我们的系统会把系统分为两个基本大类
1、用户可恢复的异常。比如输入的数据不符合业务逻辑,或者要修改的数据以被其它用户修改,用户通过修改输入内容,或者重新获取要修改的数据就可以继续完成业务操作的。

2、用户无法恢复的异常。通过上述用户操作仍然无法正常完成业务操作的异常。

在开发过程中,虽然有很多api抛出的异常都是非运行时异常,但是因为这些异常对最终用户没有意义,用户无法通过自己的努力从这些异常中恢复过来,所以我们将这些异常捕获后 打印相关log,再转换成运行时异常抛出。

前辈的意思是:
1. 可恢复的异常,比如数据不符合规则,通过修改数据可以完成业务操作.[抛出用户自定义异常或者封装异常信息到返回对象中]
2. 不可恢复的异常 比如DAO异常,用户无法通过自己的努力从这些异常中恢复过来,所以我们将这些异常捕获后,打印相关log,再转换成运行时异常抛出即可.[不污染接口]
0 请登录后投票
   发表时间:2011-08-22  
dwbin 写道
怎么处理异常要看业务逻辑的吧。
比如说前台输入错误导致的后台转换异常,这种肯定是要经过一定的处理然后在前台进行提示的,所谓的可恢复异常。
再有类似数据库出错的时候的异常--资源异常,这种异常属于不可自动恢复,往往需要手工介入,所以需要发通知,需要一个注册和通知机制。
再有一些非常严重的bug,比如内存泄漏,网络服务器down机等等,私人觉着应该有通知和自动切换机制,保证业务的连续性。
当然在处理异常的时候主要考虑的还是业务的完整性。任何异常发生了都应该首先保证业务状态,以备恢复或者直接进行业务回滚。


前辈的意思:
1. 可恢复异常处理如上.
2. 对于运行时异常,比如资源异常,这种异常属于不可自动恢复,需要发通知,注册和通知机制[邮件等],或者考虑业务的完整性,当异常发生时保证业务状态,以备恢复或直接业务回滚。

对于异常的考虑更深入,已经考虑到了异常的数据状态,异常的通知机制,还有对于某些业务异常的回滚机制。good
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics