前言
异常分为Checked/Unchecked,两种类型,前者集成自Exception,后者集成自RuntimeException。
异常处理机制的优势:将正常的代码与异常处理代码分离,
异常抛出的三个场景
- 编程错误导致异常: 如IndexOutOfBoundsException、NullPointerException ,出现这些异常通常由于编程错误导致
- 客户端代码导致异常: 如方法本来需要传入一个yyyymmdd的日期字符串,却传入了人名字符串
- 资源失败导致异常: 内存不足、网络连接失败、找不到要打开的文件等
最佳实践
1. 在设计方法的时候,当决定使用checked exception还是unchecked exception时,先问问自己:“当发生异常,客户端的代码可以做什么?”。如果客户端可以采取相应的恢复措施,使用checked exception,否则使用unchecked exception。
2. 不要让你要抛出的checked exception升级到较高的架构层级,比如,不要将SQLException从DAO层传递到业务层,因为业务层关心这个异常,你有两个办法实现这个目的:
- 转换SQLException -> 另一个checked exception,如果客户端代码可以恢复这个异常
- 转换SQLException -> unchecked exception,如果客户端代码什么也做不了
3. 代码结束后要关闭、清理资源,使用try finlly,如关闭JDBC连接的代码。
4. 不要忽略异常
try {
....
} catch (IOException ex) {
ex.printStackTrace()
}
// or
try {
....
} catch (IOException ex) { }
5. 不要使用异常控制流程
public void useExceptionsForFlowControl() {
try {
while (true) {
increaseCount();
}
} catch (MaximumCountReachedException ex) {
}
// Continue execution
}
public void increaseCount() throws MaximumCountReachedException {
if (count >= 5000)
throw new MaximumCountReachedException();
}
6. 尽力捕获具体异常,而不是Exception这样的高层级异常,下面将导致所有异常(checked、unchecked)都被隐藏。
try{
....
} catch(Exception ex){ }
7. 一个流程的相同异常,只记录一次。
8. 如果希望客户程序员有意识地采取措施,那么抛出checked exception。比如语句:new FileInputStream(aFile),它声明为checked exception,要求客户端程序员根据情况处理这个异常,比如如果业务场景认为这是一个正常的行为,在就直接记录一行info或者warning日志;在某些场景下,则需要将异常直接抛出,或者转换为RuntimeException后抛出
9. 在使用unChecked异常时,必须在在方法声明中详细的说明该方法可能会抛出的unChekced异常。由调用者自己去决定是否捕获unChecked异常
/**
*
* @throws RuntimeException
*/
public static void foo() {
}
业务异常:客户端未按正常流程操作导致的异常,都是Checked Exception,比如输入格式有误,取款转账余额不足——使用checked Exception
如何处理异常?
何时使用unchecked exception?
设计一个方法是,如果是方法调用者错误使用导致代码BUG——使用unchecked异常。
如下代码,如果调用nextToken()前没有调用hasMoreTokens(),会跑出 NoSuchElementException,这个异常是unchecked exception,因为他它是有错误的使用导致的。
StringTokenizer tok = new StringTokenizer(aStr);
while (tok.hasMoreTokens()) {
System.out.print(tok.nextToken());
}
何时使用checked exception?
何时转换异常?
当你调用的程序声明为checked exception,而你有对这个异常束手无策时,将它转换为unchecked exception
何时忽略异常?
public Date getDate(String str){
Date applyDate = null;
SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);
try{
applyDate = format.parse(applyDateStr);
}
catch(ParseException ex){
//忽略异常
}
return applyDate;
}
参考:
http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html
http://tech.e800.com.cn/articles/2009/79/1247105040929_1.html
http://www.cnblogs.com/JavaVillage/articles/384483.html
-- end --