当前位置: 首页 > news >正文

asp网站栏目修改/优化服务公司

asp网站栏目修改,优化服务公司,低代码开发平台优缺点,小米的网站是哪个公司做的Java 中有一个非常重要的内容是 try-catch-finally 的执行顺序和返回值问题,其中 finally 一定会执行,但是为什么会这样? 下面看下 try-catch-finally 背后的实现原理 try-catch public class Test {public static void main(String[] args)…

Java 中有一个非常重要的内容是 try-catch-finally 的执行顺序和返回值问题,其中 finally 一定会执行,但是为什么会这样? 下面看下 try-catch-finally 背后的实现原理

try-catch

public class Test {public static void main(String[] args) {foo();}public static void foo() {try {int i = 1 / 0;}catch (Exception e){System.out.println("执行异常");e.printStackTrace();}}}

字节码

public class com.yxzapp.Test {public com.yxzapp.Test();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: invokestatic  #2                  // Method foo:()V3: returnpublic static void foo();Code:0: iconst_1                         // 将int 类型值1压栈到栈顶1: iconst_0						   // 将int 类型值0压栈到栈顶2: idiv                             // 将栈顶两int型数值相除并将结果压入栈顶3: istore_0                         // 将栈顶类型int数据存储到局部变量表下标04: goto          20                 // 如果不抛异常跳到20行7: astore_0                         // 将引入对象(异常对象)存储局部变量表下标08: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;11: ldc           #5                  // String 鎵ц寮傚父13: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V16: aload_017: invokevirtual #7                  // Method java/lang/Exception.printStackTrace:()V20: returnException table:from    to  target type0     4     7   Class java/lang/Exception
}

17 4: goto 20 // 如果不抛异常跳到20行

如果有异常抛出,如何处理呢?

当方法包含 try-catch 语句时,在编译单元生成的方法的 Code 属性中会生成一个异常表 (Exception table), 每个异常项表示一个异常处理器, 由 from 指针 、to 指针、target 指针 、所捕获的异常类型 type 四部分组成。这些指针的值是字节码索引,用于定位字节码。其含义是在 [from ,to) 字节码范围内,如果跑出来异常类型为 type 的异常,就会跳转到 target 指针表示的字节码处继续执行。

上面的例子中 Exception table表示,在 0 - 4 之间(不包含4),如果抛出类型为 Exception 或其子类就跳转到7继续执行

当抛出异常时,Java 虚拟机会自动将异常对象加载到操作数栈栈顶

多try-catch

public class Test {public static void main(String[] args) {foo();}public static void foo() {try {int i = 1 / 0;}catch (ArithmeticException e){System.out.println("执行异常 ArithmeticException");e.printStackTrace();} catch (NullPointerException e){System.out.println("执行异常 NullPointerException");e.printStackTrace();}}}

字节码

public class com.yxzapp.Test {public com.yxzapp.Test();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: invokestatic  #2                  // Method foo:()V3: returnpublic static void foo();Code:0: iconst_11: iconst_02: idiv3: istore_04: goto          367: astore_08: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;11: ldc           #5                  // String 鎵ц寮傚父 ArithmeticException13: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V16: aload_017: invokevirtual #7                  // Method java/lang/ArithmeticException.printStackTrace:()V20: goto          3623: astore_024: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;27: ldc           #9                  // String 鎵ц寮傚父 NullPointerException29: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V32: aload_033: invokevirtual #10                 // Method java/lang/NullPointerException.printStackTrace:()V36: returnException table:from    to  target type0     4     7   Class java/lang/ArithmeticException0     4    23   Class java/lang/NullPointerException
}

可以看到 ,多一个 catcha 语句处理分析, 异常表里面就会多一条记录,当程序出现异常时, Java 虚拟机会从上至下遍历异常表中所有的条目。当触发异常的字节码索引值在某个条目的 [from 、to)范围内,则会判断抛出的异常是否是想捕获的异常或子类

如果异常匹配, Java 虚拟机将控制跳转到 target 指向的字节码继续执行;如果不匹配,则继续遍历异常表。如果遍历完所有的异常表还未找到匹配的异常处理器,那么该异常将继续抛到调用方 (caller)中重复上述的操作

try-catch-finally

public class Test {public static void main(String[] args) {foo();}public static void foo() {try {int i = 1 / 0;}catch (ArithmeticException e){System.out.println("执行异常 ArithmeticException");e.printStackTrace();} finally {System.out.println("执行");}}}

字节码

public class com.yxzapp.Test {public com.yxzapp.Test();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: invokestatic  #2                  // Method foo:()V3: returnpublic static void foo();Code:0: iconst_1                          // 将int 类型值1压栈到栈顶1: iconst_0                          // 将int 类型值0压栈到栈顶2: idiv                              // 将栈顶两int型数值相除并将结果压入栈顶3: istore_0							// 开始执行 finally 代码块4: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;7: ldc           #4                  // String 鎵ц9: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V12: goto          5015: astore_0// 异常(被catch)情况下开始执行 finally 代码块16: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;19: ldc           #7                  // String 鎵ц寮傚父 ArithmeticException21: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V24: aload_025: invokevirtual #8                  // Method java/lang/ArithmeticException.printStackTrace:()V28: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;31: ldc           #4                  // String 鎵ц33: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V36: goto          5039: astore_1// 异常(catch中执行出现异常)代码块出现异常 情况下开始									   执行 finally 代码块40: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;43: ldc           #4                  // String 鎵ц45: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V48: aload_149: athrow50: returnException table:from    to  target type0     4    15   Class java/lang/ArithmeticException0     4    39   any15    28    39   any
}

可以看出字节码中 出现三次调用

   getstatic     #3                     // Field java/lang/System.out:Ljava/io/PrintStream;ldc           #4                        // String 鎵цinvokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V

都是在程序正常 return 和异常 throw 之前,其中两处在 try-catch 语句调用 return 之前,一处是在异常抛出 throw 之前

由代码可知,现在的 Java 编译器采用复制 finally 代码块的方式,并将其内容插入到 try 和 catch 代码块中所有正常退出和异常退出之前。这样就解释了我们一直以来所熟知的 finally 语句块一定会执行

http://www.ho-use.cn/article/547.html

相关文章:

  • 华为云建站怎么样/免费推广广告链接
  • 综合门户网站什么意思/广东seo网站优化公司
  • 网站开发毕业设计书/seo搜索引擎工具
  • 如何用ftp做网站/网页在线客服免费版
  • 网站制作的电话/登封网络推广公司
  • 宿迁网站建设价位/百度一下首页官网百度
  • 做农产品的网站名称/软件外包公司排行榜
  • 自己怎么做短视频网站/互联网营销模式有哪些
  • 注册了域名后怎么设计网站/弹窗广告最多的网站
  • 自己做的小网站分享/新闻头条新闻
  • 简单网站建设流程图/18种最有效推广的方式
  • 网站app服务器租用/优化手机流畅度的软件
  • 化妆品应如何网站建设定位/如何去做网络营销
  • 马鞍山哪里做网站/企业关键词大全
  • 常州市建设工程质量监督站网站/优化排名工具
  • 著名建筑设计作品解析/牛排seo
  • 做网站IP/想学销售去哪培训
  • 在什么网站做公司人员增减/百度推广的步骤
  • 专门做辅助的网站/保定百度seo排名
  • 媒体网站推广方法/百度提交入口网址是什么
  • 公司网站制作公司倒闭/软文推广的100个范例
  • 中国网站设计公司/吸引人的营销标题
  • 危险网站怎么解除/刷移动端seo软件
  • 政府网站建设新模式济南网站建设哪家专业
  • 做网站需要的素材照片/关键词完整版免费听
  • 网站开发属于软件开发吗/老客外链
  • 数码产品网站建设计划书/seo简单优化操作步骤
  • 做公司网站的好处/百度排名优化专家
  • 网站更换域名如何操作/百度集团公司简介
  • 武汉便宜网站建设/北京seo诊断