ホームページ >バックエンド開発 >PHPチュートリアル >try-catch-finally の実行順序は何ですか?
try-catch-finally の実行シーケンスは次のとおりです。 1. 例外があるかどうかに関係なく、finally ブロック内のコードが実行されます。 2. try と catch で return がある場合、 3.final は return に続く式が評価された後に実行されます。
try catchfinally 実行シーケンスの結論
1. 例外があるかどうかに関係なく、コードは;
2. try と catch に return がある場合でも、finally が実行されます。
3. return の後の式演算の後に、finally が実行されます。現時点では戻り操作はありません。最初に返される値を保存する代わりに、finally のコードが何であっても、戻り値は変更されず、以前に保存された値のままです)。そのため、関数の戻り値は、finally の前に決定されます。 ;
4.finally に return を含めないことをお勧めします。そうしないと、プログラムが早期に終了し、戻り値は try または catch で保存された戻り値ではなくなります。
テスト ケース 1
public class FinallyTest { public static void main(String[] args) { System.out.println(new FinallyTest().test());; } static int test() { int x = 1; try { x++; return x; } finally { ++x; } } }
結果は次のとおりです。
2
分析:
try ステートメント内で、実行 ステートメントを返すと、返される結果が準備され、この時点でプログラムは最終的に実行に切り替わります。
転送する前に、まず try は返される結果を x とは別のローカル変数に格納します。最後に実行した後、返された結果を取り出します。
したがって、変数 x が最終的に変更されましたが、返される結果には影響しません。
テスト ケース 2
public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i); }catch(Exception e){ i ++; System.out.println("catch block i = "+i); }finally{ i = 10; System.out.println("finally block i = "+i); } return i; }
はい、順番に実行されます。最初に try でコード セグメントを実行し、例外がない場合は最後に入力します。そして最後に戻り、出力は次のようになります:
try block, i = 2 finally block i = 10 main test i = 10
テスト ケース 3
public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i); return i; }catch(Exception e){ i ++; System.out.println("catch block i = "+i); return i; }finally{ i = 10; System.out.println("finally block i = "+i); } }
出力結果は次のとおりです:
try block, i = 2 finally block i = 10 main test i = 2
コードはtryからfinallyまで順番に実行されますが、いずれにしてもfinallyが実行されるため、tryの文は直接返されません。 try ステートメントの return ブロックでは、return によって返される参照変数は、try ステートメントの外部で定義された参照変数 i ではありませんが、システムはローカル参照 i' を再定義します。この参照は、参照 i に対応する値を指します。たとえ、finally ステートメントで参照 i が値 10 を指していても、return によって返される参照はもはや i ではなく i' であるため、参照 i の値は try ステートメントの戻り値とは何の関係もありません。声明。
ただし、これはほんの一部です。i が基本型ではなく参照型に変更された場合はどうなるでしょうか。例は次のとおりです。 >
出力結果は次のとおりです。public static List<Object> testWrap(){ List<Object> list = new ArrayList<>(); try{ list.add("try"); System.out.println("try block"); return list; }catch(Exception e){ list.add("catch"); System.out.println("catch block"); return list; }finally{ list.add("finally"); System.out.println("finally block "); } }ご覧のとおり、リスト コレクションに対する操作が最終的に有効になります。これはなぜでしょうか。基本型はスタックに格納されることがわかりますが、非基本型の場合はヒープに格納され、ヒープ内のアドレスが返されるため、内容が変更されます。
try block finally block main test i = [try, finally]
さて、finally に return を追加して、ステートメントの戻り元を確認します。
出力結果は次のとおりです。public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i); return i; }catch(Exception e){ i ++; System.out.println("catch block i = "+i); return i; }finally{ i = 10; System.out.println("finally block i = "+i); return i; } }ご覧のとおり、finally ステートメント ブロックから返されます。 JVM が try の return ステートメントを無視していることがわかります。しかし、最後に追加された return に対して IDE に黄色の警告が表示されます。これはなぜでしょうか。try に行を追加すると、次のようにコードが異常実行されます。
try block, i = 2 finally block i = 10 main test i = 10finally に return ステートメントがあるため、try と catch の例外がダイジェストされ、例外の発生が遮蔽されていることがわかります。これは、try を使用する本来の意図に反しています。初期の段階ではキャッチされるため、コンパイラの警告も表示されます。
public static int testBasic(){ int i = 1; try{ i++; int m = i / 0 ; System.out.println("try block, i = "+i); return i; }catch(Exception e){ i ++; System.out.println("catch block i = "+i); return i; }finally{ i = 10; System.out.println("finally block i = "+i); return i; } }
では、finally で例外が発生した場合、try と catch の例外にどのような影響があるでしょうか?
catch block i = 3 finally block i = 10 main test i = 10
ここでは、try と catch に例外ステートメントを強制的に追加します。出力結果は次のとおりです。
このプロンプトは、finally の例外情報を表します。これは、1 回の If を意味します。 Final で例外が発生すると、try と catch での例外情報が消化されてしまい、例外情報処理の目的が達成できなくなります。public static int testBasic(){ int i = 1; try{ i++; Integer.parseInt(null); System.out.println("try block, i = "+i); return i; }catch(Exception e){ String.valueOf(null); System.out.println("catch block i = "+i); return i; }finally{ i = 10; int m = i / 0; System.out.println("finally block i = "+i); } }
上記のテストの概要:
Exception in thread “main” java.lang.ArithmeticException: / by zero at tryandcatch.TryAndCatch.testBasic(TryAndCatch.java:25) at tryandcatch.TryAndCatch.main(TryAndCatch.java:45)1.finally ステートメントは常に実行されます。2. try と catch に return ステートメントが存在しない場合。パッケージングタイプ、静的変数、およびグローバル変数以外のデータは、try および catch で返される変数に影響を与えません (パッケージングタイプ、静的変数、およびグローバル変数は変更されます)
3. return ステートメントがfinallyで使用されると、try と catch の return ステートメントは無視され、try と catch の例外も無視され、エラーの発生が回避されます。
4. Final で例外を再度スローすることは避けてください。Finally で例外が発生すると、コードの実行では例外情報が Final にスローされ、try と catch の例外は無視されます。
したがって、実際のプロジェクトでは、finally になります。多くの場合、ストリームまたはデータベース リソースを閉じるために使用され、追加の操作は実行されません。
関連知識の詳細については、
PHP 中国語 Web サイトをご覧ください。 !