[Java] 9.2. 自訂異常

自訂您的異常,創造出代表你系統的異常狀態。

 

image/svg+xml9.2. ⾃訂異常 – Customize Exception 逗點( , ),定義建構式的多重異常狀況 class Person { private String id; private String name; private String gender; private int age; Person(){} int getAge() { if (gender == " 女⽣ " ) return 18 ; return age; } void setAge ( int newAge ) { if (newAge < 0 || newAge > 150 ) System.out.println( " 年齡必須介於 0~150 之間 " ); else age = newAge; } } class PersonException extends Exception { PersonException ( String errorMsg ){ super ( errorMsg ); } } 更完整的異常-年齡、姓名、 性別與⾝份證號異常類別 class AgeException extends PersonException { AgeException( String errorMsg){ super (errorMsg); } } class NameException extends PersonException { NameException( String errorMsg){ super (errorMsg); } } class GenderException extends PersonException { GenderException( String errorMsg){ super (errorMsg); } } class IDException extends PersonException { IDException( String errorMsg){ super (errorMsg); } } class Person { private String id; private String name; private String gender; private int age; Person(){} int getAge() { if (gender == " 女⽣ " ) return 18 ; return age; } void setAge ( int newAge) { if (newAge < 0 || newAge > 150 ) System.out.println( " 年齡必須介於 0~150 之間 " ); else age = newAge; } } class Person { private String id; private String name; private String gender; private int age; Person(){} int getAge() { if (gender == " 女⽣ " ) return 18 ; return age; } void setAge ( int newAge) throws AgeException { if (newAge < 0 || newAge > 150 ) throw new AgeException (" 年齡必須介於 0~150 之間 " ); else age = newAge; } } class Main { public static void main( String [] args) { Person p = new Person (); try { p.setAge ( 200 ); } catch ( AgeException e ){ System.out.println( e . getMessage ()); } } } 執⾏結果 年齡必須介於 0~150 之間。 class Person { private String id; private String name; private String gender; private int age; Person ( String pID, String pName , String pGender, int pAge) throws IDException , NameException , GenderException , AgeException { if (pID.trim().length() == 0 ) throw new IDException (" ⾝份證字號不可空⽩。 " ); if (pName.trim().length() == 0 ) throw new NameException (" 姓名不可空⽩。 " ); if (! (pGender.trim().equals( " 男⽣ " ) || pGender.trim().equals( " 女⽣ " ))) throw new GenderException (" 姓別以可是男⽣或女⽣。 " ); if (pAge < 0 || pAge > 150 ) throw new AgeException ( " 年齡必須介於 0~150 之間。 " ); } int getAge() { if (gender == " 女⽣ " ) return 18 ; return age; } void setAge( int newAge) throws AgeException { if (newAge < 0 || newAge > 150 ) throw new AgeException( " 年齡必須介於 0~150 之間 " ); else age = newAge; } } class Main { public static void main( String [] args) { try { Person p = new Person ( "K123456789" , "Jack" , " 男⽣ " , 20 ); } catch ( IDException e1){ System.out.println(e1.getMessage()); } catch ( NameException e2){ System.out.println(e2.getMessage()); } catch ( GenderException e3){ System.out.println(e3.getMessage()); } catch ( AgeException e4){ System.out.println(e4.getMessage()); } } } class Person { private String id; private String name; private String gender; private int age; // 略過⼀些程式 void setInfo ( String pID, String pName , String pGender, int pAge) throws IDException , NameException , GenderException , AgeException { if (pID.trim().length() == 0 ) throw new IDException( " ⾝份證字號不可控⽩。 " ); if (pName.trim().length() == 0 ) throw new NameException( " 姓名不可控⽩。 " ); if (! (pGender.trim().equals( " 男⽣ " ) || pGender.trim().equals( " 女⽣ " ))) throw new GenderException( " 姓別以可是男⽣或女⽣。 " ); if (pAge < 0 || pAge > 150 ) throw new AgeException( " 年齡必須介於 0~150 之間。 " ); } // 略過⼀些程式 } class Person { private String id; private String name; private String gender; private int age; Person ( String pID, String pName, String pGender , int pAge) throws PersonException { if (pID.trim().length() == 0 ) throw new IDException (" ⾝份證字號不可空⽩。 " ); if (pName.trim().length() == 0 ) throw new NameException (" 姓名不可空⽩。 " ); if (! (pGender.trim().equals( " 男⽣ " ) || pGender.trim().equals( 女⽣ " ))) throw new GenderException (" 姓別以可是男⽣或女⽣。 " ); if (pAge < 0 || pAge > 150 ) throw new AgeException ( " 年齡必須介於 0~150 之間。 " ); } int getAge() { if (gender == " 女⽣ " ) return 18 ; return age; } void setAge( int newAge) throws AgeException { if (newAge < 0 || newAge > 150 ) throw new AgeException( " 年齡必須介於 0~150 之間 " ); else age = newAge; } } class Main { public static void main( String [] args) { try { Person p = new Person ( "K123456789" , "Jack" , " Man " , 20 ); } catch ( PersonException e1 ){ System.out.println( e1 instanceof GenderException ); System.out.println(e1.getMessage()); } } } 執⾏結果 true 姓別必須是男⽣或女⽣。 J9_2_1 – Person.java 3. 其實 Exception 異常類別有個多載的建構式,可以為您設 定異常的⽂字訊息。若有透過 Exception 的建構式設定異常的 ⽂字訊息的話,則建出來的異常物件(例如⾃訂的 PersonExcepion ),可以透過 getMessage() ⽅法來取得異 常訊息,當然,取得的訊息可透過此異常的建構式,透過 super() 的⽅式,間接代入異常的訊息。 J9_2_2 – PersonExcep 6 on.java 1. 這是⼈員類別( Person )。 2. 這是年齡設值式( setAge() ),其會透過參數代入 預設定的年齡值,並限定年齡必須介於 0~150 之間。 3. 這時,若輸入的年齡並非介於 0~150 歲之間,則在年齡設定式 中,能否以異常的⽅式,拋出⼀個異常物件,以表現這個異常現象 呢?這樣我們就可以使⽤ try~catch 流程,控制這個異常了。 Obj 1. 這是專為⼈員類別( Person )打造的⼈ 員異常類別( PersonException )。只要 在不正當的操作⼈員類別的情況下,皆會使 ⽤到⼈員異常類別來表⽰操作異常的情況。 2. 注意,⾃訂的異常類別⾄少要繼承 Exception 異常類別,這樣⾃訂的異常類別 才能夠在 Java 的異常處理機制中使⽤。 J9_2_2 – AgeExcep 6 on.java J9_2_2 – NameExcep 6 on.java J9_2_2 – GenderExcep 6 on.java J9_2_2 – IDExcep 6 on.java 1. 年齡專⽤的異常類別,可繼承⾃⼈員異常類別 PersonException ),以進⾏⼈員細部異常的延伸。 2. 姓名專⽤的異常類別,繼承⾃⼈員異常類別,這也同時代表著, 我們將以異常類別的名稱,指出更細部的⼈員異常狀況。 3. 性別專⽤的異常類別,同樣繼承⾃⼈員異常類別。 4. ⾝份證字號專⽤的異常類別,也同樣繼承⾃⼈員異常 類別,以表⽰⼈員更細部的異常狀況。 J9_2_3 – Person.java 1. 這是⼈員類別( Person )。 2. 這是年齡設值式( setAge() ),此⽅法會限定年齡必須介於 0~150 之間。 3. 如何以拋出年齡異常物件( AgeException 來表⽰年齡必須介於 0~150 齡之間呢? Obj J9_2_4 – Person.java 1. 這是⼈員類別( Person )。 3. throws 關鍵字是加在⽅法的⼩括號( ( ) )與 ⼤括號( { } )之間的,⽤以描述此⽅法可能產⽣的 異常物件的型別。⽽在年齡設定式( setAge() )中 希望在年齡不介於 0~150 歲之間時,則產⽣年齡異 常類型的物件( AgeException )以表⽰設定年齡 的異常事件,這時就必須透過 throws 描述年齡異常 型別是有可能拋出的異常物件的型別。 2. 這是年齡設值式( setAge() ),此 ⽅法會限定年齡必須介於 0~150 之間。 4. 當年設定的年齡不介於 0~150 歲之間時,則透過 throw 關鍵字,將建立的年齡異常物件拋出⾄⽅法外,當然要能夠 成功拋出⽅法外,年齡設定式( setAge() )⼀定要使⽤ throws 為拋出的年齡異常物件開⼀個窗⼝(即異常型別需與 異常物件的型別相吻合),說明年齡異常型別的物件是可以 拋出⽅法外的。 J9_2_4 – Main.java 5. 建立⼈員物件( Person )。 6. 透可能發⽣異常的程式- p.setAge(200) try~catch 裝起來,以進⼀步的捕抓異常物件。 7. 刻意給予超出 0~150 的數值 200 ,以設定⼈員的年齡。 8. 因為年齡必須介於 0~150 之間,否則將會產⽣年 齡異常物件( AgeException ),當然這時就可以 catch 區塊指定捕抓年齡異常類別的物件。 9. 此列印的資訊,是在抓到異常後,透過 getMessge() 取得的異常訊息,告 訴我們 年齡必須介於 0~150 之間 ,如此即達到以 try~catch 流程控制的⽅ 式,控制年齡異常,記住,唯有透過流程控制,才有機會定義管理異常的流程。 J9_2_5 – Person.java J9_2_5 – Main.java 1. 這是⼈員類別( Person )。 2. 這是⼈員類別的建構式。 3. 建構式上有可以透過 throws 來拋出 說明可能拋出的異常物件的類別。 4. 以逗號( , )連結多個不同的異常類別,以表⽰此建構式有可能拋出上述所列的異常物 件,在此可能產⽣⾝份證字號異常( IDException )、姓名異常( NameException )、 性別異常( GenderException )與年齡異常( AgeException )。 5. 依照不同條件,來判斷是否拋出相對應的異常物件。 6. ⼈員類別的建構式,有可能發⽣異常,因此放在 try 區塊中。 7. 接著,在透過 catch 陳述並補抓可能發 ⽣在⼈員建構式的異常物件,即⾝份證字號 異常、姓名異常、性別異常與年齡異常。 J9_2_6 – Person.java 1. 這是⼈員類別( Person )。 2. 這是⼀個設定資訊⽅法( setInfo() ),其透過 throws 關鍵字定義可能產⽣的異常類型。 3. 同樣也可以使⽤逗號( , )連結多個不同的異常類別, 以表⽰此⽅法有可能拋出上述所列的異常物件。 J9_2_7 – Person.java J9_2_7 – Main.java 1. 這是⼈員類別( Person )。 2. 這是⼈員建構式。 3. 利⽤多型的原理,指定拋出的異常物件的型別為⼈員異常類別 PersonException )。這時不論拋出的異常物件是什麼類別,皆可以透過轉型 成⼈員異常物件的⽅式拋出⾄建構式外,⽽⾝份證字號異常( IDException )、姓 名異常( NameException )、性別異常( GenderException )與年齡異常 AgeException )皆繼承⾃⼈員異常類別,因此皆可透過多型的原理,轉型為⽗ 類別-⼈員異常型別後,拋出⾄建構式之外。 4. 建立⼈員物件。 5. 故意將姓別以英⽂ “Man” 的⽅式代入,這時 就會產⽣姓別異常物件 GenderException ),但因為⼈員建構式是 將姓別異常物件轉型成⼈員異常物件後拋出的, 因此只需要捕抓⼈員異常型別的物件即可。 6. 在此透過 instanceof 運算式判斷此異常物件是否擁有姓別異 常的型別。這個結果是 true ,因為拋出的異常物件確實是⼀個姓別 異常的物件,只是它暫時被轉型為⼈員異常型別的物件拋出⽽已。 真想為⼈員打造專屬的異常類別, 不知⾏不⾏? 繼承 Exception ,以打造⼈員異常類別 當年齡不在 0~150 的範圍內,如何產⽣⼀個異常事件, 並將年齡異常物件拋出呢? throws throw 為年齡設定式拋出年齡異常物件 1 1 throws+ 多型,以⽗類別概括所有異常狀況 逗點( , ),再定義⽅法的多重異常狀況 1 2 1 2

留言