2011-01-29 5 views
0

何か例外が発生した場合には、初期化を行い、クリーンアップする必要があります。私はまだ呼び出し側に渡す例外が欲しいと思います。問題は、今ではこのメソッドをthrows Throwableと宣言してから、すべてのプロシージャが暗黙のうちにThrowableを投げていないかのように、呼び出し側でこのthrowableを明示的に処理する必要があることです。愚かではないですか?クリーンアップを実行して呼び出し元に例外を渡す

これを行う1つの方法は、最終的には代わりにブロックでクリーンアップを実行することである

try { 
    init_step1(); 
    init_step2(); 
} 
catch (Throwable th) { 
    clean(); 
    throw th; 
} 

答えて

1

、あなたが実際にtryブロックの最後になったかどうかによって例外があったのかどうか気付い:

boolean success = false; 
try { 
    // Stuff here 
    success = true; 
} finally { 
    if (!success) { 
     clean(); 
    } 
} 
0

Stupidはチェック例外と戦っています。すべての呼び出し元に処理を要求したくない場合は、別のものを投げる必要があります。 RuntimeExceptionをスローするだけです

public void myMethod() throws RuntimeException { 
    try { 
     init_step1(); 
     init_step2(); 
    } 
    catch (Throwable th) { 
     clean(); 
     throw new RuntimeException(th); 
    } 
} 

どうして最初にThrowableをキャッチしますか? init_step1()とinit_step2()は例外をスローしませんか?

+0

init_step1()とinit_step2()がThrowableをスローする可能性があり、データの一貫性を確保する必要があります。私は呼び出し側にチェックされた例外だけを処理させたい。そういうわけで彼らは彼らを「点検」と呼んでいるのですか? – milan

+0

Ok init_step1()とinit_step2()はThrowableをスローします。これで呼び出し元にスローしたいのですが、何ですか? – Mauricio

+0

Exceptionクラスを拡張する例外のみ。それは言語が一般的にどのように機能するかです。 – milan

0

@Jon Skeetのソリューションは最もクリーンです。あなたに興味のある別の解決策。

try { 
    // Stuff here 
} catch(Throwable t) { 
    clean(t); 
    // bypasses the compiler check 
    Thread.currentThread().stop(t); 
} 

スローされた例外を知る必要がある場合は、この方法を使用することをお勧めします。例えばクローズ可能なリソースについては、クローズを引き起こした例外を記録します。リソースを使用しようとすると、リソースが閉じられた理由がわかります。

private void checkClosed() { 
    if (closed) 
     throw new IllegalStateException("Closed", reasonClosed); 
} 
関連する問題