一、異常體系結構
1、異常:在Java語言中,將程序執行中發生的不正常情況稱為“異常” 。 (開發過程中的語法錯誤和邏輯錯誤不是異常)
2、Java程序在執行過程中所發生的異常事件可分為兩類:
1)Error:Java虛擬機無法解決的嚴重問題。如:JVM系統內部錯誤、資源 耗盡等嚴重情況。比如:StackOverflowError和OOM。一般不編寫針對性 的代碼進行處理。
2)Exception: 其它因編程錯誤或偶然的外在因素導致的一般性問題,可以使 用針對性的代碼進行處理。例如: 空指針訪問 試圖讀取不存在的文件 網絡連接中斷 數組角標越界
3、錯誤處理
一是遇到錯誤就終止程序 的運行。另一種方法是由程序員在編寫程序時,就考慮到錯誤的 檢測、錯誤消息的提示,以及錯誤的處理。
捕獲錯誤最理想的是在編譯期間,但有的錯誤只有在運行時才會發生。 比如:除數為0,數組下標越界等
4、Exception分類:編譯時異常和運行時異常
1)運行時異常:是指編譯器不要求強制處置的異常。一般是指編程時的邏輯錯誤,是程序 員應該積極避免其出現的異常。java.lang.RuntimeException類及它的子 類都是運行時異常。對於這類異常,可以不作處理,因為這類異常很普遍,若全處理可能會對 程序的可讀性和運行效率產生影響。
2)編譯時異常:是指編譯器要求必須處置的異常。即程序在運行時由於外界因素造成的一 般性異常。編譯器要求Java程序必須捕獲或聲明所有編譯時異常。對於這類異常,如果程序不處理,可能會帶來意想不到的結果。
二、常見異常
1、java.lang.RuntimeException
1)ClassCastException //類型轉換異常
2)ArrayIndexOutOfBoundsException
3)NullPointerException
4)ArithmeticException //算術異常
5)NumberFormatException //數據格式不匹配
6)InputMismatchException 。。。。 //輸入不匹配
2、java.io.IOExeption
1)FileNotFoundException //文件找不到
2)EOFException
3、java.lang.ClassNotFoundException //類找到不
4、java.lang.InterruptedException
5、java.io.FileNotFoundException
6、java.sql.SQLException
三、異常處理機制一:try-catch-finally
在編寫程序時,經常要在可能出現錯誤的地方加上檢測的代碼, 如進行x/y運算時,要檢測分母為0,數據為空,輸入的不是數據 而是字符等。過多的if-else分支會導致程序的代碼加長、臃腫, 可讀性差。因此采用異常處理機制。
1、Java提供的是異常處理的抓拋模型。
2、Java程序的執行過程中如出現異常,會生成一個異常類對象, 該異常對象將被提交給Java運行時系統,這個過程稱為拋出 (throw)異常。
3、異常對象的生成
1)由虛擬機自動生成:程序運行過程中,虛擬機檢測到程序發生了問題,如果在當 前代碼中沒有找到相應的處理程序,就會在后台自動創建一個對應異常類的實例 對象並拋出——自動拋出
2)由開發人員手動創建:Exception exception = new ClassCastException();——創 建好的異常對象不拋出對程序沒有任何影響,和創建一個普通對象一樣
4、如果一個方法內拋出異常,該異常對象會被拋給調用者方法中處 理。如果異常沒有在調用者方法中處理,它繼續被拋給這個調用 方法的上層方法。這個過程將一直繼續下去,直到異常被處理。 這一過程稱為捕獲(catch)異常。
5、如果一個異常回到main()方法,並且main()也不處理,則程序運 行終止。
6、程序員通常只能處理Exception,而對Error無能為力。
//異常處理是通過try-catch-finally語句實現的。
try{ ...... //可能產生異常的代碼
} catch( ExceptionName1 e ){ ...... //當產生ExceptionName1型異常時的處置措施
} catch( ExceptionName2 e ){ ...... //當產生ExceptionName2型異常時的處置措施
} [ finally{ ...... //無論是否發生異常,都無條件執行的語句
} ]
7、捕獲異常的有關信息:
與其它對象一樣,可以訪問一個異常對象的成員變量或調用它的 方法。
1)getMessage() 獲取異常信息,返回字符串
2)printStackTrace() 獲取異常類名和異常信息,以及異常出 現在程序中的位置。返回值void。
8、前面使用的異常都是RuntimeException類或是它的子類,這些類的異常的特 點是:即使沒有使用try和catch捕獲,Java自己也能捕獲,並且編譯通過 ( 但運行時會發生異常使得程序運行終止 )。
9、如果拋出的異常是IOException等類型的非運行時異常,則必須捕獲,否則 編譯錯誤。也就是說,我們必須處理編譯時異常,將異常進行捕捉,轉化為 運行時異常
示例
import java.io.*; public class IOExp { public static void main(String[] args) { try { FileInputStream in = new FileInputStream("atguigushk.txt"); int b; b = in.read(); while (b != -1) { System.out.print((char) b); b = in.read(); } in.close(); } catch (IOException e) { System.out.println(e); } finally { System.out.println(" It’s ok!"); } } }
四、異常處理機制二:throws
1、聲明拋出異常是Java中處理異常的第二種方式
1)如果一個方法(中的語句執行時)可能生成某種異常,但是並不能確定如何處理這 種異常,則此方法應顯示地聲明拋出異常,表明該方法將不對這些異常進行處理, 而由該方法的調用者負責處理。
2)在方法聲明中用throws語句可以聲明拋出異常的列表,throws后面的異常類型可 以是方法中產生的異常類型,也可以是它的父類。
示例:
public void readFile(String file) throws FileNotFoundException { …… // 讀文件的操作可能產生FileNotFoundException類型的異常
FileInputStream fis = new FileInputStream(file); ..…… }
2、重寫方法不能拋出比被重寫方法范圍更大的異常類型。在多態的情況下, 對methodA()方法的調用-異常的捕獲按父類聲明的異常處理。
public class A { public void methodA() throws IOException { …… } } public class B1 extends A { public void methodA() throws FileNotFoundException { …… } } public class B2 extends A { public void methodA() throws Exception { //報錯
…… } }
五、手動拋出異常
1、Java異常類對象除在程序執行過程中出現異常時由系統自動生成並 拋出,也可根據需要使用人工創建並拋出。
1)首先要生成異常類對象,然后通過throw語句實現拋出操作(提交給Java運 行環境)。
IOException e = new IOException();
throw e;
2)可以拋出的異常必須是Throwable或其子類的實例。下面的語句在編譯時將 會產生語法錯誤:
throw new String("want to throw");
六、用戶自定義異常
1、 一般地,用戶自定義異常類都是RuntimeException的子類。
2、自定義異常類通常需要編寫幾個重載的構造器。
3、自定義異常需要提供serialVersionUID
4、自定義的異常通過throw拋出。
5、自定義異常最重要的是異常類的名字,當異常出現時,可以根據 名字判斷異常類型。
用戶自定義異常類MyException,用於描述數據取值范圍錯誤信息。用戶 自己的異常類必須繼承現有的異常類。
示例:
class MyException extends Exception { static final long serialVersionUID = 13465653435L; private int idnumber; public MyException(String message, int id) { super(message); this.idnumber = id; } public int getId() { return idnumber; } }