JAva try catch finally実行順序まとめ
10927 ワード
目次
戻り値の実行順序
try内return,finally特殊動作しない
try内return,finallyもreturn
try内return,finally前returnの内容を修正する
try内returnの前に異常が発生し、finallyとcatchが変数を変更します.
try内に異常が発生し、catch内return、finallyで各種動作を行う
returnまとめ
異常を投げ出す
catchで異常を投げ出し、finallyは特殊な動作をしない
catchから異常が投げ出され、finally return
catchで異常を投げ出し、finallyでも異常を投げ出す
catchから異常が投げ出され、finallyはcatchの異常をキャプチャしようとした.
catch内放出異常まとめ
戻り値の実行順序
try内return,finally特殊動作しない
実行結果:
説明tryのreturn文はすでに実行されており、finally文を実行しますが、直接戻るのではなく、finally文が実行されてから結果を返します.
この例がまだこの状況を説明するのに十分ではないと思ったら、次の例を加えて証明の結論を強化します.
実行結果:
説明tryのreturn文は先に実行したがすぐに返さず、after returnという文字列を保存し、finally実行が終了してからこの文字列を返し、mainプログラムに印刷させる
ここではfinallyにもreturn文があれば、そのまま戻ってしまい、tryのreturnは戻ってこないのではないかと思うかもしれません.下を見てください.
try内return,finallyもreturn
実行結果:
これはfinallyのreturnが直接戻ってきたことを示しています.tryに戻ってくる文があるかどうかにかかわらず、ここには小さな詳細があります.finallyにreturnを加えると、finallyの外のreturn bは到達不可能な文になります.つまり、永遠に実行できません.注釈が必要です.そうしないと、コンパイラが間違っています.
ここで、finallyにreturn文がないのにbの値を変更した場合、tryのreturnは修正後の値を返しますか、それとも元の値を返しますか.下を見てください.
try内return,finally前returnの内容を修正する
実行結果:
tryのreturnに相当します 100では、100という値が格納され、bという変数が格納されていないため、finallyの変更は無効であり、finallyが終了すると、直接100に戻り、return 2000は実行されません.
実行結果:
tryのreturnに相当します mapの場合、mapという変数のアドレスが格納されており、mapという変数が格納されているわけではないので、finallyのmapという変数に対応するオブジェクトを修正した内容に対して、mapはnullのためmapのアドレスを修正したが、無効であり、アドレスが格納されているため
なぜテスト例1のfinallyのb=150であるか.テスト例2ではfinallyのmap.put("KEY","FINALLY");機能してmapは = null;役に立たなかったの?
これがJavaが値を伝えるかアドレスするかという問題で、簡単に言えば、Javaの中で値を伝えるだけでアドレスがないのも、map=nullという言葉が役に立たない理由です.
これはまた、戻り文がfinallyの外側のreturn bではなくtryのreturn文であることを示している.この文
信じなければ、return bを試してみてください.return 294に変更すると、元の結果には少しも影響しません.
ここで皆さんはまた、tryのreturn文が毎回返されるのではないかと考えているかもしれません.ではfinally外のreturn bは少しも役に立たないのではないでしょうか.下を見てください.
try内returnの前に異常が発生し、finallyとcatchが変数を変更します.
実行結果:
ここでreturnの前に0を除く異常が発生したため、try中のreturnは実行されず、次に異常をキャプチャしたcatch文と最終的なfinally文が実行され、このとき両者のbに対する修正は最終的な戻り値に影響し、このときreturn b;役に立ちました.
もちろん、ここでreturn bをreturn 300に変更したりして、最後に戻ったのは300であることは間違いありません.
ここで疑問に思うかもしれませんが、catchにreturn文があれば?もちろん異常の場合のみ実行可能ですが、finallyの前に戻るのでしょうか?下を見てください.
try内に異常が発生し、catch内return、finallyで各種動作を行う
実行結果は次のとおりです.
異常が発生した場合、catchのreturn文は先に実行され、戻り値が確定してからfinallyブロックを実行し、catchを実行してから戻り、finallyのbの変更は戻り値に影響を及ぼさないことを説明した.原因は前と同じで、つまりtryのreturn文の実行と完全に同じである.
b=b+50になってからreturn bに行くと、tryとcatchで返されるbの値が変更されます.
returnまとめ
最後に、finallyブロックの文はtryまたはcatchのreturn文が実行された後、戻る前に実行されます.
またfinallyの修正文はtryやcatchでreturnが決定した戻り値(数値は影響せず、参照は影響しない)に影響しない可能性があり、finallyにreturn文がある場合はtryやcatchのreturn文を上書きし、直接戻ります.
異常を投げ出す
catchで異常を投げ出し、finallyは特殊な動作をしない
catchが異常を放出した後、finallyは実行を継続し、放出された異常bを保持し、その後放出を継続する
Exception in thread "main"java.lang.ArithmeticException:/by zero at test.t05new.Test9.test(Test9.java:27) at test.t05new.Test9.main(Test9.java:17) try block catch block finally block
catchから異常が投げ出され、finally return
try block catch block finally block finally result
returnはcatchから放出された異常をクリアしました
catchで異常を投げ出し、finallyでも異常を投げ出す
try block catch block finally block Exception in thread "main"java.lang.ArithmeticException:/by zero at test.t05new.Test9.test(Test9.java:32) at test.t05new.Test9.main(Test9.java:17)
finallyが投げた異常はcatchが投げた異常に代わった
catchから異常が投げ出され、finallyはcatchの異常をキャプチャしようとした.
try block catch block finally block finally block2 Exception in thread "main"java.lang.ArithmeticException:/by zero at test.t05new.Test9.test(Test9.java:27) at test.t05new.Test9.main(Test9.java:17)
異常bがキャプチャされていないことがわかり、異常bはプログラムによって保持され、finallyに渡されていない.
catch内放出異常まとめ
catch内に異常が投げ出され、catch内のプロセスが中断され、プログラム内にこの異常が保存され、finallyが正常に実行され、内部returnまたは異常が投げ出された場合、プログラムが終了し、returnまたはfinally内の異常がcatchの異常を上書きします.
戻り値の実行順序
try内return,finally特殊動作しない
try内return,finallyもreturn
try内return,finally前returnの内容を修正する
try内returnの前に異常が発生し、finallyとcatchが変数を変更します.
try内に異常が発生し、catch内return、finallyで各種動作を行う
returnまとめ
異常を投げ出す
catchで異常を投げ出し、finallyは特殊な動作をしない
catchから異常が投げ出され、finally return
catchで異常を投げ出し、finallyでも異常を投げ出す
catchから異常が投げ出され、finallyはcatchの異常をキャプチャしようとした.
catch内放出異常まとめ
戻り値の実行順序
try内return,finally特殊動作しない
public class FinallyTest1 {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
int b = 20;
try {
System.out.println("try block");
return b += 80;
}
catch (Exception e) {
System.out.println("catch block");
}
finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
}
return b;
}
}
実行結果:
try block
finally block
b>25, b = 100
100
説明tryのreturn文はすでに実行されており、finally文を実行しますが、直接戻るのではなく、finally文が実行されてから結果を返します.
この例がまだこの状況を説明するのに十分ではないと思ったら、次の例を加えて証明の結論を強化します.
public class FinallyTest1 {
public static void main(String[] args) {
System.out.println(test11());
}
public static String test11() {
try {
System.out.println("try block");
return test12();
} finally {
System.out.println("finally block");
}
}
public static String test12() {
System.out.println("return statement");
return "after return";
}
}
実行結果:
try block
return statement
finally block
after return
説明tryのreturn文は先に実行したがすぐに返さず、after returnという文字列を保存し、finally実行が終了してからこの文字列を返し、mainプログラムに印刷させる
ここではfinallyにもreturn文があれば、そのまま戻ってしまい、tryのreturnは戻ってこないのではないかと思うかもしれません.下を見てください.
try内return,finallyもreturn
public class FinallyTest2 {
public static void main(String[] args) {
System.out.println(test2());
}
public static int test2() {
int b = 20;
try {
System.out.println("try block");
return b += 80;
} catch (Exception e) {
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
return 200;
}
// return b;
}
}
実行結果:
try block
finally block
b>25, b = 100
200
これはfinallyのreturnが直接戻ってきたことを示しています.tryに戻ってくる文があるかどうかにかかわらず、ここには小さな詳細があります.finallyにreturnを加えると、finallyの外のreturn bは到達不可能な文になります.つまり、永遠に実行できません.注釈が必要です.そうしないと、コンパイラが間違っています.
ここで、finallyにreturn文がないのにbの値を変更した場合、tryのreturnは修正後の値を返しますか、それとも元の値を返しますか.下を見てください.
try内return,finally前returnの内容を修正する
public class FinallyTest3 {
public static void main(String[] args) {
System.out.println(test3());
}
public static int test3() {
int b = 20;
try {
System.out.println("try block");
return b += 80;
} catch (Exception e) {
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b = 150;
}
return 2000;
}
}
実行結果:
try block
finally block
b>25, b = 100
100
tryのreturnに相当します 100では、100という値が格納され、bという変数が格納されていないため、finallyの変更は無効であり、finallyが終了すると、直接100に戻り、return 2000は実行されません.
import java.util.*;
public class FinallyTest6
{
public static void main(String[] args) {
System.out.println(getMap().get("KEY").toString());
}
public static Map getMap() {
Map map = new HashMap();
map.put("KEY", "INIT");
try {
map.put("KEY", "TRY");
return map;
}
catch (Exception e) {
map.put("KEY", "CATCH");
}
finally {
map.put("KEY", "FINALLY");
map = null;
}
return map;
}
}
実行結果:
FINALLY
tryのreturnに相当します mapの場合、mapという変数のアドレスが格納されており、mapという変数が格納されているわけではないので、finallyのmapという変数に対応するオブジェクトを修正した内容に対して、mapはnullのためmapのアドレスを修正したが、無効であり、アドレスが格納されているため
なぜテスト例1のfinallyのb=150であるか.テスト例2ではfinallyのmap.put("KEY","FINALLY");機能してmapは = null;役に立たなかったの?
これがJavaが値を伝えるかアドレスするかという問題で、簡単に言えば、Javaの中で値を伝えるだけでアドレスがないのも、map=nullという言葉が役に立たない理由です.
これはまた、戻り文がfinallyの外側のreturn bではなくtryのreturn文であることを示している.この文
信じなければ、return bを試してみてください.return 294に変更すると、元の結果には少しも影響しません.
ここで皆さんはまた、tryのreturn文が毎回返されるのではないかと考えているかもしれません.ではfinally外のreturn bは少しも役に立たないのではないでしょうか.下を見てください.
try内returnの前に異常が発生し、finallyとcatchが変数を変更します.
public class FinallyTest4 {
public static void main(String[] args) {
System.out.println(test4());
}
public static int test4() {
int b = 20;
try {
System.out.println("try block");
b = b / 0;
return b += 80;
} catch (Exception e) {
b += 15;
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b += 50;
}
return b;
}
}
実行結果:
try block
catch block
finally block
b>25, b = 35
85
ここでreturnの前に0を除く異常が発生したため、try中のreturnは実行されず、次に異常をキャプチャしたcatch文と最終的なfinally文が実行され、このとき両者のbに対する修正は最終的な戻り値に影響し、このときreturn b;役に立ちました.
もちろん、ここでreturn bをreturn 300に変更したりして、最後に戻ったのは300であることは間違いありません.
ここで疑問に思うかもしれませんが、catchにreturn文があれば?もちろん異常の場合のみ実行可能ですが、finallyの前に戻るのでしょうか?下を見てください.
try内に異常が発生し、catch内return、finallyで各種動作を行う
public class FinallyTest5 {
public static void main(String[] args) {
System.out.println(test5());
}
public static int test5() {
int b = 20;
try {
System.out.println("try block");
b = b /0;
return b += 80;
} catch (Exception e) {
System.out.println("catch block");
return b += 15;
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b += 50;
}
//return b;
}
}
実行結果は次のとおりです.
try block
catch block
finally block
b>25, b = 35
35
異常が発生した場合、catchのreturn文は先に実行され、戻り値が確定してからfinallyブロックを実行し、catchを実行してから戻り、finallyのbの変更は戻り値に影響を及ぼさないことを説明した.原因は前と同じで、つまりtryのreturn文の実行と完全に同じである.
b=b+50になってからreturn bに行くと、tryとcatchで返されるbの値が変更されます.
returnまとめ
最後に、finallyブロックの文はtryまたはcatchのreturn文が実行された後、戻る前に実行されます.
またfinallyの修正文はtryやcatchでreturnが決定した戻り値(数値は影響せず、参照は影響しない)に影響しない可能性があり、finallyにreturn文がある場合はtryやcatchのreturn文を上書きし、直接戻ります.
異常を投げ出す
catchで異常を投げ出し、finallyは特殊な動作をしない
public static void main(String[] args) {
System.out.println(test());
}
public static String test() {
try {
System.out.println("try block");
int a = 1 / 0;
return "try result";
} catch (Exception e) {
System.out.println("catch block");
int b = 1 / 0;
return "catch result";
} finally {
System.out.println("finally block");
//return "finally result";
}
}
catchが異常を放出した後、finallyは実行を継続し、放出された異常bを保持し、その後放出を継続する
Exception in thread "main"java.lang.ArithmeticException:/by zero at test.t05new.Test9.test(Test9.java:27) at test.t05new.Test9.main(Test9.java:17) try block catch block finally block
catchから異常が投げ出され、finally return
public static String test() {
try {
System.out.println("try block");
int a = 1 / 0;
return "try result";
} catch (Exception e) {
System.out.println("catch block");
int b = 1 / 0;
return "catch result";
} finally {
System.out.println("finally block");
return "finally result";
}
}
try block catch block finally block finally result
returnはcatchから放出された異常をクリアしました
catchで異常を投げ出し、finallyでも異常を投げ出す
public static void main(String[] args) {
System.out.println(test());
}
public static String test() {
try {
System.out.println("try block");
int a = 1 / 0;
return "try result";
} catch (Exception e) {
System.out.println("catch block");
int b = 1 / 0;
return "catch result";
} finally {
System.out.println("finally block");
int c = 1 / 0;
return "finally result";
}
}
try block catch block finally block Exception in thread "main"java.lang.ArithmeticException:/by zero at test.t05new.Test9.test(Test9.java:32) at test.t05new.Test9.main(Test9.java:17)
finallyが投げた異常はcatchが投げた異常に代わった
catchから異常が投げ出され、finallyはcatchの異常をキャプチャしようとした.
public static void main(String[] args) {
System.out.println(test());
}
public static String test() {
try {
System.out.println("try block");
int a = 1 / 0;
return "try result";
} catch (Exception e) {
System.out.println("catch block");
int b = 1 / 0;
return "catch result";
} finally {
System.out.println("finally block");
try {
System.out.println("finally block2");
} catch (Exception e2) {
System.out.println("finally block3");
return "finally result";
}
//int c = 1 / 0;
//return "finally result";
}
}
try block catch block finally block finally block2 Exception in thread "main"java.lang.ArithmeticException:/by zero at test.t05new.Test9.test(Test9.java:27) at test.t05new.Test9.main(Test9.java:17)
異常bがキャプチャされていないことがわかり、異常bはプログラムによって保持され、finallyに渡されていない.
catch内放出異常まとめ
catch内に異常が投げ出され、catch内のプロセスが中断され、プログラム内にこの異常が保存され、finallyが正常に実行され、内部returnまたは異常が投げ出された場合、プログラムが終了し、returnまたはfinally内の異常がcatchの異常を上書きします.