異常
異常概述
Java中將程序執行出現的一些意外情況分爲兩種:
1- 錯誤
2- 異常
錯誤(Error)
錯誤一般是JVM虛擬出現的一些內存不足,或者資源耗盡的系統級別錯誤(比如:棧溢出,JVM錯誤等),這些問題對於程序員來說無法從根本上解決。
異常(Exception)
異常指的是程序在編譯或者執行過程中出現的一些外在因素導致的問題(比如:數組索引越界,空指針異常,類型轉換異常等),這些問題程序員一般是可以解決的,因此異常需要重點關注。
異常分類
Java中將異常分爲兩大類,第一大類稱之爲編譯時異常(一般異常/檢查異常);第二大類稱之爲運行時異常(RuntimeException)
編譯異常
編譯異常也稱之一般異常,檢查異常;這種類型異常一般表現爲在編譯期間,由編譯器直接拋出,需要由程序員進行手動處理。常見如下:
- FileNotFoundException
- IOException
- ClassNotFoundException
- ParseException
- …
運行時異常
在編譯期間正常通過,在JVM執行程序時,出現的異常稱之爲運行時(Runtime)異常,運行時異常是所有異常中最常見的異常,常見如下:
- ArrayIndexOutOfBoundsException
- NullPointerException
- ArithmeticException
- ClassCastException
- …
異常處理
Java中的異常處理分爲兩種方式:
- 異常拋出(throw)
- 異常捕獲(catch)
異常處理的常見關鍵字:
- throws:一般作用於方法上,將有可能出現異常拋出,交給下一級調用者處理
- throw:
- try
- catch
- finally
異常拋出
異常拋出通常使用throws關鍵字,在方法的聲明上將有可能出現的異常拋給下一級的調用者處理,異常拋出是一種實際開發中非常常見的處理異常的方式。
public class Demo2 {
/**方法拋出了異常,將由下一級調用者處理*/
public void m1() throws FileNotFoundException{
FileInputStream fis = new FileInputStream("c:/a.txt");
}
/**該方法調用了m1方法,因此需要處理m1中的異常,另外:m2方法可以拋出比m1方法範圍更大的異常*/
public void m2() throws IOException{
System.out.println("第二個方法");
m1();
}
/**檢查異常最終可以拋給主方法由JVM進行最終處理(打印異常信息到標準輸出流)*/
public static void main(String[] args) throws IOException{
new Demo2().m2();
}
}
注意:通常異常的拋出爲檢查異常;運行時異常一般無需拋出,即便拋出運行時異常,下一級調用者也無需繼續拋出或手動處理該異常,例如:
public class Demo2 {
/**a方法拋出的爲運行時異常*/
public void a() throws NullPointerException{
}
/**b方法無需處理,也可以選擇處理(編譯器不會提示需要處理)*/
public void b(){
a();
}
public static void main(String[] args) {
new Demo2().b();
}
}
throw
throw用於拋出異常,語法結構如下:
thorw 異常對象;
throw new Exception("出現異常啦");
throw這一行語句一旦執行,程序就一定會出現異常;throw主要用於程序編寫過程中,程序員手動提出的異常(自定義異常)
異常捕獲
由於異常的拋出是一種臨時性解決方案,最終異常還是需要有處理機制,因此異常的捕獲就是爲了解決這些問題而存在的另一種異常處理方案。異常捕獲的語法結構
try{
//有可能出現異常的代碼片段
}catch(異常類型 引用){
//異常的解決(打印異常信息到標準輸出流/記錄到日誌文件)
}finally{
//不論是否出現異常都會執行(一般用於回收資源等操作)
}
異常出現後的關注事項:
- 異常的類型
- 異常出現位置的關鍵字
- 第一次出現的位置(行號)
自定義異常
在實際開發中JDK中內置的異常類並不能滿足所有的異常需求,比如一些業務層面的異常,因此,自定義異常就十分有必要了,自定義異常類需要從java.lang.Exception類繼承。