さいがくいじょう


キャプチャ異常処理
1.異常処理には2つの基本モードがあります.
  • 終了モード:このモデルでは、エラーが非常に重要であると仮定し、プログラムは異常が発生した場所に戻って実行を継続することができず、異常が投げ出されると、エラーが挽回できないことを示し、戻って実行を継続することもできない.(Javaおよびc++でサポートされているモデル)
  • リカバリモデル:例外ハンドラの動作は、エラーを修正し、問題が発生したメソッドを再試行し、2回目に成功すると考えられます.

  • カスタム例外の作成
    1.異常コードの例をログで関連付けることができます.
    class LoggingException extends Exception {
        //    Logger  
          private static Logger logger = Logger.getLogger("LoggingException");
          public LoggingException() {
            //     
            StringWriter trace = new StringWriter();
            //            
            printStackTrace(new PrintWriter(trace));
            //  server               
            logger.severe(trace.toString());
          }
        }
    
        public class LoggingExceptions {
          public static void main(String[] args) {
            try {
              throw new LoggingException();
            } catch(LoggingException e) {
              System.err.println("Caught " + e);
            }
            try {
              throw new LoggingException();
            } catch(LoggingException e) {
              System.err.println("Caught " + e);
            }
          }
        } 

    運行結果:2月26日、2015 9:28:23午後beyondboy.LoggingException重大:beyondboy.LoggingException at beyondboy.LoggingExceptions.main(LoggingExceptions.java:20)
    Caught beyondboy.LoggingException 2月26日、2015 9:28:25午後beyondboy.LoggingException重大:beyondboy.LoggingException at beyondboy.LoggingExceptions.main(LoggingExceptions.java:25)
    Caught beyondboy.LoggingException
    すべての例外を取得
    1.現在の例外オブジェクトのみを再放出する場合、printStackTrace()メソッドは、再放出ポイントの情報ではなく、元の例外放出ポイントの呼び出しスタック情報を表示します.この情報を更新するには、fillInStackTrace()メソッドを呼び出し、Throwableオブジェクトに戻ります.これは、現在の呼び出しスタック情報を元の異常オブジェクトに埋め込むことによって確立される(異常オブジェクトのinitCause()メソッドを使用して元の異常情報を保持することもできる).コード例:
    public class Rethrowing {
          public static void f() throws Exception {
            System.out.println("originating the exception in f()");
            throw new Exception("thrown from f()");
          }
          public static void g() throws Exception {
            try {
              f();
            } catch(Exception e) {
              System.out.println("Inside g(),e.printStackTrace()");
              e.printStackTrace(System.out);
              throw e;
            }
          }
          public static void h() throws Exception {
            try {
              f();
            } catch(Exception e) {
              System.out.println("Inside h(),e.printStackTrace()");
              e.printStackTrace(System.out);
              throw (Exception)e.fillInStackTrace();
            }
          }
          public static void main(String[] args) {
            try {
              g();
            } catch(Exception e) {
              System.out.println("main: printStackTrace()");
              e.printStackTrace(System.out);
            }
            try {
              h();
            } catch(Exception e) {
              System.out.println("main: printStackTrace()");
              e.printStackTrace(System.out);
            }
          }
        } 

    実行結果:originating the exception in f()Inside g(),e.printStackTrace()java.lang.Exception: thrown from f() at beyondboy.Rethrowing.f(Rethrowing.java:6) at beyondboy.Rethrowing.g(Rethrowing.java:10) at beyondboy.Rethrowing.main(Rethrowing.java:28) main: printStackTrace() java.lang.Exception: thrown from f() at beyondboy.Rethrowing.f(Rethrowing.java:6) at beyondboy.Rethrowing.g(Rethrowing.java:10) at beyondboy.Rethrowing.main(Rethrowing.java:28) originating the exception in f() Inside h(),e.printStackTrace() java.lang.Exception: thrown from f() at beyondboy.Rethrowing.f(Rethrowing.java:6) at beyondboy.Rethrowing.h(Rethrowing.java:19) at beyondboy.Rethrowing.main(Rethrowing.java:34) main: printStackTrace() java.lang.Exception: thrown from f() at beyondboy.Rethrowing.h(Rethrowing.java:23) at beyondboy.Rethrowing.main(Rethrowing.java:34) 2.異常をキャプチャした後に別の異常を投げ出すと、元の異常発生点に関する情報が失われ、残りは新しい投げ出し点に関する情報です.
    class OneException extends Exception {
      public OneException(String s) { super(s); }
    }
    
    class TwoException extends Exception {
      public TwoException(String s) { super(s); }
    }
    
    public class RethrowNew {
      public static void f() throws OneException {
        System.out.println("originating the exception in f()");
        throw new OneException("thrown from f()");
      }
      public static void main(String[] args) {
        try {
          try {
            f();
          } catch(OneException e) {
            System.out.println(
              "Caught in inner try, e.printStackTrace()");
            e.printStackTrace(System.out);
            throw new TwoException("from inner try");
          }
        } catch(TwoException e) {
          System.out.println(
            "Caught in outer try, e.printStackTrace()");
          e.printStackTrace(System.out);
        }
      }
    }

    実行結果:originating the exception in f()Caught in inner try,e.printStackTrace()beyondboy.OneException: thrown from f() at beyondboy.RethrowNew.f(RethrowNew.java:14) at beyondboy.RethrowNew.main(RethrowNew.java:19) Caught in outer try, e.printStackTrace() beyondboy.TwoException: from inner try at beyondboy.RethrowNew.main(RethrowNew.java:24)
    finallyによるクリーンアップ
    1.Javaの例外が例外が放出された場所に戻ることを許可しない場合、tryブロックを不良に戻すことができ、「プログラムが実行される前に達成しなければならない」という条件を確立することができます.コード例:
    class ThreeException extends Exception {}
    
    public class FinallyWorks {
      static int count = 0;
      public static void main(String[] args) {
        while(true) {
          try {
            if(count++ == 0)
              throw new ThreeException();
            System.out.println("No exception");
          } catch(ThreeException e) {
            System.out.println("ThreeException");
          } finally {
            System.out.println("In finally clause");
            //  while
            if(count == 2) break; 
          }
        }
      }
    }

    実行結果:ThreeException In finally clause No exception In finally clause 2.finallyが正しく使用されていないと、異常が失われやすくなります.コード例:
    class VeryImportantException extends Exception {
          public String toString() {
            return "A very important exception!";
          }
        }
    
        class HoHumException extends Exception {
          public String toString() {
            return "A trivial exception";
          }
        }
    
        public class LostMessage {
          void f() throws VeryImportantException {
            throw new VeryImportantException();
          }
          void dispose() throws HoHumException {
            throw new HoHumException();
          }
          public static void main(String[] args) {
            try {
              LostMessage lm = new LostMessage();
              try {
                lm.f();
              } finally {
                lm.dispose();
              }
            } catch(Exception e) {
              System.out.println(e);
            }
          }
        }

    実行結果:A trivial exception
    異常な制限
    1.オーバーライド方法の場合、ベースメソッドの異常説明に記載されているそれらの異常のみを放出することができ、派生クラスコンストラクタの異常説明はベースクラスコンストラクタの異常説明を含まなければならず、ベースクラスコンストラクタが放出した異常を捕獲することができず、派生クラスが放出異常のベースメソッドをオーバーライドしている場合、異常説明を持たなくてもよい.ただし、例外を投げ出さないベースクラスメソッドを上書きする場合は、例外の説明を付けてはいけません.コード例:
    class BaseballException extends Exception {}
    class Foul extends BaseballException {}
    class Strike extends BaseballException {}
    
    abstract class Inning {
      public Inning() throws BaseballException {}
      public void event() throws BaseballException {
    
      }
      public abstract void atBat() throws Strike, Foul;
      //            
      public void walk() {} 
    }
    
    class StormException extends Exception {}
    class RainedOut extends StormException {}
    class PopFoul extends Foul {}
    
    interface Storm {
      public void event() throws RainedOut;
      public void rainHard() throws RainedOut;
    }
    
    public class StormyInning extends Inning implements Storm {
     //          ,              
      public StormyInning()
        throws RainedOut, BaseballException {}
      public StormyInning(String s)
        throws Foul, BaseballException {}
      //               ,       
    //! void walk() throws PopFoul {}
      //                
    //! public void event() throws RainedOut {}
      //           
      public void rainHard() throws RainedOut {}
      //        
      public void event()  {}
      //                
      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");
        }
        try {
          //     
          Inning i = new StormyInning();
          i.atBat();
         //                    
        } 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");
        }
      }
    } 

    コンストラクタ
    1.物理リソースを閉じると、finallyは毎回クリーンアップコードを実行するため、コンストラクタが実行中に途中で停止した場合、オブジェクトの一部が正常に作成されていない可能性があります.これらの部分はfinally句でクリーンアップされます.これにより矛盾が発生します.コンストラクタに異常が投げ出された場合、クリーンアップする必要があるオブジェクトを作成した後、すぐにtry-finally文ブロックに入ります.コード例:
    class NeedsCleanup { 
            //           
          private static long counter = 1;
          private final long id = counter++;
          public void dispose() {
            System.out.println("NeedsCleanup " + id + " disposed");
          }
        }
    
        class ConstructionException extends Exception {}
    
        class NeedsCleanup2 extends NeedsCleanup {
          //             
          public NeedsCleanup2() throws ConstructionException {}
        }
    
        public class CleanupIdiom {
          public static void main(String[] args) {
            //                      
            NeedsCleanup nc1 = new NeedsCleanup();
            try {
            } finally {
              nc1.dispose();
            }
    
            //                      
            NeedsCleanup nc2 = new NeedsCleanup();
            NeedsCleanup nc3 = new NeedsCleanup();
            try {
              // ...
            } finally {
              nc3.dispose(); 
              nc2.dispose();
            }
    
            //                        
            try {
              NeedsCleanup2 nc4 = new NeedsCleanup2();
              try {
                NeedsCleanup2 nc5 = new NeedsCleanup2();
                try {
                  // ...
                } finally {
                  nc5.dispose();
                }
              } catch(ConstructionException e) { 
                System.out.println(e);
              } finally {
                nc4.dispose();
              }
            } catch(ConstructionException e) { 
              System.out.println(e);
            }
          }
        }

    実行結果:NeedsCleanup 1 disposed NeedsCleanup 3 disposed NeedsCleanup 2 disposed NeedsCleanup 5 disposed NeedsCleanup 4 disposed
    いじょうごう
    1.検査された異常を処理すると、コンパイラがエラーを処理する準備ができていない可能性がある場合にcatch文を追加するよう強制する可能性があります.「飲み込むと有害」という問題を引き起こす可能性があります.ここでは、異常チェーンの方法で検査異常を検査しない異常に変換することができます.コード例:
              
            wce.throwRuntimeException(3);
            //        
            for(int i = 0; i < 4; i++)
              try {
                if(i < 3)
                  wce.throwRuntimeException(i);
                else
                  throw new SomeOtherException();
              } catch(SomeOtherException e) {
                  System.out.println("SomeOtherException: " + e);
              } catch(RuntimeException re) {
                try {
                    //          
                  throw re.getCause();
                } catch(FileNotFoundException e) {
                    System.out.println("FileNotFoundException: " + e);
                } catch(IOException e) {
                    System.out.println("IOException: " + e);
                } catch(Throwable e) {
                    System.out.println("Throwable: " + e);
                }
              }
          }
        } 

    実行結果:FileNotFoundException:java.io.FileNotFoundException IOException: java.io.IOException Throwable: java.lang.RuntimeException: Where am I? SomeOtherException: beyondboy.SomeOtherException