24   例外處理(Exception handling)-2

[24-1內建例外處理類別的訊息]

[getMessage()方法]

內建例外處理類別的簡單訊息可經由個別例外類別的getMessage()方法取得。getMessage()方法只取得訊息,可以System.out.println等顯示。

[]

public class GetMsg1{

  public static void main(String[] args){

    try{

        int[] box = {10,20,30};

        int a = box[1];

        System.out.println("a的整數值為"+a);

        int b = box[3];

        System.out.println("b的整數值為"+b);

       }

    catch(IndexOutOfBoundsException e1){

     System.out.println("e1例外訊息:"+e1.getMessage());

       }

    catch(Exception e2){

        System.out.println("e2例外訊息:"+e2. getMessage());

       }

    finally{

        System.out.println("GetMsg1程式結束");

       }

  }

}

執行結果:C:\js>java GetMsg1

a的整數值為20

e1例外訊息:3

GetMsg1程式結束

 

由上述e1.getMssage方法顯示的訊息僅為"3",即指造成錯誤之陣列指標超過0123,太過於簡略。 

 

[printStackTrace(System.out)方法]

內建例外處理類別的詳細訊息可經由個別例外類別的printStackTrace(System.out)方法取得。printStackTrace(System.out)方法可直接顯示,不須使用System.out.println等。

[]

public class GetMsg2{

  public static void main(String[] args){

    try{

        int[] box = {10,20,30};

        int a = box[1];

        System.out.println("GetMsg2a的整數值為"+a);

        int b = box[3];

        System.out.println("GetMsg2b的整數值為"+b);

       }

    catch(IndexOutOfBoundsException e1){

      e1.printStackTrace(System.out));

       }

    catch(Exception e2){

        e2.printStackTrace(System.out));

       }

    finally{

        System.out.println("GetMsg2程式結束");

       }

  }

}

執行結果:C:\js>java GetMsg2

GetMsg2a的整數值為20

java.lang.ArrayIndexOutOfBoundsException: 3

        at GetMsg2.main(GetMsg2.java:7)

GetMsg2程式結束

 

printStackTrace(System.out)方法可顯示較詳細、可讀之訊息。 

 

 

[24-2自訂例外處理類別的訊息]

經由throw可自訂例外訊息,即透過內建例外處理類別自訂顯示訊息。

[]未指定訊息

import java.io.*;

import java.lang.*;

class MainException6 {

  public static void main(String args[]) {

    try{

        int m=0, n=0 ;       

        if(n == 0){

        ArithmeticException e = new ArithmeticException ();

        throw e;

        //或合併為 throw new ArithmeticException ()

        }

        m = 100/n;

       }

    catch(ArithmeticException e) {

      System.out.println(e.getMessage());

    }

  }

}

執行結果:C:\js>java MainException6

null

 

因未指定訊息,尚未發生例外前由throw丟出例外,故其訊息為null

 

 

[]給定訊息

import java.io.*;

import java.lang.*;

class MainException7 {

  public static void main(String args[]) {

    try{

        int m=0, n=0 ;       

        if(n == 0){

        ArithmeticException e = new ArithmeticException ("錯誤:除數為0");

        throw e;

        //或合併為 throw new ArithmeticException ("錯誤:除數為0")

        }

        m = 100/n;

       }

    catch(ArithmeticException e) {

      System.out.println(e.getMessage());

    }

  }

}

執行結果:C:\js>java MainException7

錯誤:除數為0

 

 

[24-3自訂例外處理類別]

經由內建處理類別的繼承,可自訂例外處理類別,也可以自訂顯示例外訊息。

[24-3-1自訂例外處理類別及固定格式訊息]

固定格式的自訂訊息,於繼承時確立訊息。

import java.lang.*;

class MyException extends ArithmeticException { //自訂例外處理類別

MyException() {

    super("MyException:除數為0");

    //執行父類別建構式並設定例外訊息

}

class MainException8 {

public static void main(String args[]) {

try{

int m=0, n=0;

      if(n == 0){

MyException e = new MyException ();

          throw e;

      }

          m = 100/n;

   }

catch(MyException e) {

      System.out.println(e.getMessage());

       }

   }

}

執行結果:C:\js>java MainException8

MyException:除數為0

 

[24-3-2自訂例外處理類別及彈性格式訊息]

自訂訊息,於建立物件時指定。

import java.lang.*;

class FlexException extends ArithmeticException {

FlexException(String msg) { //建立物件時可指定訊息

     super(msg);

  }

}

class MainException9 {

  public static void main(String args[]) {

    try{

        int m=0, n=0;

        if(n == 0) throw new FlexException("彈性格式:除數為0");

        m = 100/n;

   }

   catch(FlexException e) {

     System.out.println(e.getMessage());

   }

 }

}

執行結果:C:\js>java MainException9

彈性格式:除數為0

 

 

[24-4例外處理程式碼的所在]

系統或自行(throw)拋出的例外要在那一個類別的那一個方法內處理?

*由拋出例外的方法捕捉處理。

*由拋出例外的方法上層方法(即呼叫者,可為同類別或他類別)捕捉處理。

*如拋出例外的方法之上層方法沒捕捉處理,可再由上上層捕捉處理,如果一直往上都沒有捕捉處理,最後由JVM處理及拋出訊息。

 

[24-4-1同一方法內]

class Exception11{

  public static void main(String[] args){

    Exception21 E21 = new Exception21();

E21.emethod211(); }

}

class Exception21{

  public void emethod211(){

    emethod212();  }

  public void emethod212(){

   try{  int a=10, b=0, c=0;

        c=a/b;  }

   catch( ArithmeticException e){

       System.out.println(e.getMessage());  }

  }

}

執行結果:C:\js>java Exception11

/ by zero

 

[24-4-2上層(同類別他方法)]

class Exception12{

  public static void main(String[] args){

    Exception22 E22 = new Exception22();

E22.emethod221(); }

}

class Exception22{

  public void emethod221(){

   try{  emethod222();  }

   catch( ArithmeticException e){

       System.out.println(e.getMessage());  }

  }

  public void emethod222(){

    int a=10, b=0, c=0;

    c=a/b;  }

}

執行結果:C:\js>java Exception12

/ by zero

 

[24-4-3上層(他類別)]

class Exception13{

  public static void main(String[] args){

    Exception23 E23 = new Exception23();

try{ E23.emethod231();  }

catch( ArithmeticException e){

       System.out.println(e.getMessage());  }

  }

}

class Exception23{

  public void emethod231(){

    emethod232();  }

  public void emethod232(){

    int a=10, b=0, c=0;

    c=a/b;  }

}

執行結果:C:\js>java Exception13

/ by zero

 

[24-4-4 JVM(try/catch)]

class Exception14{

  public static void main(String[] args){

    Exception24 E24 = new Exception24();

E24.emethod241(); }

}

class Exception24{

  public void emethod241(){

    emethod242();  }

  public void emethod242(){

    int a=10, b=0, c=0;

    c=a/b;  }

}

執行結果:C:\js>java Exception14

Exception in thread "main" java.lang.ArithmeticException: / by zero

        at Exception24.emethod242(Exception14.java:11)

        at Exception24.emethod241(Exception14.java:8)

        at Exception14.main(Exception14.java:4)

JVM拋出之訊息和由getMessage()顯示之訊息不同。

 

[24-5由例外類別繼承體系的那一個類別捕捉處理]

Java系統內建例外處理類別繼承體系之父子類別關係如下表例,程式catch述句可撰寫相對應之類別來捕捉異常。

 

Java系統內建例外處理類別之父子類別關係表

 

T

h

r

o

w

a

b

l

e

(

)

Error

(處不處理

皆可)

VirtualMachineError

StackOverflowError

OutOfMemoryError

AssertionError

LinkageError

ExceptionInInitializerError

NoClassDefFoundError

E

x

c

e

p

t

i

o

n

Unchecked

Exception

(處不處理

皆可)

RuntimeException

ArithmeticException

NullPointerException

IllegalStateException

IndexOutOfBoundsException

ClassCastException

IllegalArgumentException

Checked

Exception

(須處理)

IOException

EOFException

FileNotFoundException

ClassNotFoundException

SQLException

InterruptedException

 

 

[24-5-1由例外類別本身捕捉處理]

例:設有一陣列包含5個元素,並由命令列輸入欲顯示內容之陣列元素。如命令列輸入之陣列元素超出陣列範圍,則顯示陣列元素n超出範圍!程式結束。,如輸入之陣列元素在陣列範圍內,則顯示陣列元素n = x程式結束。,其中n為由1開始之陣列元素次序值,x為第n個陣列元素內容。

import java.io.*;

public class Exception31 {

  public static void main(String args[]) {

    if (args.length != 1) {

      System.out.println("請輸入一個陣列元素次序值");

      System.exit(1);

      }

      int n = Integer.parseInt(args[0]);     

    try {

      int x[] = {3,6,9,12,15};

      System.out.println("陣列元素" + n + " = " + x[n-1] + "");

      }

    catch (ArrayIndexOutOfBoundsException ae) {

      System.out.println("Exception31陣列元素" + n + "超出範圍!");

      }

    finally {

      System.out.println("程式結束。");

      }

  }

}

執行結果:

C:\js>java Exception31 5

陣列元素5 = 15

程式結束。

 

C:\js>java Exception31 6

Exception31陣列元素6超出範圍!

程式結束。

 

C:\js>java Exception31

請輸入一個陣列元素次序值

 

[24-5-2由例外類別的父類別、祖父類別捕捉處理]

上例由其上一層例外處理類別" IndexOutOfBoundsException"來接收例外之範例如下:

import java.io.*;

public class Exception32 {

  public static void main(String args[]) {

    if (args.length != 1) {

      System.out.println("請輸入一個陣列元素次序值");

      System.exit(1);

      }

      int n = Integer.parseInt(args[0]);     

    try {

      int x[] = {3,6,9,12,15};

      System.out.println("陣列元素" + n + " = " + x[n-1] + "");

      }

    catch (IndexOutOfBoundsException ie) {

      System.out.println("Exception32陣列元素" + n + "超出範圍!");

      }

    finally {

     System.out.println("程式結束。");

      }

  }

}

執行結果:C:\js>java Exception32 7

Exception32陣列元素7超出範圍!

程式結束。

 

[24-5-3由繼承體系多個例外類別捕捉處理]

可以多個catch捕捉繼承體系上相對應之例外及錯誤:

下例以"RuntimeException""IndexOutOfBoundsException" "ArrayIndexOutOfBoundsException" 捕捉,但實際為"ArithmeticException",本例只能由其父類別"RuntimeException"捕捉。

class Exception33{

  public static void main(String[] args){

   try{  int a=10, b=0, c=0;

         c=a/b;  }

    catch(ArrayIndexOutOfBoundsException e1){

         System.out.println("e1" + e1.getMessage()); }

    catch(IndexOutOfBoundsException e2){

         System.out.println("e2" + e2.getMessage()); }

catch(RuntimeException e3){

         System.out.println("e3" + e3.getMessage()); }

  }

}

執行結果:C:\js>java Exception33

e3/ by zero

 

["Exception"例外類別處理]

如果沒有辦法知曉何種例外時,則可以例外類別(非錯誤類別)的最上位Exception總括處理,並以其方法(get.Message())取得訊息,如下例:

class Exception34{

  public static void main(String[] args){

   try{  int a=10, b=0, c=0;

         c=a/b;  }

    catch(Exception ex){

         System.out.println("ex" + ex.getMessage());

ex.printStackTrace(System.out);  }

  }

}

執行結果:C:\js>java Exception34

ex/ by zero

java.lang.ArithmeticException: / by zero

        at Exception34.main(Exception34.java:4)

 

arrow
arrow

    祈泊 發表在 痞客邦 留言(0) 人氣()