路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码( 六 )


zengzhiqin@cengzhiqindeMacBook-Pro?~/Desktop/daima/leetcode/ src?javap-cTestExceptionCompiledfrom"TestException.java"publicclassTestException{publicTestException();Code:0:aload_01:invokespecial#1//Methodjava/lang/Object."":()V4:returnpublicintinc();Code:0:iconst_1//try中x=1,1压入操作数栈1:istore_1//将1从操作数栈存储到局部变量表第一个位置,x=12:iload_1//加载局部变量表第一个位置元素到操作数栈顶3:istore_2//弹出操作数栈顶元素1 , 保存到局部变量表第2个位置4:iconst_3//finally块中x=3 , 将3压入操作数栈5:istore_1//弹出栈顶元素3 , 将其保存到局部变量表第1个位置6:iload_2//将变量表第2个位置值1放到栈顶 , 准备给ireturn返回7:ireturn//正常情况下返回1正确吻合~8:astore_2//给catch中定义的Exceptione赋值 , 存储在slot2中9:iconst_2//catch中x=2 , 2压入操作数栈10:istore_1//弹出栈顶的2 , 保存到slot111:iload_1//局部变量表第1个位置的2压入栈顶12:istore_3//弹出栈顶元素2保存到局部变量第3个位置13:iconst_3//finally中x=3 , 将3压入操作数栈14:istore_1//将3放到局部变量表第1个位置 , 准备给ireturn返回15:iload_3//加载局部变量表第3个位置的值2到栈顶16:ireturn//返回栈顶元素2catch异常返回2正确 , 吻合17:astore4//如果出现了不属于java.lang.Exception及其子类异常走到这里19:iconst_3//finally块中x=3 , 将3压入操作数栈20:istore_1//将3存储到局部变量表第1个位置21:aload4//将异常引用放在栈顶 , 并且抛出23:athrow//抛出异常Exceptiontable:fromtotargettype048Classjava/lang/Exception0417any81317any171917any}复制代码这里可初步推测 , Java虚拟机执行字节码是基于栈的体系结构 , 执行过程可以看我上一篇的讲解~懒得贴链接了 。
异常的执行过程 , finally代码块会在所有正常及异常的路径上都复制一份 , 在这段字节码中 , iconst_3就是对应着finally代码块 , 共三份 , 所以即便在try或者catch代码块中有return语句 , 最终还是会会执行finally代码块中的内容 , 这段代码毫无疑问是返回1 , 如果在finally里面加上returnX,那么就是返回3了 , 这个return什么值的原因是这样来滴!!!
我们可以看到异常表 , 归纳出异常表结构:
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
字节码0-4行所做的操作数就是将整数1赋值给变量x如果这时没有出现异常 , 则会继续走到第5-7行如果出现了异常 , PC寄存器指针转到第8行如果0-4行出现任何异常 , 则跳转17行如果8-13行出现任何异常 , 则跳转17行如果17-19行出现任何异常 , 则跳转17行可知 , 异常表实际上是JAVA代码的一部分 , 编译器使用异常表而不是简单命令来实现JAVA异常以及finally处理机制的 。
异常是平时最常用的 , 其他的属性大家有兴趣再去深入了解亦可 , 写到这里本可爱是真的很累 , 而你百分之八十的几率是直接跳着看到我这句话的 , 路过的小哥哥们随手点个赞吧 ,
作者:阿甘的马路链接:来源:掘金著作权归作者所有 。 商业转载请联系作者获得授权 , 非商业转载请注明出处 。