<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## [異常限制](https://lingcoder.gitee.io/onjava8/#/book/15-Exceptions?id=%e5%bc%82%e5%b8%b8%e9%99%90%e5%88%b6) 當覆蓋方法的時候,只能拋出在基類方法的異常說明里列出的那些異常。這個限制很有用,因為這意味著與基類一起工作的代碼,也能和導出類一起正常工作(這是面向對象的基本概念),異常也不例外。 下面例子演示了這種(在編譯時)施加在異常上面的限制: ~~~ // exceptions/StormyInning.java // Overridden methods can throw only the exceptions // specified in their base-class versions, or exceptions // derived from the base-class exceptions class BaseballException extends Exception {} class Foul extends BaseballException {} class Strike extends BaseballException {} abstract class Inning { Inning() throws BaseballException {} public void event() throws BaseballException { // Doesn't actually have to throw anything } public abstract void atBat() throws Strike, Foul; public void walk() {} // Throws no checked exceptions } class StormException extends Exception {} class RainedOut extends StormException {} class PopFoul extends Foul {} interface Storm { void event() throws RainedOut; void rainHard() throws RainedOut; } public class StormyInning extends Inning implements Storm { // OK to add new exceptions for constructors, but you // must deal with the base constructor exceptions: public StormyInning() throws RainedOut, BaseballException {} public StormyInning(String s) throws BaseballException {} // Regular methods must conform to base class: //- void walk() throws PopFoul {} //Compile error // Interface CANNOT add exceptions to existing // methods from the base class: //- public void event() throws RainedOut {} // If the method doesn't already exist in the // base class, the exception is OK: @Override public void rainHard() throws RainedOut {} // You can choose to not throw any exceptions, // even if the base version does: @Override public void event() {} // Overridden methods can throw inherited exceptions: @Override public void atBat() throws PopFoul {} public static void main(String[] args) { try { StormyInning si = new StormyInning(); si.atBat(); } catch(PopFoul e) { System.out.println("Pop foul"); } catch(RainedOut e) { System.out.println("Rained out"); } catch(BaseballException e) { System.out.println("Generic baseball exception"); } // Strike not thrown in derived version. try { // What happens if you upcast? Inning i = new StormyInning(); i.atBat(); // You must catch the exceptions from the // base-class version of the method: } catch(Strike e) { System.out.println("Strike"); } catch(Foul e) { System.out.println("Foul"); } catch(RainedOut e) { System.out.println("Rained out"); } catch(BaseballException e) { System.out.println("Generic baseball exception"); } } } ~~~ 在 Inning 類中,可以看到構造器和 event() 方法都聲明將拋出異常,但實際上沒有拋出。這種方式使你能強制用戶去捕獲可能在覆蓋后的 event() 版本中增加的異常,所以它很合理。這對于抽象方法同樣成立,比如 atBat()。 接口 Storm 包含了一個在 Inning 中定義的方法 event() 和一個不在 Inning 中定義的方法 rainHard()。這兩個方法都拋出新的異常 RainedOut,如果 StormyInning 類在擴展 Inning 類的同時又實現了 Storm 接口,那么 Storm 里的 event() 方法就不能改變在 Inning 中的 event() 方法的異常接口。否則的話,在使用基類的時候就不能判斷是否捕獲了正確的異常,所以這也很合理。當然,如果接口里定義的方法不是來自于基類,比如 rainHard(),那么此方法拋出什么樣的異常都沒有問題。 異常限制對構造器不起作用。你會發現 StormyInning 的構造器可以拋出任何異常,而不必理會基類構造器所拋出的異常。然而,因為基類構造器必須以這樣或那樣的方式被調用(這里默認構造器將自動被調用),派生類構造器的異常說明必須包含基類構造器的異常說明。 派生類構造器不能捕獲基類構造器拋出的異常。 StormyInning.walk() 不能通過編譯是因為它拋出了一個 Inning.walk() 中沒有聲明的異常。如果編譯器允許這么做的話,就可以編寫調用Inning.walk()卻不處理任何異常的代碼。 但是當使用`Inning`派生類的對象時,就會拋出異常,從而導致程序出現問題。通過強制派生類遵守基類方法的異常說明,對象的可替換性得到了保證。 覆蓋后的 event() 方法表明,派生類版的方法可以不拋出任何異常,即使基類版的方法拋出了異常。因為這樣做不會破壞那些假定基類版的方法會拋出異常的代碼。類似的情況出現在`atBat()`上,它拋出的異常`PopFoul`是由基類版`atBat()`拋出的`Foul`異常派生而來。如果你寫的代碼同`Inning`一起工作,并且調用了`atBat()`的話,那么肯定能捕獲`Foul`。又因為`PopFoul`是由`Foul`派生而來,因此異常處理程序也能捕獲`PopFoul`。 最后一個有趣的地方在`main()`。如果處理的剛好是 Stormylnning 對象的話,編譯器只要求捕獲這個類所拋出的異常。但是如果將它向上轉型成基類型,那么編譯器就會準確地要求捕獲基類的異常。所有這些限制都是為了能產生更為健壯的異常處理代碼。 盡管在繼承過程中,編譯器會對異常說明做強制要求,但異常說明本身并不屬于方法類型的一部分,方法類型是由方法的名字與參數的類型組成的。因此,不能基于異常說明來重載方法。此外,一個出現在基類方法的異常說明中的異常,不一定會出現在派生類方法的異常說明里。這點同繼承的規則明顯不同,在繼承中,基類的方法必須出現在派生類里,換句話說,在繼承和覆蓋的過程中,某個特定方法的“異常說明的接口”不是變大了而是變小了——這恰好和類接口在繼承時的情形相反。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看