java中checked和unchecked 異常處理的例子
有兩種型別的異常:一種是checked異常一種是unchecked異常,在這篇文章中我們將利用例項來學習這兩種異常,checked的異常和unchecked異常最大的區別就是checked去唱是在編譯時檢查的而unchecked異常是在執行時檢查的。
什麼是checked異常呢?
checked異常在編譯時檢查,這意味著如果一個方法丟擲checked異常,那麼它應該使用try-catch塊或者使用throws關鍵字來處理這個異常,否則的話程式會報編譯錯誤,命名為checked異常是因為是在編譯時checked的。
用例子來理解這個問題,在這個例子中,我們讀取myfile.txt這個檔案並且將它的內容輸出到螢幕上,在下邊這個程式中有三處異常被丟擲。FileInputStream使用了指定的檔案路徑和名稱,丟擲FileNotFoundException,這個讀取檔案內容的read()函式丟擲IOException異常,關閉檔案輸入流的close()函式同樣也丟擲IOException異常。
import java.io.*; class Example { public static void main(String args[]) { FileInputStream fis = null; /*This constructor FileInputStream(File filename) * throws FileNotFoundException which is a checked * exception*/ fis = new FileInputStream("B:/myfile.txt"); int k; /*Method read() of FileInputStream class also throws * a checked exception: IOException*/ while(( k = fis.read() ) != -1) { System.out.print((char)k); } /*The method close() closes the file input stream * It throws IOException*/ fis.close(); } }
輸出的結果:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Unhandled exception type FileNotFoundException
Unhandled exception type IOException
Unhandled exception type IOException
為什麼這個會編譯錯誤呢?像我在一開始提到的checked異常在編譯時被檢查,因為我們沒有處理這些異常,我們的編譯程式報出了編譯錯誤。
怎麼解決這個錯誤呢?有兩種方式避免這種錯誤,我們一條一條的來看:
方法一:使用throws關鍵字宣告異常
我們知道在main()函式裡有三個checked異常發生,那麼避免這種編譯錯誤的一種方式就是:在方法上使用throws關鍵字宣告一個異常,你或許會想我們的程式碼丟擲FileNotFoundException和IOEXception,為什麼我們是聲明瞭一個IOException呢,原因是IOException是FileNotFoundException的父類,前者預設覆蓋了後者,如果你想你也可以這樣宣告異常:
public static void main(String args[]) throws IOException, FileNotFoundException.
import java.io.*;
class Example {
public static void main(String args[]) throws IOException
{
FileInputStream fis = null;
fis = new FileInputStream("B:/myfile.txt");
int k;
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}
}
輸出結果:
File content is displayed on the screen.
方法二:使用try-catch塊處理異常
上一種方法並不是很好,那不是處理異常最好的方式,你應該對每一個異常給出有意義的資訊,使那些想了解這些錯誤的人能夠理解,下邊是這樣的程式碼:
import java.io.*;
class Example {
public static void main(String args[])
{
FileInputStream fis = null;
try{
fis = new FileInputStream("B:/myfile.txt");
}catch(FileNotFoundException fnfe){
System.out.println("The specified file is not " +
"present at the given path");
}
int k;
try{
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}catch(IOException ioe){
System.out.println("I/O error occurred: "+ioe);
}
}
}
上邊的程式碼能夠正常執行,並將內容顯示出來
下邊是一些其他的checked異常
SQLException
IOEXception
DataAccessException
ClassNotFoundException
InvocationTargetException
什麼是unchecked異常呢
unchecked異常在編譯時不會檢查,這意味著即使你沒有宣告或者處理異常你的程式也會丟擲一個unchecked異常,程式不會給出一個編譯錯誤,大多數情況下這些異常的發生是由於使用者在互動過程中提供的壞資料。這需要程式設計師提前去判斷這種能夠產生這種異常的情況並且恰當的處理它。所有的unchecked異常都是RuntimeException的子類。我們來看一下下邊的程式碼:
class Example {
public static void main(String args[])
{
int num1=10;
int num2=0;
/*Since I'm dividing an integer with 0
* it should throw ArithmeticException*/
int res=num1/num2;
System.out.println(res);
}
}
如果你編譯這段程式碼,這段程式碼將會被通過,但是當你執行的時候它將丟擲ArithmeticException。這段程式碼清楚的表明了unchecked異常在編譯期間是不會被checked的,他們在執行期間被檢查,我們來看另一個例子:
class Example {
public static void main(String args[])
{
int arr[] ={1,2,3,4,5};
/*My array has only 5 elements but
* I'm trying to display the value of
* 8th element. It should throw
* ArrayIndexOutOfBoundsException*/
System.out.println(arr[7]);
}
}
這段程式碼同樣被成功的編譯通過,因為ArrayIndexOutOfBoundsException是unchecked異常。
注意:這並不意味著編譯器不檢查這些異常我們就不處理這些異常了,事實上我們需要更加小心的處理這些異常,例如在上邊的例子中,應該提供給使用者一個他想讀取的資訊在陣列中不存在的資訊,以便使用者修改這個問題
class Example {
public static void main(String args[])
{
try{
int arr[] ={1,2,3,4,5};
System.out.println(arr[7]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("The specified index does not exist " +
"in array. Please correct the error.");
}
}
}
這裡還有其他的一些常見的unchecked異常:
NullPointerException
ArrayIndexOutOfBoundsException
ArithmeticException
IllegalArgumentException