對於java異常的處理一直都不很清楚,只知道try..catch...finally,在具體的項目中才發現僅僅了解這些
還是不夠的.
Java 中定義了兩類異常:
Checked exception: 這類異常都是Exception的子類,該異常必須明確的捕獲或重新拋出,因為編譯期就會檢查是否有處理.
Unchecked exception: 這類異常都是RuntimeException的子類,雖然RuntimeException同樣也是Exception的子類,但是它們是特殊的,它們不能通過client code來試圖解決,所以稱為Unchecked exception
以往我都是應用checked exception多於Unchecked exception,最近,在java社區激起了一場關於checked exception和使用它們的價值的爭論。這場爭論起源於JAVA是第一個擁有Checked exception的主流OO語言這樣一個事實,而C++和C#都是根本沒有Checked exception,它們所有的異常都是unchecked。
在實際項目中,自己寫的服務類型方法是否拋出異常,以及拋出什麼類型的異常呢?
當方法本身出現不可預估到的異常情況時,應該拋出或轉換成RuntimeException.
而在方法內部處理邏輯時,對於不合理的業務狀況,應該拋出業務異常,業務異常直接繼承Exception,是Checked exception.這樣客戶端就必須處理這些異常,以及盡可能的恢復異常,執行程序.
如果客戶端不需要處理處理異常,只需要打印提示出來,那麼業務異常也可以使用Unchecked exception類型.
下面轉貼另一個文章,寫的也很清楚
[zt] Java语言的异常类使用讨论
Java异常的语法应该是很简单的,一个try,catch,finally,一个throws,throw,两分钟就可学完了。我相信许多人和我一样,对于异常是这样处理的:
1.写程序时就等编译器检查,一旦通不过就加try,catch;
2.自己抛异常常常忘了在方法声明时加throws,而且又不明白为什么有的异常需要throws,而有的又不需要;
3.从来不写自己的异常类;
4.catch到异常不知道怎么办,通通加一行printStackTrace拉倒;
如果属于以上这几种情况的,我觉得有必要和我一起讨论一下Java的异常使用方法。
查阅资料可以得知,Java最主要的异常类包括4种:Throwable、Error、Exception和RuntimeException;其中Throwable是所有异常类的父类,它继承Object类并实现Serializable接口;Error和Exception都是Throwable的子类;而RuntimeException是Exception的子类。Exception的子类非常多,但是RuntimeException是一个特殊的子类,需要单独讨论。
一般当程序员在某个方法中抛出一个Exception异常(或者其子类)时,需在方法头部声明此方法抛出了一个异常,就是用throws关键字来声明;但是如果在方法中抛出一个RuntimeException或者一个Error时,则不需要声明此方法抛出了异常,这是为什么呢?
语法上的约束必然有其背后的道理;如果不去弄明白这些道理而是一味的依赖编辑器来帮忙,则事倍功半。事实上,Java语言的这种语法含义是:Java编译器要求Java程序必须捕获或声明所有非运行时的异常,也就是说,Exception异常是需查异常,必须由程序员对它严格的负责,如果在方法中抛出,必须声明,如果抛出的异常没有被catch,则会出现语法错误,编译都不能通过。这是强制性的让程序员遵守Java的异常规则。这样规定的原因是当Exception异常出现时,运行的程序还有补救的余地,通过异常处理代码,可以让程序恢复运行,如果不捕捉这种异常,则白白浪费了补救程序的机会。而且,这种异常应让程序员可见,所以必须在方法头部声明此方法抛出了某种Exception异常。
那么,Error和RuntimeException都是不需查异常,在方法中抛出这两种异常都不需要声明,在程序中不catch它们也不会造成语法错误。我的理解是,当出现这样的异常时,运行的程序已经没有补救的余地了,于是直接抛出异常让程序结束是比较合理的安排。如果在程序运行时出现了Error或者RuntimeException,那么程序员也无能为力,所以它们可以对程序员透明,也不需要特意声明让程序员来处理它们。
现在我们知道,try和catch一般对Exception及其子类使用,throws也是。而对于Error和RuntimeException则不需要throws,不过还是可以catch的,但是catch到它们一般也就是释放资源,退出程序而已。
对于catch到的异常的处理,最经常犯的错误就是丢失异常,catch到旧的异常抛出新的异常,等到程序出错时就找不到旧异常的信息了。其实JDK1.4已经提供了这个问题的解决方案,就是用Exception的构造函数形成异常链,用旧异常作为参数构造新异常,这样就可以在出错时一步步跟踪到所有出现过的异常了,这两个构造函数就是:
public Exception(String message, Throwable cause) {
super(message, cause);
}
public Exception(Throwable cause) {
super(cause);
}
就想到这么多,以后有了新体会再续。
更詳細的可參考javaeye的討論:为什么 Java 中要使用 Checked Exceptions