Java的「異常」

Java的「異常」

   下載地址 http://wenku.it168.com/d_000095031.shtml

「異常」指的是程序運行時出現的非正常狀況。在用傳統的語言編程時,程序員只能經過函數的返回值來發出錯誤信息。這易於致使不少錯誤,由於在不少狀況下須要知道錯誤產生的內部細

節。一般,用全局變量errno來存儲「異常」的類型。這容易致使誤用,由於一個errno的值有可能在被處理以前被另外的錯誤覆蓋掉。即便最優美的C語言程序,爲了處理「異常」狀況,也常

求助於goto語句。Java對「異常」的處理是面向對象的。一個Java的Exception是一個描述「異常」狀況的對象。當出現「異常」狀況時,一個Exception對象就產生了,並放到產生這個「異

常」的成員函數裏。
1基礎
Java的「異常」處理是經過5個關鍵詞來實現的:try,catch,throw,throws和finally。用try來執行一段程序,若是出現「異常」,系統拋出(throws)一個「異常」,你能夠經過它的類型來

捕捉(catch)它,或最後(finally)由缺省處理器來處理。下面是「異常」處理程序的基本形式:
try { 
//程 序 塊 
} catch (ExceptionType1 e) { 
// 對ExceptionType1的處 理 
} catch (ExceptionType2 e) { 
// 對ExceptionType2的 處 理 throw(e); 
//再 拋 出 這 個「 異 常」 
} finally { } 
}
2"異常」的類型
在「異常」類層次的最上層有一個單獨的類叫作Throwable。這個類用來表示全部的「異常」狀況。每一個「異常」類型都是Throwable的子類。Throwable有兩個直接的子類。一類是Exception

,是用戶程序可以捕捉到的「異常」狀況。咱們將經過產生它的子類來建立本身的「異常」。另外一類是Error,它定義了那些一般沒法捕捉到的「異常」。要謹慎使用Error子類,由於它們通

常會致使災難性的失敗。在Exception中有一個子類RuntimeException,它是程序運行時自動地對某些錯誤做出反應而產生的。
3不捕捉「異常」
「異常」對象是Java在運行時對某些「異常」狀況做出反應而產生的。例如,下面這個小程序包含一個整數被0除的「異常」。
package com.chinasofti;

class Exc0 {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
當Java執行這個除法時,因爲分母是0,就會構造一個「異常」對象來使程序停下來並處理這個錯誤狀況,在運行時「拋出」(throw)這個「異常」。說「拋出」是由於它象一個滾燙的馬鈴

薯,你必須把它抓住並當即處理。程序流將會在除號操做符處被打斷,而後檢查當前的調用堆棧來查找「異常」。一個「異常」處理器是用來當即處理「異常」狀況的。在這個例子裏,咱們

沒有編一個「異常」處理器,因此缺省的處理器就發揮做用了。缺省的處理器打印Exception的字符值和發生「異常」的地點。下面是咱們的小例子的輸出。
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.chinasofti.Exc0.main(Exc0.java:6)
4 try與catch
一般咱們但願本身來處理「異常」並繼續運行。能夠用try來指定一塊預防全部「異常」的的程序。緊跟在try程序後面,應包含一個catch子句來指定你想要捕捉的「異常」的類型。例如,下

面的例子是在前面的例子的基礎上構造的,但它包含一個try程序塊和一個catch子句。
package com.chinasofti;

class Exc1 {
public static void main(String args[]) {
try {
int d = 0;
int a = 42 / d;
} catch (ArithmeticException e) {
System.out.println("division by zero");
}
}
}
catch子句的目標是解決「異常」狀況,把一個變量設到合理的狀態,並象沒有出錯同樣繼續運行。若是一個子程序不處理某個「異常」,則返到上一級處理,直到最外一級。
5多個catch子句
在某些狀況下,同一段程序可能產生不止一種「異常」狀況。你能夠放置多個catch子句,其中每一種「異常」類型都將被檢查,第一個與之匹配的就會被執行。若是一個類和其子類都有的話

,應把子類放在前面,不然將永遠不會到達子類。下面是一個有兩個catch子句的程序的例子。
package com.chinasofti;

class MultiCatch {
public static void main(String args[]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
} catch (ArithmeticException e) {
System.out.println("div by 0: " + e);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("array index oob: " + e);
}
}
}
若是在程序運行時不跟參數,將會引發一個0作除數的「異常」,由於a的值爲0。若是咱們提供一個命令行參數,將不會產生這個「異常」,由於a的值大於0。但會引發一個

ArrayIndexOutOfBoundexception的「異常」,由於整型數組c的長度是1,卻給c[42]賦值。下面是以上兩種狀況的運行結果。
a = 0
div by 0: java.lang.ArithmeticException: / by zero
6try語句的嵌套
你能夠在一個成員函數調用的外面寫一個try語句,在這個成員函數內部,寫另外一個try語句保護其餘代碼。每當遇到一個try語句,「異常」的框架就放到堆棧上面,直到全部的try語句都完

成。若是下一級的try語句沒有對某種「異常」進行處理,堆棧就會展開,直到遇到有處理這種「異常」的try語句。下面是一個try語句嵌套的例子。
package com.chinasofti;

class MultiNest {
static void procedure() {
try {
int c[] = { 1 };
c[42] = 99;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("array index oob: " + e);
}
}

public static void main(String args[]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
procedure();
} catch (ArithmeticException e) {
System.out.println("div by 0: " + e);
}
}
}
成員函數procedure裏有本身的try/catch控制,因此main不用去處理ArrayIndexOutOfBoundsException。
7throw語句
throw語句用來明確地拋出一個「異常」。首先,你必須獲得一個Throwable的實例的控制柄,經過參數傳到catch子句,或者用new操做符來建立一個。下面是throw語句的一般形式。
throw ThrowableInstance;
程序會在throw語句後當即終止,它後面的語句執行不到,而後在包含它的全部try塊中從裏向外尋找含有與其匹配的catch子句的try塊。下面是一個含有throw語句的例子。
package com.chinasofti;

class ThrowDemo {
static void demoproc() {
try {
throw new NullPointerException("de3mo");
} catch (NullPointerException e) {
System.out.println("caught inside demoproc");
throw e;
}
}

public static void main(String args[]) {
try {
demoproc();
} catch (NullPointerException e) {
System.out.println("recaught: " + e);
}
}
}
下面是這個例子的輸出:
caught inside demoproc
recaught: java.lang.NullPointerException: de3mo
8 throws語句
throws用來標明一個成員函數可能拋出的各類「異常」。對大多數Exception子類來講,Java編譯器會強迫你聲明在一個成員函數中拋出的「異常」的類型。若是「異常」的類型是Error或

RuntimeException,或它們的子類,這個規則不起做用,由於這些在程序的正常部分中是不期待出現的。若是你想明確地拋出一個RuntimeException,你必須用throws語句來聲明它的類型。

這就從新定義了成員函數的定義語法:
type method-name(arg-list) throws exception-list { }
下面是一段程序,它拋出了一個「異常」,但既沒有捕捉它,也沒有用throws來聲明。這在編譯時將不會經過。
package com.chinasofti;

class ThrowsDemo1 {
static void procedure() {
System.out.println("inside procedure");
throw new IllegalAccessException("demo");
}

public static void main(String args[]) {
procedure();
}
}
爲了讓這個例子編譯過去,咱們須要聲明成員函數procedure拋出了IllegalAccessException,而且在調用它的成員函數main裏捕捉它。下面是正確的例子:
package com.chinasofti;

class ThrowsDemo {
static void procedure() throws IllegalAccessException {
System.out.println("inside procedure");
throw new IllegalAccessException("demo");
}

public static void main(String args[]) {
try {
procedure();
} catch (IllegalAccessException e) {
System.out.println("caught " + e);
}
}
}
下面是這個例子的輸出:
inside procedure
caught java.lang.IllegalAccessException: demo
9 finally
當一個「異常」被拋出時,程序的執行就再也不是線性的,跳過某?copy;行,甚至會因爲沒有與之匹配的catch子句而過早地返回。有時確保一段代碼無論發生什麼「異常」都被執行到是必要的

,關鍵詞finally就是用來標識這樣一段代碼的。即便你沒有catch子句,finally程序塊也會在執行try程序塊後的程序以前執行。每一個try語句都須要至少一個與之相配的catch子句或finally

子句。一個成員函數返回到調用它的成員函數,或者經過一個沒捕捉到的「異常」,或者經過一個明確的return語句,finally子句老是剛好在成員函數返回前執行。下面是一個例子,它有幾

個成員函數,每一個成員函數用不一樣的途徑退出,但執行了finally子句。
package com.chinasofti;

public class FinallyDemo {
static void procA() {
try {
System.out.println("inside procA");
throw new RuntimeException("demo");
} finally {
System.out.println("procA's finally");
}
}

static void procB() {
try {
System.out.println("inside procB");
return;
} finally {
System.out.println("procB's finally");
}
}

public static void main(String args[]) {
try {
procA();
} catch (Exception e) {
e.printStackTrace();
}
procB();
}
}
下面是這個例子的輸出:
inside procA
procA's finally
inside procBjava.lang.RuntimeException: demo
at com.chinasofti.FinallyDemo.procA(FinallyDemo.java:7)
at com.chinasofti.FinallyDemo.main(FinallyDemo.java:24)

procB's finally


小結
1.「異常」指的是程序運行時出現的非正常狀況。2.在「異常」類層次的最上層的類叫Throwable,它有兩個直接的子類:Exception和Error。3.Java的「異常」處理經過5個關鍵詞來實現:try,catch,throw,throws和finally。
相關文章
相關標籤/搜索