try catch finallyとreturnの間の順序の葛藤
5228 ワード
return文のtry-catch-finallyでの実行順序
一般的な状況:
実行結果:
a: 0finally a: 111tcr.test(): 111
1.まず3ブロックのreturnの優先度をテストする
実行結果:
a: 0finally a: 111tcr.test(): 111
test()メソッドはfinallyモジュールのreturn文から最後に返されることがわかる.
結論:
1.finallyモジュールは常に実行され、finallyモジュールのreturnも常に実行されるが、tryモジュールのreturnは実行されていないとみなすことができる.
2.finallyモジュール内でreturnを推奨しない;
2.finallyブロックにreturnがない場合の戻り順をテストする.
実行結果:
a: 0finally a: 111tcr.test(): 110
test()メソッドでは、tryモジュールのreturn文はfinallyモジュールより先に実行されるが、returnはすぐに戻るのではなく、実行後、関数スタックに戻り、finallyモジュールの実行が完了するとtryモジュールのreturn文に戻り、メソッドを終了し、実行を完了する.従って、この場合、tryモジュールのreturn文はfinallyモジュールより先に実行されると考えられるが、メソッドは最終的にreturn文から終了を返す.
結論:
1.tryまたはcatchブロックにreturn文がある場合、finallyモジュールの文は実行されます.
2.tryまたはcatchモジュールにreturn文がある場合、finallyモジュールにreturnがない場合、tryまたはcatchモジュールのreturn戻り値はfinallyモジュールの実行前に決定され、return文はfinallyモジュールより先に実行される.
3.returnがtry-catch-finally文の後にある場合、finallyモジュールはreturnの前に実行される.(最初の例のように)
3.catchモジュールの介入時のreturnの戻り順をテストする(finallyはreturnがない).
実行結果:
a: 0finally a: 114tcr.test(): 113
test()はcatchモジュールのreturn文から返され、実行プロセスはテスト2に類似しており、finallyモジュールはcatchモジュールのreturn実行前に実行され、catchモジュールのreturn戻り値はfinallyモジュール実行前に決定される.
4.catchモジュールの介入時のreturnの戻り順序(finallyにreturnがある)をテストする.
実行結果:
a: 0finally a: 114tcr.test(): 114
test()はfinallyモジュールのreturn文から返され、catchモジュールのreturnは実行されていないとみなされ、最終的にfinallyモジュールaの値が返される.
4.まとめ
1.例外があるかどうかにかかわらず、finallyブロックの文はtryまたはcatchモジュールにreturnがあるかどうかにかかわらず実行されます.
2.finallyモジュールにreturnがある場合、tryまたはcatchモジュールにreturnがあるかどうかにかかわらず、プログラムセグメントは最終的にfinallyのreturnから返される.
しかし、finally文ではreturnは一般的に推奨されません.
3.finallyモジュールにreturnがない場合、return文はfinallyモジュールより先に実行され、tryまたはcatchモジュールのreturn戻り値(returnがある場合)はfinallyモジュールの実行前に決定されますが、方法は最終的にreturn文から返されます.
4.try-catch-finally文の後のreturn文の場合、finallyモジュールはreturnの前に実行され、return戻り値はfinallyモードの実行後に決定される.
一般的な状況:
public class TryCatchReturn {
public static void main(String[] args) {
TryCatchReturn tcr = new TryCatchReturn();
System.out.println("tcr.test(): "+tcr.test());
}
public int test(){
int a = 0;
try{
System.out.println("a: "+a);
a = 110;
}catch(Exception e){
a = a+3;
}finally{
a ++;
System.out.println("finally a: "+a);
}
return a;
}
}
実行結果:
a: 0finally a: 111tcr.test(): 111
1.まず3ブロックのreturnの優先度をテストする
public class TryCatchReturn {
public static void main(String[] args) {
TryCatchReturn tcr = new TryCatchReturn();
System.out.println("tcr.test(): "+tcr.test());
}
public int test(){
int a = 0;
try{
System.out.println("a: "+a);
a = 110;
return a;
}catch(Exception e){
a = a+3;
return a;
}finally{ // : finally block does not complete normally
a ++;
System.out.println("finally a: "+a);
return a;
}
//return a; // , !
}
}
実行結果:
a: 0finally a: 111tcr.test(): 111
test()メソッドはfinallyモジュールのreturn文から最後に返されることがわかる.
結論:
1.finallyモジュールは常に実行され、finallyモジュールのreturnも常に実行されるが、tryモジュールのreturnは実行されていないとみなすことができる.
2.finallyモジュール内でreturnを推奨しない;
2.finallyブロックにreturnがない場合の戻り順をテストする.
public class TryCatchReturn {
public static void main(String[] args) {
TryCatchReturn tcr = new TryCatchReturn();
System.out.println("tcr.test(): "+tcr.test());
}
public int test(){
int a = 0;
try{
System.out.println("a: "+a);
a = 110;
return a;
}catch(Exception e){
a = a+3;
return a;
}finally{
a ++;
System.out.println("finally a: "+a);
}
}
}
実行結果:
a: 0finally a: 111tcr.test(): 110
test()メソッドでは、tryモジュールのreturn文はfinallyモジュールより先に実行されるが、returnはすぐに戻るのではなく、実行後、関数スタックに戻り、finallyモジュールの実行が完了するとtryモジュールのreturn文に戻り、メソッドを終了し、実行を完了する.従って、この場合、tryモジュールのreturn文はfinallyモジュールより先に実行されると考えられるが、メソッドは最終的にreturn文から終了を返す.
結論:
1.tryまたはcatchブロックにreturn文がある場合、finallyモジュールの文は実行されます.
2.tryまたはcatchモジュールにreturn文がある場合、finallyモジュールにreturnがない場合、tryまたはcatchモジュールのreturn戻り値はfinallyモジュールの実行前に決定され、return文はfinallyモジュールより先に実行される.
3.returnがtry-catch-finally文の後にある場合、finallyモジュールはreturnの前に実行される.(最初の例のように)
3.catchモジュールの介入時のreturnの戻り順をテストする(finallyはreturnがない).
public class TryCatchReturn {
public static void main(String[] args) {
TryCatchReturn tcr = new TryCatchReturn();
System.out.println("tcr.test(): "+tcr.test());
}
public int test(){
int a = 0;
try{
System.out.println("a: "+a);
a = 110;
throw new Exception(); //try return,unreachable
}catch(Exception e){
a = a+3;
return a;
}finally{
a ++;
System.out.println("finally a: "+a);
}
}
}
実行結果:
a: 0finally a: 114tcr.test(): 113
test()はcatchモジュールのreturn文から返され、実行プロセスはテスト2に類似しており、finallyモジュールはcatchモジュールのreturn実行前に実行され、catchモジュールのreturn戻り値はfinallyモジュール実行前に決定される.
4.catchモジュールの介入時のreturnの戻り順序(finallyにreturnがある)をテストする.
public class TryCatchReturn {
public static void main(String[] args) {
TryCatchReturn tcr = new TryCatchReturn();
System.out.println("tcr.test(): "+tcr.test());
}
public int test(){
int a = 0;
try{
System.out.println("a: "+a);
a = 110;
throw new Exception(); //try return,unreachable
}catch(Exception e){
a = a+3;
return a;
}finally{
a ++;
System.out.println("finally a: "+a);
return a;
}
}
}
実行結果:
a: 0finally a: 114tcr.test(): 114
test()はfinallyモジュールのreturn文から返され、catchモジュールのreturnは実行されていないとみなされ、最終的にfinallyモジュールaの値が返される.
4.まとめ
1.例外があるかどうかにかかわらず、finallyブロックの文はtryまたはcatchモジュールにreturnがあるかどうかにかかわらず実行されます.
2.finallyモジュールにreturnがある場合、tryまたはcatchモジュールにreturnがあるかどうかにかかわらず、プログラムセグメントは最終的にfinallyのreturnから返される.
しかし、finally文ではreturnは一般的に推奨されません.
3.finallyモジュールにreturnがない場合、return文はfinallyモジュールより先に実行され、tryまたはcatchモジュールのreturn戻り値(returnがある場合)はfinallyモジュールの実行前に決定されますが、方法は最終的にreturn文から返されます.
4.try-catch-finally文の後のreturn文の場合、finallyモジュールはreturnの前に実行され、return戻り値はfinallyモードの実行後に決定される.