JAvaがtryとfinallyだけを使用してcatchを使用しない理由とシーン

1544 ワード

JDKコンカレントキットでは、AbstractExecutorService、すなわちtryとfinallyのみcatchがないなどの例外処理の多くが使用されています.
class X 
{
    private final ReentrantLock lock = new ReentrantLock();
    // ...
 
    public void m()
    {
	lock.lock();  // block until condition holds
	try 
	{
		// ... method body
	} finally
	{
		lock.unlock()
	}
     }
}

なぜこの構造を使うのですか?何のメリットがありますか?まず次のコードを見てください.
 public void testTryAndFinally(String name)
 {
        try
        {
            name.length();// NullPointerException
        }
        finally
        {
            System.out.println("aa");
        }
 }

null呼び出しメソッドを渡す実行結果は、コンソールでaaを印刷し、NullPointerExceptionを放出することです.すなわち、プログラムの実行フローは、まずtryブロックを実行し、異常が発生した後にfinallyブロックを実行し、最後に呼び出し者にtry中の異常を投げ出す.この実行結果はcatch異常プロセッサがないため、この方法は発生した異常を外部に放出するしかない.finallyがあるため、メソッドが例外を投げ出す前にfinallyコードブロックのクリーンアップを実行します.
 
このやり方のメリットは何ですか.testTryAndFinallyにとって、それは自分がしなければならないことをして、自分が処理できない異常を外に投げ出しました.呼び出し者にとっては,出現した異常を感知し,必要に応じて処理することができる.すなわち,この構造は職責の分離を実現し,異常処理(throw)と異常クリーンアップ(finally)のデカップリングを実現し,異なる方法を自分のすべきことに集中させる.
では、try-finallyはいつ、try-catch-finallyはいつ使いますか.これは、tryに現れる異常を方法自体が処理できるかどうかに依存することは明らかである.自分で処理できるなら、直接catchに住んで、方法の呼び出し者に投げつける必要はありません.自分がどう処理するか分からない場合は、異常を外に投げ出すべきで、呼び出し者に異常が発生したことを知らせることができる.すなわち,メソッドの署名にthrowsが現れる可能性があり,自分では処理できない異常を宣言するが,メソッド内部で自分のすべきことをする.これはExecutorService.invokeAny()のメソッドを参照して署名できます.
  T invokeAny(Collection extends Callable> tasks) throws InterruptedException, ExecutionException;