【JVM】异常和return

来源:互联网 发布:sql双引号转义字符 编辑:程序博客网 时间:2024/06/05 03:08

        参照下文字节码对应来看,环境JDK 8.

package exception;/** * 1. 当只有try块中有return且能正常返回的时候,return的value被存放到局部变量表中,然后执行完finally之后才返回;  * 2. 当try和finally中都有return的时候,try块中的return会被优化掉,只会返回finally中;  * 3. 当try和catch中都有return的时候,异常返回catch,正常返回try;  * 4. 当try、catch和finally中都有return的时候 * 正常: try中的return被优化,直接返回finally中的return; * 异常: try中的return不会被执行,catch中的代码被执行,返回finally中的value; */public class FinallyTest {public static void main(String[] args) {System.out.println(getValueTry());System.out.println(getValueCatch());System.out.println(getValueFinally());System.out.println(getValueTryCatchFinally());/** * 打印结果: * 1 * 1 * 2 * 2 */}// 只有try中returnpublic static int getValueTry() {int i = 1;try {/** * 当执行完return i的时候,i的值被保存到局部变量表其他slot * 等执行完finally之后,才会从该slot从返回 */return i; } finally {/** * 此时增加的是局部变量表中原来的i的值 * 待返回的值被保存到局部变量表中其他的位置,因此这里不影响返回值 */i++;}}// try和catch中returnpublic static int getValueCatch() {int i = 1;try {/*if(i == 1)throw new Exception("xx");*/return i;} catch (Exception e) {return ++i;}}// try和finally中return@SuppressWarnings("finally")public static int getValueFinally() {int i = 1;try {/** * try中的return在编译的时候就被优化掉了 */return i;} finally {i++;return i;}}// try、catch和finally中都有return@SuppressWarnings("finally")public static int getValueTryCatchFinally() {int i = 1;try {/** * 1. 如果不相等(if_icmpne),则goto finally * 意味着如果i != 100,那么try中的return被优化掉,直接跳到finally中执行 * 2. 如果相等,则到try块中执行,执行完后goto finally中执行 * 意味着如果1 == 100,那么走异常,try块中的return不会被执行,只执行catch和finally中的代码 * catch中的return被又化成iinc指令,而不是return指令 */if (i == 100)throw new Exception("xx");return i;} catch (Exception e) {return ++i;} finally {return ++i;}}}
对应的字节码:

public class exception.FinallyTest  minor version: 0  major version: 52  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Class              #2             // exception/FinallyTest   #2 = Utf8               exception/FinallyTest   #3 = Class              #4             // java/lang/Object   #4 = Utf8               java/lang/Object   #5 = Utf8               <init>   #6 = Utf8               ()V   #7 = Utf8               Code   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V   #9 = NameAndType        #5:#6          // "<init>":()V  #10 = Utf8               LineNumberTable  #11 = Utf8               LocalVariableTable  #12 = Utf8               this  #13 = Utf8               Lexception/FinallyTest;  #14 = Utf8               main  #15 = Utf8               ([Ljava/lang/String;)V  #16 = Fieldref           #17.#19        // java/lang/System.out:Ljava/io/PrintStream;  #17 = Class              #18            // java/lang/System  #18 = Utf8               java/lang/System  #19 = NameAndType        #20:#21        // out:Ljava/io/PrintStream;  #20 = Utf8               out  #21 = Utf8               Ljava/io/PrintStream;  #22 = Methodref          #1.#23         // exception/FinallyTest.getValueTry:()I  #23 = NameAndType        #24:#25        // getValueTry:()I  #24 = Utf8               getValueTry  #25 = Utf8               ()I  #26 = Methodref          #27.#29        // java/io/PrintStream.println:(I)V  #27 = Class              #28            // java/io/PrintStream  #28 = Utf8               java/io/PrintStream  #29 = NameAndType        #30:#31        // println:(I)V  #30 = Utf8               println  #31 = Utf8               (I)V  #32 = Methodref          #1.#33         // exception/FinallyTest.getValueCatch:()I  #33 = NameAndType        #34:#25        // getValueCatch:()I  #34 = Utf8               getValueCatch  #35 = Methodref          #1.#36         // exception/FinallyTest.getValueFinally:()I  #36 = NameAndType        #37:#25        // getValueFinally:()I  #37 = Utf8               getValueFinally  #38 = Methodref          #1.#39         // exception/FinallyTest.getValueTryCatchFinally:()I  #39 = NameAndType        #40:#25        // getValueTryCatchFinally:()I  #40 = Utf8               getValueTryCatchFinally  #41 = Utf8               args  #42 = Utf8               [Ljava/lang/String;  #43 = Utf8               i  #44 = Utf8               I  #45 = Utf8               StackMapTable  #46 = Class              #47            // java/lang/Throwable  #47 = Utf8               java/lang/Throwable  #48 = Class              #49            // java/lang/Exception  #49 = Utf8               java/lang/Exception  #50 = Utf8               e  #51 = Utf8               Ljava/lang/Exception;  #52 = String             #53            // xx  #53 = Utf8               xx  #54 = Methodref          #48.#55        // java/lang/Exception."<init>":(Ljava/lang/String;)V  #55 = NameAndType        #5:#56         // "<init>":(Ljava/lang/String;)V  #56 = Utf8               (Ljava/lang/String;)V  #57 = Utf8               SourceFile  #58 = Utf8               FinallyTest.java{  public exception.FinallyTest();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0         1: invokespecial #8                  // Method java/lang/Object."<init>":()V         4: return      LineNumberTable:        line 11: 0      LocalVariableTable:        Start  Length  Slot  Name   Signature            0       5     0  this   Lexception/FinallyTest;  public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=2, locals=1, args_size=1         0: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;         3: invokestatic  #22                 // Method getValueTry:()I         6: invokevirtual #26                 // Method java/io/PrintStream.println:(I)V         9: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;        12: invokestatic  #32                 // Method getValueCatch:()I        15: invokevirtual #26                 // Method java/io/PrintStream.println:(I)V        18: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;        21: invokestatic  #35                 // Method getValueFinally:()I        24: invokevirtual #26                 // Method java/io/PrintStream.println:(I)V        27: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;        30: invokestatic  #38                 // Method getValueTryCatchFinally:()I        33: invokevirtual #26                 // Method java/io/PrintStream.println:(I)V        36: return      LineNumberTable:        line 13: 0        line 14: 9        line 15: 18        line 16: 27        line 24: 36      LocalVariableTable:        Start  Length  Slot  Name   Signature            0      37     0  args   [Ljava/lang/String;  public static int getValueTry();    descriptor: ()I    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=1, locals=3, args_size=0         0: iconst_1         1: istore_0         2: iload_0         3: istore_2         4: iinc          0, 1         7: iload_2         8: ireturn         9: astore_1        10: iinc          0, 1        13: aload_1        14: athrow      Exception table:         from    to  target type             2     4     9   any      LineNumberTable:        line 28: 0        line 34: 2        line 40: 4        line 34: 7        line 35: 9        line 40: 10        line 41: 13      LocalVariableTable:        Start  Length  Slot  Name   Signature            2      13     0     i   I      StackMapTable: number_of_entries = 1        frame_type = 255 /* full_frame */          offset_delta = 9          locals = [ int ]          stack = [ class java/lang/Throwable ]  public static int getValueCatch();    descriptor: ()I    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=1, locals=2, args_size=0         0: iconst_1         1: istore_0         2: iload_0         3: ireturn         4: astore_1         5: iinc          0, 1         8: iload_0         9: ireturn      Exception table:         from    to  target type             2     3     4   Class java/lang/Exception      LineNumberTable:        line 46: 0        line 50: 2        line 51: 4        line 52: 5      LocalVariableTable:        Start  Length  Slot  Name   Signature            2       8     0     i   I            5       5     1     e   Ljava/lang/Exception;      StackMapTable: number_of_entries = 1        frame_type = 255 /* full_frame */          offset_delta = 4          locals = [ int ]          stack = [ class java/lang/Exception ]  public static int getValueFinally();    descriptor: ()I    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=1, locals=1, args_size=0         0: iconst_1         1: istore_0         2: goto          6         5: pop         6: iinc          0, 1         9: iload_0        10: ireturn      Exception table:         from    to  target type             2     5     5   any      LineNumberTable:        line 59: 0        line 64: 2        line 65: 5        line 66: 6        line 67: 9      LocalVariableTable:        Start  Length  Slot  Name   Signature            2       9     0     i   I      StackMapTable: number_of_entries = 2        frame_type = 255 /* full_frame */          offset_delta = 5          locals = [ int ]          stack = [ class java/lang/Throwable ]        frame_type = 0 /* same */  public static int getValueTryCatchFinally();    descriptor: ()I    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=3, locals=2, args_size=0         0: iconst_1         1: istore_0         2: iload_0         3: bipush        100         5: if_icmpne     26         8: new           #48                 // class java/lang/Exception        11: dup        12: ldc           #52                 // String xx        14: invokespecial #54                 // Method java/lang/Exception."<init>":(Ljava/lang/String;)V        17: athrow        18: astore_1        19: iinc          0, 1        22: goto          26        25: pop        26: iinc          0, 1        29: iload_0        30: ireturn      Exception table:         from    to  target type             2    18    18   Class java/lang/Exception             2    25    25   any      LineNumberTable:        line 74: 0        line 76: 2        line 77: 8        line 79: 18        line 80: 19        line 81: 25        line 82: 26      LocalVariableTable:        Start  Length  Slot  Name   Signature            2      29     0     i   I           19       6     1     e   Ljava/lang/Exception;      StackMapTable: number_of_entries = 3        frame_type = 255 /* full_frame */          offset_delta = 18          locals = [ int ]          stack = [ class java/lang/Exception ]        frame_type = 70 /* same_locals_1_stack_item */          stack = [ class java/lang/Throwable ]        frame_type = 0 /* same */}SourceFile: "FinallyTest.java"


附注:

        如有错漏,烦请不吝指正,谢谢!

0 0
原创粉丝点击