Javaにおけるfinallyとreturnの実行順序の解析(コード例)

不言
リリース: 2018-09-11 14:16:02
オリジナル
1710 人が閲覧しました

この記事の内容は Java での Final と return の実行シーケンス分析 (コード例) です。必要な方は参考にしていただければ幸いです。

finally

1 の実行特性は、例外があるかどうかに関係なく、try と catch でリターンがある場合でも実行されます。実行されました。

そこで問題は、実行命令とは何でしょうか?

単純なテストクラスと逆コンパイルされたバイトコード:

public class Test {
         publicstatic void main(String[] args) {
             System.out.println(test());
         }
 
         publicstatic int test() {
                   try{
                            System.out.println("Codesin try block.");
                            return0;
                   }catch (Exception e) {
                            System.out.println("Codesin catch block.");
                            return100;
                   }finally {
                            System.err.println("Codesin finally block.");
                   }
         }
}
/*
 public static int test();
   Code:
      0: getstatic     #2                  // Fieldjava/lang/System.out:Ljava/io/PrintStream;
      3: ldc           #5                  // String Codes in try block.
      5: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      8: iconst_0
      9: istore_0
     10: getstatic     #7                  // Field java/lang/System.err:Ljava/io/PrintStream;
     13: ldc           #8                  // String Codes in finallyblock.
     15: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     18: iload_0
     19: ireturn
     20: astore_0
     21: getstatic     #2                  // Fieldjava/lang/System.out:Ljava/io/PrintStream;
     24: ldc           #10                 // String Codes in catchblock.
     26: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     29: bipush        100
     31: istore_1
     32: getstatic     #7                  // Fieldjava/lang/System.err:Ljava/io/PrintStream;
     35: ldc           #8                  // String Codes in finallyblock.
     37: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     40: iload_1
     41: ireturn
     42: astore_2
     43: getstatic     #7                  // Fieldjava/lang/System.err:Ljava/io/PrintStream;
     46: ldc           #8                  // String Codes in finallyblock.
     48: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     51: aload_2
     52: athrow
*/
ログイン後にコピー

私たちが書いたコードとコンパイルされたバイトコードを比較できます:

仮想マシンが私たちのために多くのことをしてくれたことがわかりました。finallyステートメントが挿入されています。 try、catch、return ステートメント間のブロック。これが、例外があるかどうか、返されるかどうかに関係なく、finally が実行される理由です。 finally が実行されるため、finally で返されるものはすべて返されます。 finally より前の return はすべて無効なので、return にはどのような意味があるのでしょうか。したがって、実際には、finally ブロックを返すことはできません。 Eclipse コンパイラーは、「finallyblock は正常に完了しません」という警告を表示します。 Javaにおけるfinallyとreturnの実行順序の解析(コード例)

いくつかの状況でのテストコード

try{ return; }catch(){}finally{} return;

テストコード:

1. 参照データ型の変更参照オブジェクト

   public static int test1(){
      int a = 10;
      try{
         a = 20;
         return a;
      }catch(Exception e){
         //other codes.
      }finally{
         a += 5;
         //other codes.
      }
      return a;
   }//最终返回值为20
ログイン後にコピー
   public static StringBuffer test2(){
      StringBuffer sb = new StringBuffer("abc");
      try{
         return sb;
      }catch(Exception e){
         //other codes.
      }finally{
         sb.append("DEF");
         //other codes.
      }
      return sb;
   }//最终返回中内容为abcDEF
ログイン後にコピー

の値 この状況のテストでは、finally の前に return ステートメントがある場合、return 変数にどのような変更が加えられても、finally の再代入など、変数自体は再び変更されないことがわかります。値を基本型変数に割り当てたり、参照型変数に参照を再割り当てしたりしても、戻り値には記録されません。ただし、finally の文は実行されるため、finally の参照型変数が指すオブジェクトの内容は変更でき、その変更は有効になります。この状況は、return ステートメントに遭遇すると、仮想マシンは戻り値のためにハウスを構築しますが、そのハウスは自由に破壊することができますか?できません。しかし、家の中の人は変わる可能性があります。基本データ型や参照型の変数そのものが家であり、参照型の変数が指すオブジェクトの中身が家の中の人です。

そのような小さなテストがあります:

  public static StringBuffer test3(){
      StringBuffer sb = new StringBuffer("abc");
      try{
         return sb;
      }catch(Exception e){
         //other codes.
      }finally{
         sb = new StringBuffer("DEF");
         //other codes.
      }
      return sb;
   }//最终返回值中的内容为abc
ログイン後にコピー

1.1 try ブロックに例外がない場合の戻り値は何ですか?

1.2 try ブロックで ArithmeticException が発生した場合の戻り値は何ですか?

1.3 try ブロックに他の例外がある場合の戻り値は何ですか?

答え: すべて 30 です。その理由は、try ブロックの return の前にコードを実行した後、jvm が return の間のfinally ブロックにコードを挿入するためです。finally ブロックには return が含まれているため、直接返されます。

関連する推奨事項:

Java の try、finally、return ステートメントの実行順序

Java のコード ブロックの実行順序を示す例

以上がJavaにおけるfinallyとreturnの実行順序の解析(コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート