【JVM】异常和return
2016-04-15 16:44
459 查看
参照下文字节码对应来看,环境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中return public static int getValueTry() { int i = 1; try { /** * 当执行完return i的时候,i的值被保存到局部变量表其他slot * 等执行完finally之后,才会从该slot从返回 */ return i; } finally { /** * 此时增加的是局部变量表中原来的i的值 * 待返回的值被保存到局部变量表中其他的位置,因此这里不影响返回值 */ i++; } } // try和catch中return public 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_SUPER Constant 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"
附注:
如有错漏,烦请不吝指正,谢谢!
相关文章推荐
- Ruby中的异常处理代码编写示例
- MySQL抛出Incorrect string value异常分析
- 浅谈C#中简单的异常引发与处理操作
- 详解C#编程中异常的创建和引发以及异常处理
- 详解JavaScript中的异常处理方法
- JSP中内建exception对象时出现500错误的解决方法
- 杂谈try-catch-finally异常处理
- 再谈异常处理try catch finally
- java程序中的延时加载异常及解决方案
- 解析Java异常的栈轨迹及其相关方法
- .NET(C#):Emit创建异常处理的方法
- windows7服务器上weblogic启动失败异常解决方法
- js中的异常处理try...catch使用介绍
- 有关ajax的error与后台的异常问题解决
- 深入探讨JAVA中的异常与错误处理
- Java 将字符串动态生成字节码的实现方法
- try catch finally的执行顺序深入分析
- Python3 错误和异常
- 异常
- Python try except finally返回数据的问题