我當初學java異常處理的時候,對于父子異常的處理,我記得幾句話“子類方法只能拋出父類方法所拋出的異常或者是其子異常,子類構造器必須要拋出父類構造器的異常或者其父異常”。那個時候還不知道子類方法為什么要這樣子拋出異常,后來通過學習《Thinking in Java》,我才明白其中的道理,現在我再來溫習一下。
一、子類方法只能拋出父類方法的異常或者是其子異常
對于這種限制,主要是因為子類在做向上轉型的時候,不能正確地捕獲異常
1
2
3
4
5
6
7
8
9
10
|
package thinkinginjava; public abstract class InningDemo1 { public void walk() throws BaseException{} public abstract void sing() throws BaseException; } class BaseException extends Exception{} class SubException1 extends BaseException{} class CupException extends Exception{} |
1
2
3
4
5
|
package thinkinginjava; public interface OtherFunction { public void task() throws RuntimeException; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package thinkinginjava; public class SubInningDemo1 extends InningDemo1 implements OtherFunction{ //子類方法可以拋出父類方法的異常 @Override public void walk() throws BaseException{} //但不能拋出父類中沒有的異常,否則編譯會出錯 //public void walk() throws Exception{} //子類方法可以拋出父類方法的子異常 @Override public void sing() throws SubException1{} //當實現的接口和父類中的方法都有異常時,可以選擇不拋出異常 public void task(){} } |
就拿這個例子來說,假如子類中有這方法 public void walk() throws CupException{},拋出了父類方法沒有的異常,我們使用父類的引用指向子類
1
2
3
4
5
6
7
|
public void f(){ InningDemo1 inn = new SubInningDemo1(); inn.walk() ; //父類調用walk()方法時,并不知道它會拋出CupException,從而f()方法不知如何捕獲異常。因此在編譯期就要防止子類方法亂拋異常。 } |
從上面的例子中,我們也可以看到,子類方法可以不拋出異常
二、子類構造器必須要拋出父類構造器的異常或者其父異常
這是因為子類構造器中默認添加了父類的構造器
1
2
3
4
5
6
7
8
9
10
11
|
package thinkinginjava; public abstract class InningDemo2 { public InningDemo2() throws SubException{ } } class FatherException extends Exception{} class SubException extends FatherException{} class PenException extends Exception{} |
1
2
3
4
5
6
7
8
|
package thinkinginjava; public class SubInningDemo2 extends InningDemo2{ public SubInningDemo2() throws FatherException { //子類構造器中默認添加了父類的構造器,所以需要拋出父類的異常或者其父異常 //super(); } } |
三、異常丟失
1、在finally中拋出異常,可能會之前拋出的異常丟失
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package thinkinginjava; public class FinallyException { public static void main(String[] args){ try { try { throw new RedException(); } finally { //把上一個異常覆蓋掉 throw new BlueException(); } } catch (Exception e){ System.out.println(e); } } } class RedException extends Exception{} class BlueException extends Exception{} |
運行結果:thinkinginjava.BlueException
2、在finally中使用return,不會拋出異常
1
2
3
4
5
6
7
8
9
10
11
|
package thinkinginjava; public class ReturnException { public static void main(String[] args){ try { throw new Exception(); } finally { return ; } } } |
以上代碼我們看到它拋出了異常,但運行時不會有任何輸出
以上這篇淺談java異常處理(父子異常的處理)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。