2013-10-03 12 views
23

これは私にとって非常に奇妙です。 RuntimeExceptionはを継承するExceptionを継承します。例外をキャッチしてRuntimeExceptionをキャッチしないのはなぜですか?

catch(Exception exc) { /* won't catch RuntimeException */ 

しかし

catch(Throwable exc) { /* will catch RuntimeException */ 

私はそれが未チェックだという点でRuntimeExceptionが特別であることを知っています。しかし、私の理解には、例外が宣言されなければならないかどうかだけでなく、彼らが捕らえられているかどうかにも当てはまります。そして、それでも、私はこのロジックがThrowableを捕まえることでなぜ破壊されるのか分かりません。

ターミナル操作でRuntimeExceptionsがスローされる可能性があるので、これは私にとってはかなり関係しています。私はこのパターンの名前はわかりませんが、私のクラスEmailRollerCallbacksの配列をとります。コードは次のようになります。

for(Callback cb : callbacks) { 
    try { 
     cb.call(item); 
    } 
    catch(Exception exc) { 
     logger.error("Error in callback: ", exc); 
    } 
} 

だから、これはOOMEのようなものは、これらのコールバックのいずれかが、すべてのマシンのメモリを消費している場合ので、フライスルーする必要がある場合は、その確認などheckがの実行に影響を与えるために起こっている、あります他のもの。しかし、NullPointerException?またはIndexOutOfBoundsException?これらはコールバックに影響しますが、他のコールが実行されるのを妨げません。

また、これはエンタープライズデザインのビットです。異なるプログラマやチームがコールバックを追加してアイテムを処理することはできますが、それらは互いに分離する必要があります。これは、これらのコールバックを互いに絶縁する役割を担うプログラマとして、エラーが伝播しないようにすることを頼りにするべきではないということです。キャッチExceptionは正しい行に近いはずですが、RuntimeExceptionがスリップするためではありません。ですから、私のより一般的な質問は、ここで良いパターンは何ですか?ちょうどcatch(Exception | RuntimeException exc)、私はそれが継承のために構文エラーであると信じていますか?

答えて

81

キャッチExceptionキャッチRuntimeExceptionのため、前提が間違っています。デモコード:

public class Test { 
    public static void main(String[] args) { 
     try { 
      throw new RuntimeException("Bang"); 
     } catch (Exception e) { 
      System.out.println("I caught: " + e); 
     } 
    } 
} 

出力:

  • callbacksがループの実行中に
  • 何かがcallbacksを変更nullであることがあった場合(次の場合

    I caught: java.lang.RuntimeException: Bang 
    

    あなたのループが問題を持っていますコレクションではなく配列)

おそらくそれはあなたが見ているものですか?

+2

私のコードを再読み込みしてください。そのとおりです。私の絶縁層はバグだった。ランタイム例外はNPEだった 'if(results.foo.bar()){/ * apply callback * /}'から来たからだ。 – djechlin

+6

@djechlin:あなたの投稿は* show * 'if(results.foo.bar())'を表示しません - あなたが実際にこの時点で尋ねていることは非常に不明です... –

18
catch (Exception ex) { ... } 

WILLキャッチのRuntimeException。

あなたがキャッチブロックに入れたものは、そのサブクラスと同様に捕捉されます。

7

RuntimeException

2

私は同様のシナリオに直面してキャッチしますExceptionをキャッチ。classAの初期化はclassBの初期化に依存していたために起こっていました。 classBの静的ブロックがランタイム例外に直面した場合、classBは初期化されませんでした。このため、classBは例外をスローせず、classAの初期化も失敗しました。

class A{//this class will never be initialized because class B won't intialize 
    static{ 
    try{ 
     classB.someStaticMethod(); 
    }catch(Exception e){ 
     sysout("This comment will never be printed"); 
    } 
} 
} 

class B{//this class will never be initialized 
static{ 
    int i = 1/0;//throw run time exception 
} 

public static void someStaticMethod(){} 
} 

はい...キャッチするExceptionは実行時例外もキャッチします。

関連する問題