什么是異常?
先看一段代碼
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
System.out.println("a = "+a);
}
這段代碼的執(zhí)行結果是
2
a = 2
如果我們輸入不是整型數(shù)2澜倦,而是一個字符串"abc",那么它的執(zhí)行結果是
abc
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at com.dd299.imserver.ExceptionTest.main(ExceptionTest.java:17)
在這里庄蹋,程序出了錯,沒有返回我們期望的結果形式卓箫,而是打印出一堆錯誤信息载矿。這種情況,就叫做異常烹卒。
從上面的例子可以看出闷盔,在java中,異常就是程序的一些錯誤旅急。
異常和哪些錯誤有關逢勾?
- 用戶輸入錯誤
- 設備錯誤
- 物理限制
- 代碼錯誤
在java中,所有的異常對象都是繼承于Throwable類的一個實例藐吮。事實上溺拱,直接繼承自Throwable的類只有兩個:Exception和Error。
- Error:主要描述系統(tǒng)內部錯誤和資源耗盡的錯誤谣辞,是脫離程序員控制的問題迫摔。
- Exception:是我們常說的異常,程序員可以通過優(yōu)化代碼的方式避免它潦闲。異常又分成兩類:
- 運行時異常(RuntimeException):指在編譯期間無法發(fā)現(xiàn)的異常攒菠,在Java語言規(guī)范中,將派生于RuntimeException和Error的所有異常稱為未檢查異常歉闰。包含下面幾種情況:
- 錯誤的類型轉換
- 數(shù)組訪問越界
- 訪問空指針
- 已檢查異常:指編譯時就可以發(fā)現(xiàn)的異常。包含的情況有:
- 試圖在文件尾部后面讀取數(shù)據(jù)
- 試圖打開一個錯誤格式的URL
- 試圖根據(jù)給定的字符串查找Class對象卓起,而這個字符串表示的類并不存在和敬。
- 運行時異常(RuntimeException):指在編譯期間無法發(fā)現(xiàn)的異常攒菠,在Java語言規(guī)范中,將派生于RuntimeException和Error的所有異常稱為未檢查異常歉闰。包含下面幾種情況:
一句永遠正確的話:“如果出現(xiàn)了RuntimeException,那一定就是你的問題”。
處理異常都有哪幾種方式
面對出錯的情況一向都是兩種處理角度戏阅,一種就是自己將錯誤處理掉昼弟;另一種是將錯誤信息拋出去,告知調用方奕筐,等待處理舱痘。相應的变骡,處理異常也一樣有兩種方式:
- try/catch塊:捕獲異常
- throws Exception,...:聲明已檢查異常。
聲明已檢查異常
對于一個已知有可能拋出異常的方法芭逝,需要在方法聲明時同時聲明可能會拋出的異常
public void function() throws Exception{
exp();
}
publi void exp() throws Exception{
}
這種情況塌碌,往往是在代碼中調用了一個同樣聲明了異常的方法。
另外對于自定義異常旬盯,java不會拋出開發(fā)者自定義的異常台妆,這時開發(fā)者要自行拋出。
public void exp(String input) throws XXXException{
...
if("a".equal.(input)){
throw new XXXException();
}
}
如何捕獲異常胖翰?
在上面的例子中接剩,除了將異常拋出去之外,還可以自行處理萨咳,這就需要捕獲異常懊缺。下面的代碼說明了一個典型的捕獲異常的情況
public void function() {
try{
exp();//(1)
}
catch(XXXException xxxe){
...//(2)
}
catch(Exception e){
...//(3)
}
}
publi void exp() throws Exception{
}
上面的例子中,如果exp()沒有出現(xiàn)錯誤培他,那么程序執(zhí)行完try中的代碼鹃两,就自動結束,不會調用catch中的代碼靶壮;在try中一旦出現(xiàn)了catch對應的異常怔毛,就會停止當前的執(zhí)行,跳到對應的catch中執(zhí)行腾降;如果出現(xiàn)了異常拣度,但在catch中沒找到對應的處理,就退出螃壤。
Finally子句
Finally子句是用來處理那些不論有沒有發(fā)生異常抗果,都要處理的情況,比如說資源的釋放奸晴。
InputStream in = ...;
try{
...
}
finally{
in.close;
}