天天看點

try catch 塊的應用

Java try和catch的使用

盡管由Java運作時系統提供的預設異常處理程式對于調試是很有用的,但通常你希望自己處理異常。這樣做有兩個好處。第一,它允許你修正錯誤。第二,它防止程式自動終止。大多數使用者對于在程式終止運作和在無論何時錯誤發生都會列印堆棧軌迹感到很煩惱(至少可以這麼說)。幸運的是,這很容易避免。

為防止和處理一個運作時錯誤,隻需要把你所要監控的代碼放進一個try塊就可以了。緊跟着try塊的,包括一個說明你希望捕獲的錯誤類型的catch子句。完成這個任務很簡單,下面的程式包含一個處理因為被零除而産生的ArithmeticException 異常的try塊和一個catch子句。

?

1 2 3 4 5 6 7 8 9 10 11 12 13

class

Exc2 {

public

static

void

main(String args[]) {

int

d, a;

try

{

// monitor a block of code.

d =

;

a =

42

/ d;

System.out.println(

"This will not be printed."

);

}

catch

(ArithmeticException e) {

// catch divide-by-zero error

System.out.println(

"Division by zero."

);

}

System.out.println(

"After catch statement."

);

}

}

該程式輸出如下:

?

1 2

Division by zero.

After catch statement.

注意在try塊中的對println( )的調用是永遠不會執行的。一旦異常被引發,程式控制由try塊轉到catch塊。執行永遠不會從catch塊“傳回”到try塊。是以,“This will not be printed。”

将不會被顯示。一旦執行了catch語句,程式控制從整個try/catch機制的下面一行繼續。

一個try和它的catch語句形成了一個單元。catch子句的範圍限制于try語句前面所定義的語句。一個catch語句不能捕獲另一個try聲明所引發的異常(除非是嵌套的try語句情況)。

被try保護的語句聲明必須在一個大括号之内(也就是說,它們必須在一個塊中)。你不能單獨使用try。

構造catch子句的目的是解決異常情況并且像錯誤沒有發生一樣繼續運作。例如,下面的程式中,每一個for循環的反複得到兩個随機整數。這兩個整數分别被對方除,結果用來除12345。最後的結果存在a中。如果一個除法操作導緻被零除錯誤,它将被捕獲,a的值設為零,程式繼續運作。

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

// Handle an exception and move on.

import

java.util.Random;

class

HandleError {

public

static

void

main(String args[]) {

int

a=

, b=

, c=

;

Random r =

new

Random();

for

(

int

i=

; i<

32000

; i++) {

try

{

b = r.nextInt();

c = r.nextInt();

a =

12345

/ (b/c);

}

catch

(ArithmeticException e) {

System.out.println(

"Division by zero."

);

a =

;

// set a to zero and continue

}

System.out.println(

"a: "

+ a);

}

}

}

顯示一個異常的描述

Throwable重載toString( )方法(由Object定義),是以它傳回一個包含異常描述的字元串。你可以通過在println( )中傳給異常一個參數來顯示該異常的描述。例如,前面程式的catch塊可以被重寫成

?

1 2 3 4

catch

(ArithmeticException e) {

System.out.println(

"Exception: "

+ e);

a =

;

// set a to zero and continue

}

當這個版本代替原程式中的版本,程式在标準javaJDK解釋器下運作,每一個被零除錯誤顯示下面的消息:

?

1

Exception: java.lang.ArithmeticException: / by zero

盡管在上下文中沒有特殊的值,顯示一個異常描述的能力在其他情況下是很有價值的——特别是當你對異常進行實驗和調試時。

Java 多重catch語句的使用

某些情況,由單個代碼段可能引起多個異常。處理這種情況,你可以定義兩個或更多的catch子句,每個子句捕獲一種類型的異常。當異常被引發時,每一個catch子句被依次檢查,第一個比對異常類型的子句執行。當一個catch語句執行以後,其他的子句被旁路,執行從try/catch塊以後的代碼開始繼續。下面的例子設計了兩種不同的異常類型:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

// Demonstrate multiple catch statements.

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(

"Divide by 0: "

+ e);

}

catch

(ArrayIndexOutOfBoundsException e) {

System.out.println(

"Array index oob: "

+ e);

}

System.out.println(

"After try/catch blocks."

);

}

}

該程式在沒有指令行參數的起始條件下運作導緻被零除異常,因為a為0。如果你提供一個指令行參數,它将幸免于難,把a設成大于零的數值。但是它将導緻ArrayIndexOutOf BoundsException異常,因為整型數組c的長度為1,而程式試圖給c[42]指派。

下面是運作在兩種不同情況下程式的輸出:

?

1 2 3 4 5 6

C:\>java MultiCatch

a = 0

Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks.

C:\>java MultiCatch TestArg

a = 1

Array index oob: java.lang.ArrayIndexOutOfBoundsException After try/catch blocks.

當你用多catch語句時,記住異常子類必須在它們任何父類之前使用是很重要的。這是因為運用父類的catch語句将捕獲該類型及其所有子類類型的異常。這樣,如果子類在父類後面,子類将永遠不會到達。而且,Java中不能到達的代碼是一個錯誤。例如,考慮下面的程式:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

class SuperSubCatch {

public static void main(String args[]) {

try {

int a = 0;

int b = 42 / a;

} catch(Exception e) {

System.out.println("Generic Exception catch.");

}

catch

(ArithmeticException e) {

// ERROR - unreachable

System.out.println(

"This is never reached."

);

}

}

}

如果你試着編譯該程式,你會收到一個錯誤消息,該錯誤消息說明第二個catch語句不會到達,因為該異常已經被捕獲。因為ArithmeticException 是Exception的子類,第一個catch語句将處理所有的面向Exception的錯誤,包括ArithmeticException。這意味着第二個catch語句永遠不會執行。為修改程式,颠倒兩個catch語句的次序。

繼續閱讀