使用自定义异常类
继承excepiton或者RuntimeException的方式来实现自定义异常类,以便更加好地控制自定义异常,例如:通过异常编码和编码描述等属性来描述项目的自定义异常,而通过自定义异常类就能很好地管理项目的异常。
public final class CRMException extends RuntimeException {
private String expCode;// 异常错误编码
private String expDesc;// 异常描述
//其它省略
}
//例如:如果有个自定义异常是描述查询数据为空的时候,则expCode:BA1000 , expDesc:CRM查询不存在数据!
不要将异常直接打印在客户端或页面上
一旦出现异常,我们只要将异常的错误编码呈现给用户,这样用户可以把错误编码交给开发者或管理员去处理。或者将错误代码转换成更通俗易懂的提示返回给用户。
不要利用 Exception 捕捉所有异常
只用Exception来捕获异常虽然不会出错,但却无法对特定的异常进行处理。
public void retrieveObjectById(Long id){
try{
... ...
}catch(IOException e){
//仅仅捕捉 IOException
throw new RuntimeException(“IOException in retieveObjectById”, e);
}catch(SQLException e){
//仅仅捕捉 SQLException
throw new RuntimeException(“SQLException in retieveObjectById”, e);
}catch(Exception e){
//最后一个使用Exception来处理未预料到的其它异常
throw new RuntimeException(“other Exception in retieveObjectById”, e);
}
}
异常应该尽早抛出(迅速失败)
通过在检测到错误时应该立刻抛出异常来实现迅速失败,可以有效继续执行无用的操作,减少了不必要的对象构建和资源占用。
延迟捕获
在迅速失败的基础上,如果希望程序能从异常中恢复而不是中断时,那么应该抛出异常后交给上级去捕获处理,并提供用户明确信息来引导他们从错误中恢复过来。
提供精确的异常的信息
例如:以下对比IllegalArgumentException 异常的两条异常信息:
消息 1: “Incorrect argument for method”
消息 2: “{expCode}:Illegal value for ${argument}=${value}
第一条消息仅说明了参数是非法的或者不正确,但第二条消息包括了参数名和非法值,而这对于找到错误的原因是很重要的。
正确处理异常
-
如果需要对异常进行处理,使用throw抛出异常中断程序,而不是使用e.printStackTrace()将异常输出到控制台。而且最好使用e.printStackTrace()打印异常堆栈信息在日志中而不是控制台
-
对可恢复的情况使用检查型异常,对编程错误使用运行时异常。
-
不要出现空的catch块
-
异常尽量不要包含在 for 循环语句块中,因为异常处理会占用系统资源,让你的代码运行缓慢。
-
为可恢复的错误使用检查型异常,如:可以通过重新询问用户文件名来处理FileNotException;为编程错误使用非检查型错误;为虚拟机的错误使用Error