淺析Java語言中兩種異常的差別
Java提供了兩類主要的異常:runtime exception和checked exception。所有的checked exception是從java.lang.Exception類衍生出來的,而runtime exception則是從java.lang.RuntimeException或java.lang.Error類衍生出來的。
它們的不同之處表現在兩方面:機制上和邏輯上。
一、機制上
它們在機制上的不同表現在兩點:1.如何定義方法;2. 如何處理丟擲的異常。請看下面CheckedException的定義:
public class CheckedException extends Exception
{
public CheckedException() {}
public CheckedException( String message )
{
super( message );
}
}
以及一個使用exception的例子:
public class ExceptionalClass
{
public void method1()
throws CheckedException
{
// ... throw new CheckedException( “...出錯了“ );
}
public void method2( String arg )
{
if( arg == null )
{
throw new NullPointerException( “method2的引數arg是null!” );
}
}
public void method3() throws CheckedException
{
method1();
}
}
你可能已經注意到了,兩個方法method1()和method2()都會丟擲exception,可是隻有method1()做了宣告。另外,method3()本身並不會丟擲exception,可是它卻宣告會丟擲CheckedException。在向你解釋之前,讓我們先來看看這個類的main()方法:
public static void main( String[] args )
{
ExceptionalClass example = new ExceptionalClass();
try
{
example.method1();
example.method3();
}
catch( CheckedException ex ) { } example.method2( null );
}
在main()方法中,如果要呼叫method1(),你必須把這個呼叫放在try/catch程式塊當中,因為它會丟擲Checked exception。
相比之下,當你呼叫method2()時,則不需要把它放在try/catch程式塊當中,因為它會丟擲的exception不是checked exception,而是runtime exception。會丟擲runtime exception的方法在定義時不必宣告它會丟擲exception。
現在,讓我們再來看看method3()。它呼叫了method1()卻沒有把這個呼叫放在try/catch程式塊當中。它是透過宣告它會丟擲method1()會丟擲的exception來避免這樣做的。它沒有捕獲這個exception,而是把它傳遞下去。實際上main()方法也可以這樣做,透過宣告它會丟擲Checked exception來避免使用try/catch程式塊(當然我們反對這種做法)。
小結一下:
* Runtime exceptions:
在定義方法時不需要宣告會丟擲runtime exception;
在呼叫這個方法時不需要捕獲這個runtime exception;
runtime exception是從java.lang.RuntimeException或java.lang.Error類衍生出來的。
* Checked exceptions:
定義方法時必須宣告所有可能會丟擲的checked exception;
在呼叫這個方法時,必須捕獲它的checked exception,不然就得把它的exception傳遞下去;
checked exception是從java.lang.Exception類衍生出來的。
二、邏輯上
從邏輯的角度來說,checked exceptions和runtime exception是有不同的使用目的的。checked exception用來指示一種呼叫方能夠直接處理的異常情況。而runtime exception則用來指示一種呼叫方本身無法處理或恢復的程式錯誤。
checked exception迫使你捕獲它並處理這種異常情況。以java.net.URL類的構建器(constructor)為例,它的每一個構建器都會丟擲MalformedURLException。MalformedURLException就是一種checked exception。設想一下,你有一個簡單的程式,用來提示使用者輸入一個URL,然後透過這個URL去一個網頁。如果使用者輸入的URL有錯誤,構建器就會丟擲一個exception。既然這個exception是checked exception,你的程式就可以捕獲它並正確處理:比如說提示使用者重新輸入。
再看下面這個例子:
public void method()
{
int [] numbers = { 1, 2, 3 };
int sum = numbers[0] numbers[3];
}
在執行方法method()時會遇到ArrayIndexOutOfBoundsException(因為陣列numbers的成員是從0到2)。對於這個異常,呼叫方無法處理/糾正。這個方法method()和上面的method2()一樣,都是runtime exception的情形。上面我已經提到,runtime exception用來指示一種呼叫方本身無法處理/恢復的程式錯誤。而程式錯誤通常是無法在執行過程中處理的,必須改正程式程式碼。
總而言之,在程式的執行過程中一個checked exception被丟擲的時候,只有能夠適當處理這個異常的呼叫方才應該用try/catch來捕獲它。而對於runtime exception,則不應當在程式中捕獲它。如果你要捕獲它的話,你就會冒這樣一個風險:程式程式碼的錯誤(bug)被掩蓋在執行當中無法被察覺。因為在程式測試過程中,系統列印出來的呼叫堆疊路徑(StackTrace)往往使你更快找到並修改程式碼中的錯誤。有些程式設計師建議捕獲runtime exception並紀錄在log中,我反對這樣做。這樣做的壞處是你必須透過瀏覽log來找出問題,而用來測試程式的測試系統(比如Unit Test)卻無法直接捕獲問題並報告出來。
在程式中捕獲runtime exception還會帶來更多的問題:要捕獲哪些runtime exception?什麼時候捕獲?runtime exception是不需要宣告的,你怎樣知道有沒有runtime exception要捕獲?你想看到在程式中每一次呼叫方法時,都使用try/catch程式塊嗎?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10901326/viewspace-965477/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 淺析Java語言中的內部類Java
- c語言中預設引數的兩種型別C語言型別
- dart系列之:dart語言中的異常Dart
- Java語言和C++語言的差異——老生常談 (轉)JavaC++
- 淺析C語言中的setjmp與longjmp函式C語言函式
- Go 語言中的兩種 slice 表示式Go
- Java異常處理的兩種方式以及自定義異常的使用方法Java
- 淺析php中的異常與錯誤PHP
- 通過PHP與Python程式碼對比淺析語法差異PHPPython
- 通過 PHP 與 Python 程式碼對比淺析語法差異PHPPython
- 淺析平面設計與網頁設計的差異性網頁
- Java語言和C++語言的差異 (轉)JavaC++
- c語言中陣列的三種型別C語言陣列型別
- 淺談java異常[Exception] (轉)JavaException
- Java中常見的十八種異常!Java
- 比對兩個資料庫的差異:Java篇資料庫Java
- Java 異常處理中的種種細節!Java
- Java語言與C++語言的差異總結JavaC++
- 常見的索引模型淺析索引模型
- C語言中&&,||,&,| 的區別C語言
- q語言中_的3種用法
- Java中測試異常的多種方式Java
- C語言中幾種報錯型別的解決方案C語言型別
- java比較mysql兩個資料庫中差異JavaMySql資料庫
- 淺析ASP.NET 3.5與ASP.NET 4.0主要差別ASP.NET
- 淺析Java反射--JavaJava反射
- 淺談C語言中函式的使用C語言函式
- 好程式設計師Java分享Java語言中的常見的跳脫字元程式設計師Java字元
- 淺析Java NIOJava
- 淺析JAVA反射Java反射
- 淺析Java的流 (轉)Java
- Java之異常資訊的三種列印方式Java
- 【轉】java六種異常處理的陋習Java
- Ajax語法淺析
- Java異常十一:使用throw丟擲異常物件;throw和throws的區別Java物件
- java字串“==”與“equals”的差異及與c#的區別Java字串C#
- ruby 怪異的while迴圈處理,和java的差別WhileJava
- 淺析number型別的值型別