「キャッチ」なしで「トライ・ファイナリー」を行うことは意味がありますか?


127

私はこのようなコードを見ました:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

try持っているはずだと思いましたcatch

なぜこのコードはこのようにするのですか?


1
特にファイルハンドルfopenまたはDB接続(PHPでも)に関して、他の応答が言及したようにクリーンアップを確実にします
MediaVince

回答:


182

これは、現在実行中のメソッドが例外をスローする一方で、リソースを適切にクリーンアップできるようにする場合に役立ちます。以下は、呼び出しメソッドからの例外を処理する具体的な例です。

public void yourOtherMethod() {
    try {
        yourMethod();
    } catch (YourException ex) {
        // handle exception
    }
}    

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}

17
次のように、ロックで一般的に使用されます。lock.lock(); {/ * locked * /}を試してください最後に{lock.unlock()}
mins

最終的に内部で例外がスローされた場合はどうなりますか?
バース

1
@barth catchブロックがない場合、スローfinallyされた例外は、tryブロック内の例外の前に実行されます。2つの例外があるので、もし1中tryとの1 finallyスローされる唯一の例外は1つですfinally。これらの言語では両方の例外が同時にスローされ、例外の順序がtry最初であるので、この動作はPHPとPythonで同じではありませんfinally

72

これdb.cleanup()は、tryブロック内のコードが例外をスローした場合でも、プログラマがそれを確実に呼び出す必要があるためです。例外はそのブロックでは処理されませんが、finallyブロックが実行された後にのみ、上向きに伝播されます。


23
+1その通り。try許可するようにそこにありますfinally。例外はキャッチされません。
zockman

2
+1は、例外がキャッチされるまで、スタックがスタックを上っていくことを明確にします。おかげで
コードジョッキー

20

なぜこのコードはこのようにするのですか?

どうやらコードはこのレベルで例外を処理する方法を知らないからです。それはいいですません。呼び出し元の1人が行う限り、つまり例外が最終的にどこかで処理される限りです。

多くの場合、ユーザーに通知する必要があるか、例外をログに記録する必要があるか、別の戦略を試す必要があるため、低レベルのコードは例外に適切に対応できません。低レベルのコードは1つを実行します機能のみを、高レベルの意思決定については認識しません。

ただし、コードは引き続きリソースをクリーンアップする必要があります(クリーンアップしないとリソースがリークするため)。そのため、finally節でそれを実行し、例外がスローされたかどうかに関係なく、常に発生するようにします。


2

finallyブロックは、RuntimeExceptionがスローされた場合でも(呼び出されたコードのバグが原因である可能性があります)、db.cleanup()呼び出しが行われるようにします。

これは、ネストが多すぎないようにするためにもよく使用されます。

try
{
    if (foo) return false;
    //bla ...
    return true;
}
finally
{
    //clean up
}

特に、メソッドが戻るポイントが多い場合は、すべての場合にクリーンアップコードが呼び出されるのを誰でも確認できるため、これにより読みやすさが向上します。


0

コードは、データベースが確実に閉じられるようにしています。
通常は、データベースにアクセスするすべてのコードをtryブロックに配置し、データベースを閉じるための呼び出しをfinallyブロックに配置します。
try ... finallyが機能する方法とは、tryブロックのコードが実行され、finallyブロックのコードがそれが終了したときに実行されることを意味します。
コンピュータが壁から引っ張られる前に、finallyが実行されます。
これは、例外が呼び出され、メソッドの実行に3年かかる場合でも、最終的にブロックされ、データベースが閉じられることを意味します。


0

tryブロックのコードのいずれかがチェック済み例外をスローできる場合は、メソッドシグネチャのthrows句に表示する必要があります。未チェックの例外がスローされると、メソッドからバブリングされます。

例外がスローされたかどうかにかかわらず、finallyブロックは常に実行されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.