標籤:
java中的異常涉及到父子類的問題,可以歸納為一句話:子類的建構函式拋出的異常必須包含父類的異常,子類的方法可以選擇拋出“範圍小於等於”父類的異常或不拋出異常。
1. 為什麼建構函式必須拋出包含父類的異常?
在《thingking in java》中有這麼一段話:
異常限制:當覆蓋方法時,只能拋出在基類方法的異常說明中列出的那些異常
異常限制對構造器不起作用,你會發現StormyInning的構造器可以拋出任何異常,而不必理會基類建構函式所拋出的異常。然而因為必須建構函式必須以這樣或那樣的方式被調用,子類建構函式的異常說明必須包含基類構造器的異常說明
這段話起初一開比較繞,但是嘻嘻看一遍就會明白:
首先,異常說明只針對覆蓋方法,而建構函式明顯不在這個範圍,所以子類建構函式可以拋出任何異常,而不用顧及父類建構函式所拋出的異常。但是在new 一個子類對象的時候,父類建構函式一定會被調用,所以子類建構函式調用的對應的父類建構函式所拋出的異常就必須考慮在內,此時又因為“子類建構函式無法捕獲父類建構函式所拋出的異常(後面會提)”,所以子類建構函式必須拋出這個異常。
class SomeException extends Exception{}class TheOtherException extends Exception{}class BaseC{public BaseC()throws SomeException{}public BaseC(int a)throws TheOtherException{}}class SubC extends BaseC{public SubC() throws SomeException //如果不拋出異常就會報錯{super(); //由於調用的基類的預設建構函式, 所以要拋出SomeException //super(37) ; //如果將super()替換成這裡,就必須拋出TheOtherException}}
2. 為什麼子類建構函式無法捕獲父類建構函式所拋出的異常?
因為子類如果想要捕獲父類拋出的異常,就必須顯示地調用super() ; 或者super(xxx...); 然而super()和this()這些都有一個特性, 就是必須將他們放在第一行, 這與try{}catch{}相矛盾, 所以無法捕獲
3. 當子類繼承的父類和介面存在相同的方法名時,這時的處理方式就必須遵循異常限制。
class SomeException extends Exception{}class TheOtherException extends Exception{}interface InterF{public void function()throws TheOtherException;}class BaseC{public void function()throws SomeException{}}class SubC extends BaseC implements InterF{//此時只能選擇不拋出異常public void function(){}//報錯:Exception SomeException is not compatible with throws clause in InterF.function()//public void function()throws SomeException{} ; //報錯:Exception TheOtherException is not compatible with throws clause in BaseC.function()// public void function()throws TheOtherException{} ;}
4. 為什麼子類只能拋出在基類方法的異常說明中列出的那些異常?
因為子類存在向上轉化成父類的可能性,如果允許子類隨意拋出異常的話,那麼向上轉化成父類時,該方法的介面(姑且這麼叫吧)會變成父類的方法類型,此時問題來了,子類會拋出異常,而父類卻無法對該異常做出處理,所以為保證對象的可替換型,強制要求“只能拋出在基類方法的異常說明中列出的那些異常”。
這裡所說的“那些異常”還包括這些異常的子異常!
5. 這一點不知道算不算,也許是我比較愚鈍吧,我在看的時候想了好久才明白過來,姑且記下來吧。
class SomeException extends Exception{}class BaseC{public void function()throws SomeException{}//如果這裡拋出的異常是一個運行時異常子類就可以不對其進行異常處理}class SubC extends BaseC{
//這兩個function()所進行的super.function()的都屬於正常的函數調用,不屬於異常處理的範圍, 但是這個函數本身要符合異常處理的規範!/*public void function()throws SomeException{super.function();}*/public void function(){try{super.function() ;}catch(SomeException e){e.printStackTrace();}}}
//thinking in java筆記,如果有不對的地方,還望指正^_^
java涉及父子類的異常