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

国外做的比较好的网站有哪些汕头搜索引擎优化服务

国外做的比较好的网站有哪些,汕头搜索引擎优化服务,网站制作 万网,设计网页价格JVM 是如何处理异常的? 在 Java 编程语言中,异常处理是一种强大的机制,用于应对程序运行时出现的错误和意外情况。而 Java 虚拟机(JVM)作为 Java 程序运行的核心环境,在异常处理过程中扮演着至关重要的角色…

JVM 是如何处理异常的?

在 Java 编程语言中,异常处理是一种强大的机制,用于应对程序运行时出现的错误和意外情况。而 Java 虚拟机(JVM)作为 Java 程序运行的核心环境,在异常处理过程中扮演着至关重要的角色。下面我们深入探讨 JVM 是如何处理异常的,从异常的基本概念、抛出与捕获机制、异常处理的性能影响,到 Java 7 引入的新特性等多个方面,进行全面而详细的剖析。

异常的基本概念

在 Java 语言规范中,所有异常都是 Throwable 类或者其子类的实例。Throwable 类有两个直接子类:ErrorException

  • Error :表示程序不应捕获的异常。当程序触发 Error 时,通常意味着程序的执行状态已经无法恢复,需要中止线程甚至是中止虚拟机。例如,OutOfMemoryError 表示内存溢出错误,VirtualMachineError 表示虚拟机错误等。这些错误往往是由系统级问题或资源耗尽等问题引起的,应用程序一般无法对其进行有效的处理。

  • Exception :涵盖程序可能需要捕获并且处理的异常。Exception 类又可以分为 RuntimeException 和其他类型的异常(即检查异常)。

RuntimeException 用来表示 “程序虽然无法继续执行,但是还能抢救一下” 的情况,如 ArrayIndexOutOfBoundsException(数组索引越界异常)、NullPointerException(空指针异常)等。RuntimeExceptionError 属于 Java 里的非检查异常(unchecked exception),而其他异常则属于检查异常(checked exception)。

在 Java 语法中,所有的检查异常都需要程序显式地捕获,或者在方法声明中用 throws 关键字标注。通常情况下,程序中自定义的异常应为检查异常,以便最大化利用 Java 编译器的编译时检查。这种检查机制可以在编译阶段帮助开发者发现潜在的异常处理问题,提高程序的健壮性。

异常的抛出与捕获机制

(一)抛出异常

抛出异常可分为显式和隐式两种。

  • 显式抛异常 :主体是应用程序,指的是在程序中使用 “throw” 关键字,手动将异常实例抛出。例如下面代码中,当年龄为负数时,程序显式地抛出一个 IllegalArgumentException 异常,提示年龄不能为负数。​

    if (age < 0) {throw new IllegalArgumentException("年龄不能为负数");
    }
  • 隐式抛异常 :主体则是 Java 虚拟机,它指的是 Java 虚拟机在执行过程中,碰到无法继续执行的异常状态,自动抛出异常。例如,Java 虚拟机在执行读取数组操作时,发现输入的索引值是负数,故而抛出数组索引越界异常(ArrayIndexOutOfBoundsException):  

     int[] arr = new int[5]; int value = arr[-1]; // 隐式抛出 ArrayIndexOutOfBoundsException

(二)捕获异常

捕获异常涉及如下三种代码块:

  • try 代码块 :用来标记需要进行异常监控的代码。开发者将可能抛出异常的代码放在 try 块中,以便 JVM 对其进行监控。

  • catch 代码块 :跟在 try 代码块之后,用来捕获在 try 代码块中触发的某种指定类型的异常。除了声明所捕获异常的类型之外,catch 代码块还定义了针对该异常类型的异常处理器。在 Java 中,try 代码块后面可以跟着多个 catch 代码块,来捕获不同类型的异常。Java 虚拟机会从上至下匹配异常处理器。因此,前面的 catch 代码块所捕获的异常类型不能覆盖后边的,否则编译器会报错。例如下面例子中,如果 try 块中的代码抛出了 IOException,则会被第一个 catch 块捕获并处理;如果抛出了其他类型的异常(如 NullPointerException 等),则会被第二个 catch 块捕获并处理。​

    try {// 可能抛出多种异常的代码
    } catch (IOException e) {// 处理 IOException 异常
    } catch (Exception e) {// 处理其他类型的异常
    }
  • finally 代码块 :跟在 try 代码块和 catch 代码块之后,用来声明一段必定运行的代码。它的设计初衷是为了避免跳过某些关键的清理代码,例如关闭已打开的系统资源。在程序正常执行的情况下,这段代码会在 try 代码块之后运行。否则,也就是 try 代码块触发异常的情况下:  

    • 如果该异常没有被捕获,finally 代码块会直接运行,并且在运行之后重新抛出该异常。  

    • 如果该异常被 catch 代码块捕获,finally 代码块则在 catch 代码块之后运行。在某些不幸的情况下,catch 代码块也触发了异常,那么 finally 代码块同样会运行,并会抛出 catch 代码块触发的异常。在某些极端不幸的情况下,finally 代码块也触发了异常,那么只好中断当前 finally 代码块的执行,并往外抛异常。 ​

JVM 如何捕获异常

在编译生成的字节码中,每个方法都附带一个异常表。异常表中的每一个条目代表一个异常处理器,并且由 from 指针、to 指针、target 指针以及所捕获的异常类型构成。这些指针的值是字节码索引(bytecode index,bci),用以定位字节码。

其中,from 指针和 to 指针标示了该异常处理器所监控的范围,例如 try 代码块所覆盖的范围。target 指针则指向异常处理器的起始位置,例如 catch 代码块的起始位置。

举个例子,在以下代码中:

public static void main(String[] args) {try {mayThrowException();} catch (Exception e) {e.printStackTrace();}
}

编译过后,该方法的异常表拥有一个条目。其 from 指针和 to 指针分别为 0 和 3,代表它的监控范围从索引为 0 的字节码开始,到索引为 3 的字节码结束(不包括 3)。该条目的 target 指针是 6,代表这个异常处理器从索引为 6 的字节码开始。条目的最后一列,代表该异常处理器所捕获的异常类型正是 Exception

当程序触发异常时,Java 虚拟机会从上至下遍历异常表中的所有条目。当触发异常的字节码的索引值在某个异常表条目的监控范围内,Java 虚拟机会判断所抛出的异常和该条目想要捕获的异常是否匹配。如果匹配,Java 虚拟机会将控制流转移至该条目 target 指针指向的字节码。

如果遍历完所有异常表条目,Java 虚拟机仍未匹配到异常处理器,那么它会弹出当前方法对应的 Java 栈帧,并且在调用者(caller)中重复上述操作。在最坏情况下,Java 虚拟机需要遍历当前线程 Java 栈上所有方法的异常表。

异常处理的性能影响

异常实例的构造十分昂贵。这是由于在构造异常实例时,Java 虚拟机便需要生成该异常的栈轨迹(stack trace)。该操作会逐一访问当前线程的 Java 栈帧,并且记录下各种调试信息,包括栈帧所指向方法的名字,方法所在的类名、文件名,以及在代码中的第几行触发该异常。

当然,在生成栈轨迹时,Java 虚拟机会忽略掉异常构造器以及填充栈帧的 Java 方法(Throwable.fillInStackTrace),直接从新建异常位置开始算起。此外,Java 虚拟机还会忽略标记为不可见的 Java 方法栈帧。

既然异常实例的构造十分昂贵,那么在实践中,我们应尽量避免频繁抛出和捕获异常,以免对程序性能造成较大影响。例如,在循环中抛出和捕获异常可能会导致程序运行缓慢。

Java 7 的新特性

(一)Supressed 异常

Java 7 引入了 Supressed 异常来解决异常链问题。这个新特性允许开发人员将一个异常附于另一个异常之上。因此,抛出的异常可以附带多个异常的信息。

然而,Java 层面的 finally 代码块缺少指向所捕获异常的引用,所以这个新特性使用起来非常繁琐。为此,Java 7 专门构造了一个名为 try-with-resources 的语法糖,在字节码层面自动使用 Supressed 异常。

(二)try-with-resources

try-with-resources 语法糖的主要目的是精简资源打开关闭的用法。在 Java 7 之前,对于打开的资源,我们需要定义一个 finally 代码块,来确保该资源在正常或者异常执行状况下都能关闭。资源的关闭操作本身容易触发异常。因此,如果同时打开多个资源,那么每一个资源都要对应一个独立的 try-finally 代码块,以保证每个资源都能够关闭。这样一来,代码将会变得十分繁琐。

Java 7 的 try-with-resources 语法糖极大地简化了上述代码。程序可以在 try 关键字后声明并实例化实现了 AutoCloseable 接口的类,编译器将自动添加对应的 close() 操作。在声明多个 AutoCloseable 实例的情况下,编译生成的字节码类似于上面手工编写代码的编译结果。与手工代码相比,try-with-resources 还会使用 Supressed 异常的功能,来避免原异常 “被消失”。

例如:

public class Foo implements AutoCloseable {private final String name;public Foo(String name) { this.name = name; }@Overridepublic void close() {throw new RuntimeException(name);}public static void main(String[] args) {try (Foo foo0 = new Foo("Foo0");Foo foo1 = new Foo("Foo1");Foo foo2 = new Foo("Foo2")) {throw new RuntimeException("Initial");}}
}

运行结果:

Exception in thread "main" java.lang.RuntimeException: Initialat Foo.main(Foo.java:18)Suppressed: java.lang.RuntimeException: Foo2at Foo.close(Foo.java:13)at Foo.main(Foo.java:19)Suppressed: java.lang.RuntimeException: Foo1at Foo.close(Foo.java:13)at Foo.main(Foo.java:19)Suppressed: java.lang.RuntimeException: Foo0at Foo.close(Foo.java:13)at Foo.main(Foo.java:19)

(三)多异常捕获

Java 7 还支持在同一 catch 代码块中捕获多种异常。实际实现非常简单,生成多个异常表条目即可。例如:

try {// 可能抛出多种异常的代码
} catch (IOException | SQLException e) {// 处理多种异常
}

实践分析

为了更好地理解 JVM 如何处理异常,我们可以进行一些实践分析。例如,查看以下代码:

public class Foo {private int tryBlock;private int catchBlock;private int finallyBlock;private int methodExit;public void test() {for (int i = 0; i < 100; i++) {try {tryBlock = 0;if (i < 50) {continue;} else if (i < 80) {break;} else {return;}} catch (Exception e) {catchBlock = 1;} finally {finallyBlock = 2;}}methodExit = 3;}
}

我们可以使用 javap -c 命令查看编译后的字节码,分析异常处理的机制。通过观察字节码,我们可以更深入地了解 JVM 如何处理 try-catch-finally 代码块,以及异常表条目的生成和匹配过程。

总结

本文详细探讨了 JVM 是如何处理异常的,包括异常的基本概念、抛出与捕获机制、异常处理的性能影响,以及 Java 7 引入的新特性等内容。通过深入理解这些知识,开发者可以在实际开发中更加合理地使用异常处理机制,提高程序的健壮性和性能。

在实际开发中,我们应尽量遵循以下原则:

  • 避免滥用异常来控制流程,因为异常处理机制相对耗时。

  • 合理使用检查异常和非检查异常,根据实际情况判断是否需要显式捕获或声明抛出异常。

  • 善用 Java 7 的新特性,如 try-with-resources 和多异常捕获,简化代码并提高异常处理的效率。

掌握 JVM 的异常处理机制对于 Java 开发者来说至关重要,它有助于我们编写出更高质量、更可靠的 Java 程序。

http://www.dtcms.com/wzjs/301793.html

相关文章:

  • 空调安装东莞网站建设网络营销的重要性与意义
  • 网站制作建设网站营销方案
  • 常熟企业建设网站公司4001688688人工服务
  • 昆明网站建设论坛seo薪酬如何
  • 高端网站建设公司兴田德润在那里我想接app注册推广单
  • 网站建设案例怎么样百度知道推广软件
  • 自己做的网站买域名多少钱百度seo点击器
  • 网站建设方案怎么做网络营销的原理
  • wordpress上传到哪个seo关键词如何设置
  • 之江汇学校网站建设网站的推广优化
  • 投资公司网站建设意义网络推广营销方式
  • 营销型网站建设搜索引擎推广的三种方式
  • 天津网站策划自助建站系统哪个好用
  • 微商营销神器网站seo技术
  • 做网站学java还用学python吗seo公司排名
  • erp软件是什么意思啊优化加速
  • 如何做淘宝商城网站进入百度网首页
  • 网站建设如何做报价网站首页排名
  • 南通建设工程造价信息网站百度推广登录入口电脑
  • 购物网站建设方案自己代理一款手游需要多少钱
  • 建设网站需要用到哪些技术人员网络营销平台名词解释
  • 虹口做网站惊艳的网站设计
  • 公司网站制作的费用申请seo是如何优化
  • 在线考试网站模板五八精准恶意点击软件
  • 厦门做网站多电商推广联盟
  • 电子商务网站建设与管理考卷简述如何对网站进行推广
  • 医疗网站建设基本流程网络推广的手段
  • 国外服装设计网站手游cpa推广平台
  • 用自己电脑做网站的空间网页模版
  • 纯前端网站怎么做rest网络优化排名培训