JavaはCatchを使わずに最後にブロックする


125

新しいコードを確認しています。プログラムにはtryとfinallyブロックのみがあります。catchブロックが除外されているため、例外またはスロー可能な何かが発生した場合、tryブロックはどのように機能しますか?最終ブロックに直接移動しますか?



25
@mP誰もがコードレビューを行う必要があり、彼らに質問することは、学び、改善する方法です。
Carl Pritchett、2011年

回答:


130

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

例外がスローされてもされなくても、finallyブロックは常に実行されます。


11
最初の段落は必ずしも真実ではありません。入れ子にできるtryブロック。チェックされていないかどうかに関係なく、キャッチされない例外はメソッドからバブリングされます。
アンディトーマス

4
ブロックは入れ子にすることができますが、お勧めしません。私はそのようにコードを書きません。
duffymo 2010

2
@duffymo:「メソッドからバブリングされた」とはどういう意味ですか?
今日ILearned

5
@Anandは、「例外をスローする」ための少し非技術的な言語です。
duffymo 2015

2
無視されません。メソッドチェーンを渡します。
duffymo 2016年

93

try/ についての小さな注意finally:最終的には、

  • System.exit() と呼ばれます。
  • JVMがクラッシュします。
  • try{}ブロックは、(例えば無限ループ)を終了することはありません。

4
どうtry{..} catch{ throw ..} finally{..}ですか?最終的には実行されないと思います
sbeliakov '11 / 11/15

10
その場合、最終的にはまだ呼び出されます。元の例外のみが失われます。
Peter Lawrey、2015年

最後に、前にSystem.exit()を呼び出した場合も実行されません。
mmirror 2017年

2
@jyw上記のリストの最初の項目で私が意味したのはこれです。
Peter Lawrey

私は言わなければならない、これはすべての拠点をカバーしています!
オスカーブラボー

39

Java言語仕様(1)は、そのtry-catch-finally実行方法を説明しています。キャッチがないことは、指定されたThrowableをキャッチできるキャッチがないことと同じです。

  • 値Vがスローされたためにtryブロックの実行が突然完了した場合は、選択肢があります。
    • Vのランタイムタイプがtryステートメントのいずれかのcatch句のパラメーターに割り当て可能な場合、
      ……
    • Vの実行時の型がtryステートメントのいずれのcatch句のパラメーターにも割り当てられない場合、finallyブロックが実行されます。次に選択肢があります:
      • finallyブロックが正常に完了すると、値Vがスローされるため、tryステートメントが突然完了します。
      • finallyブロックが理由Sで突然完了した場合、tryステートメントは理由Sで突然完了します(値Vのスローは破棄され、忘れられます)。

(1)try-catch-finallyの実行


16

内側のfinallyは、外側のブロックに例外をスローする前に実行されます。

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

6

finallyブロックは、tryブロックが終了した後に必ず実行されます。tryが正常に終了したか、例外(スロー可能)により異常終了したかは関係ありません。

tryブロック内のいずれかのコードによって例外がスローされた場合、現在のメソッドは(finallyブロックの実行後に)同じ例外を再スローする(またはスローし続ける)だけです。

finallyブロックが例外/エラー/スロー可能オブジェクトをスローし、保留中のスロー可能オブジェクトがすでに存在する場合、醜くなります。率直に言って、私は何が起こるかを正確に忘れてしまいます(何年も前の私の認定にとっては)。私両方のスロー可能オブジェクトがリンクされると思いますが、「最終的に」バーフが落ちる前に元の問題を取得するには、特別なブードゥー(つまり、私が調べなければならないメソッド呼び出し)が必要です。

ちなみに、javaにはデストラクタがないため、try / finallyはリソース管理でかなり一般的なことです。

例-

r = new LeakyThing();
try { useResource( r); }
finally { r.release(); }  // close, destroy, etc

「最後に」、もう一つのヒント:あなたがあればないキャッチに置くためにわざわざ、どちらかのキャッチ特定の(予想)スロー可能オブジェクトのサブクラス、または単にキャッチ「のThrowable」、ではない一般的なキャッチすべてのエラーをトラップするための「例外」、。反射グーフなどの問題が多すぎると、「例外」ではなく「エラー」がスローされ、次のようにコード化された「catch all」で問題が発生します。

catch ( Exception e) ...  // doesn't really catch *all*, eh?

代わりにこれを行ってください:

catch ( Throwable t) ...

醜い部分については、以下のCarlos Heubergerの回答を参照してください。
mplwork 2013年

3

バージョン7より前のJavaバージョンでは、try-catch-finallyのこれら3つの組み合わせが可能です...

try - catch
try - catch - finally
try - finally

finallytryor / and catchブロックで何が行われているかに関係なく、ブロックは常に実行されます。したがって、catchブロックがない場合、例外はここでは処理されません。

ただし、アプリケーションを完全にクラッシュさせない限り、コードのどこかに例外ハンドラが必要です。これは、ハンドラーがどこにあるか、アプリケーションのアーキテクチャーに依存します。

  • Javaのtryブロックの後には、catchまたはfinallyブロックが続く必要があります。
  • 各tryブロックには、0個以上のcatchブロックが存在する可能性がありますが、finallyブロックは1つだけです。
  • プログラムが終了した場合(System.exit()を呼び出すか、プロセスを中止させる致命的なエラーが発生した場合)、finallyブロックは実行されません。

1
「バージョン7が許可される前」は、Java 7とJava 8がこれら3つの組み合わせを許可しないことを意味していますか?それがあなたの言いたいことだとは思いませんが、それがあなたの答えが意味するものです。
Loduwijk 2017年

tryブロックにreturnステートメントがある場合、finallyブロックは実行されますか?
Rahul Yadav

@Rahulはい、ようやく呼び出されます。参考:stackoverflow.com/questions/65035/...
roottraveller

1
@Aaron-tryキーワードの直後の括弧内に構築されたものに対して自動的に.close()を呼び出すtry-with-resourceの新しい構文。
Roboprog 2018年

2

例外またはスロー可能な何かが発生した場合、tryブロックはどのように機能しますか

例外は、キャッチされない他の場合と同様に、ブロックからスローされます。

finallyブロックは、tryブロックの終了方法に関係なく実行されます-一致するcatchがあるかどうかに関係なく、catchがまったくあるかどうかに関係なく実行されます。

catchブロックとfinallyは、tryブロックの直交部分です。どちらか一方または両方を持つことができます。Java 7では、どちらも使用できなくなります。


1

そのプログラムで試してみませんか?finallyブロックに移動してfinallyブロックを実行しますが、例外は処理されません。しかし、その例外はfinallyブロックで却下できます!


1

finallyブロックは、tryブロックが完了した後に実行されます。最後のブロックを離れるときにtryブロックの内部に何かがスローされた場合、それが実行されます。


0

tryブロックの内部で、例外をスローできるコードを記述します。catch私たちは、例外を扱うところのブロックです。finally例外が発生したかどうかに関係なく、ブロックは常に実行されます。

ここで、try-catch-finallyブロックの代わりにtry-finallyブロックがある場合、例外は処理されず、tryブロックの代わりに、catchブロックに移動するのではなく、最終的にblockに移動します。例外を除いて何もしない場合は、try-finallyブロックを使用できます。


0

例外がtryブロックでスローされたかどうかに関係なく、ブロックfinallyが実行されます。例外はキャッチされません。

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