ホームページ >バックエンド開発 >PHPチュートリアル >try-catch-finally の実行順序は何ですか?

try-catch-finally の実行順序は何ですか?

PHPz
PHPzオリジナル
2016-06-13 12:03:4023490ブラウズ

try-catch-finally の実行シーケンスは次のとおりです。 1. 例外があるかどうかに関係なく、finally ブロック内のコードが実行されます。 2. try と catch で return がある場合、 3.final は return に続く式が評価された後に実行されます。

try-catch-finally の実行順序は何ですか?

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 = 10

finally に 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 サイト

をご覧ください。 !

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。