try catch finally returnの実行順序

3896 ワード

 

public class JVMTest {

	public static void main(String[] args) {

		System.out.println("aa:" + aa());

	}



	public static int aa() {

		int a = 1;

		int b = 10;

		try {

			System.out.println("abc");

			return a;

		} finally {

			a = 2;

			System.out.println("a:" + a);

		}

	}

}

実行結果:abca:2 aa:1であることから、try文でreturn文を実行する際に返す結果が準備されていることがわかり、このときプログラムはfinally実行に移行した.転送する前にtryでは返すべき結果をaとは異なる局所変数に格納しておき、finallyを実行した後、そこから戻り結果を取り出すので、finallyでは変数aが変更されても、戻り結果には影響しません.
しかし、finally句に最後にreturn aを追加したらどうなるのでしょうか.実行結果は以下の通りである:Compiling 1 source file to E:sunInsideJVMbuildclassesE:sunInsideJVMsrcJVMTest.java:37: warning: finally clause cannot complete normally}1 warningcompile-single:run-single:abca: 2aa:2
テスト1:
public static int test1()

{

    int i = 1;

    try

    {

        return ++i;

    }

    finally

    {

        ++i;

        Console.WriteLine("finally:" + i);

    }

}



static void Main(string[] args)

{

    Console.WriteLine("Main:" + test1());

}

結果:finally:3 Main:2
テスト2:
public static int test2()

{

    int i = 1;

    try

    {

        throw new Exception();

    }

    catch

    {

        return ++i;

    }

    finally

    {

        ++i;

        Console.WriteLine("finally:" + i);

    }

}



static void Main(string[] args)

{

    Console.WriteLine("Main:" + test2());

}


結果:finally:3 Main:2
テスト3:
public static int test3()

{

    try{}

    finally

    {

        return 1;

    }

}

結果:コンパイルエラー、制御はfinally句主体から離れられません.
結論:
1.異常が発生してもfinallyブロックの文は実行されます.2.tryまたはcatchブロックにreturn文がある場合、finallyブロックの文は実行されます.3.finallyブロックの文はreturn文の実行後に実行されます.すなわち、関数の戻り値はfinallyブロックの文の実行前に決定されます.4.finallyブロックにreturn文を含めることはできません.
まとめ:finallyはreturnの前に実行され、finallyの操作では確定したreturnの値は変更されません.
finallyはreturn文を追加できません.異常が発生したら、まずプロセッサがこの異常を処理できるかどうかを探します.またfinally.