私はいくつかの新しいコードをレビューしています。プログラムには、tryとfinallyブロックのみがあります。catchブロックは除外されているので、例外やスロー可能なものが発生した場合、tryブロックはどのように機能しますか?それはfinallyブロックに直接行くだけですか?
11 に答える
tryブロック内のコードのいずれかがチェックされた例外をスローできる場合、それはメソッドシグネチャのthrows句に表示される必要があります。チェックされていない例外がスローされた場合、メソッドからバブルアウトされます。
例外がスローされるかどうかに関係なく、finallyブロックは常に実行されます。
try
/に関する小さなメモfinally
:finallyは、次の場合を除いて常に実行されます
System.exit()
と呼ばれます。- JVMがクラッシュします。
- ブロックは
try{}
決して終了しません(たとえば、エンドレスループ)。
Java言語仕様(1)は、実行方法を説明していますtry-catch-finally
。キャッチがないことは、与えられたスローアブルをキャッチできるキャッチがないことと同じです。
- 値Vがスローされたために、tryブロックの実行が突然完了した場合は、次の選択肢があります。
- 実行時型Vがtryステートメントのcatch句のパラメーターに割り当て可能である場合、…<br>…
- 実行時型Vがtryステートメントのcatch句のパラメーターに割り当てられない場合、finallyブロックが実行されます。次に、選択肢があります。
- finallyブロックが正常に完了すると、値Vがスローされたため、tryステートメントが突然完了します。
- finallyブロックが理由Sで突然完了した場合、tryステートメントは理由Sで突然完了します(値Vのスローは破棄され、忘れられます)。
例外を外部ブロックにスローする前に、内部が最終的に実行されます。
public class TryCatchFinally {
public static void main(String[] args) throws Exception {
try{
System.out.println('A');
try{
System.out.println('B');
throw new Exception("threw exception in B");
}
finally
{
System.out.println('X');
}
//any code here in the first try block
//is unreachable if an exception occurs in the second try block
}
catch(Exception e)
{
System.out.println('Y');
}
finally
{
System.out.println('Z');
}
}
}
結果は
A
B
X
Y
Z
finallyブロックは、tryブロックが終了した後に常に実行されます。これは、tryが正常に終了したか、例外が原因で異常に終了したかを問わず、スロー可能です。
tryブロック内のいずれかのコードによって例外がスローされた場合、現在のメソッドは(finallyブロックを実行した後)同じ例外を単に再スローします(またはスローし続けます)。
finallyブロックが例外/エラー/スロー可能をスローし、保留中のスロー可能がすでに存在する場合、それは醜くなります。率直に言って、私は何が起こっているのかを正確に忘れています(何年も前の私の認定についてはそうです)。両方のスローアブルがリンクされていると思いますが、「最後に」バーフされて投げられる前に元の問題を取得するために、あなたがしなければならない特別なブードゥーがいくつかあります(つまり、私が調べなければならないメソッド呼び出し)。
ちなみに、Javaにはデストラクタがないため、try/finallyはリソース管理で行うのがかなり一般的なことです。
例-
r = new LeakyThing();
try { useResource( r); }
finally { r.release(); } // close, destroy, etc
「最後に」、もう1つのヒント:わざわざキャッチを入れる場合は、特定の(予想される)スロー可能なサブクラスをキャッチするか、一般的なキャッチオールエラートラップとして「例外」ではなく「スロー可能」をキャッチします。リフレクショングーフなどの問題が多すぎると、「例外」ではなく「エラー」がスローされ、次のようにコード化された「すべてをキャッチ」することで問題が発生します。
catch ( Exception e) ... // doesn't really catch *all*, eh?
代わりにこれを行います:
catch ( Throwable t) ...
バージョン7より前のJavaバージョンでは、try-catch-finallyのこれら3つの組み合わせが可能です...
try - catch
try - catch - finally
try - finally
finally
try
or / andブロックで何が起こっているかに関係なく、ブロックは常に実行されcatch
ます。したがって、catch
ブロックがない場合、例外はここでは処理されません。
ただし、もちろんアプリケーションを完全にクラッシュさせたくない場合を除いて、コードのどこかに例外ハンドラーが必要です。それは、そのハンドラーがどこにあるかを正確にアプリケーションのアーキテクチャーに依存します。
- Java tryブロックの後には、catchまたはfinallyブロックが続く必要があります。
- 各tryブロックには、0個以上のcatchブロックが存在する可能性がありますが、finallyブロックは1つだけです。
- プログラムが終了した場合(System.exit()を呼び出すか、プロセスを中止させる致命的なエラーが発生した場合)、finallyブロックは実行されません。
例外またはスロー可能なものが発生した場合、tryブロックはどのように機能しますか
例外は、キャッチされない他の場合と同様に、ブロックからスローされます。
finallyブロックは、tryブロックがどのように終了したかに関係なく、つまり、キャッチがまったくないかどうかに関係なく、一致するキャッチがあるかどうかに関係なく実行されます。
catchブロックとfinallyは、tryブロックの直交部分です。どちらかまたは両方を持つことができます。Java 7を使用すると、どちらも使用できなくなります。
あのプログラムでやってみませんか?finallyブロックに移動し、finallyブロックを実行しますが、例外は処理されません。ただし、finallyブロックでは、その例外を無効にすることができます。
試行ブロックが完了した後、finallyブロックが実行されます。tryブロック内に何かがスローされた場合、finallyブロックが実行されます。
ブロック内try
に、例外をスローできるコードを記述します。catch
ブロックは、例外を処理する場所です。finally
例外が発生したかどうかに関係なく、ブロックは常に実行されます。
これで、try-catch-finallyブロックの代わりにtry-finallyブロックがある場合、例外は処理されず、制御の代わりにtryブロックがcatchブロックに移動した後、finallyブロックに移動します。例外を除いて何もしたくない場合は、try-finallyブロックを使用できます。
ブロックで例外がスローされたかどうかに関係なく、try
ブロックfinally
が実行されます。例外はキャッチされません。