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.