Java异常处理

目录

  • 什么是Java异常?
  • 当一个Exception在程序中发生的时候,JVM是怎么作的呢?
  • 当咱们编写程序的时候如何对待可能出现的异常呢?

正文

1. 什么是Java异常?java

今天咱们来聊聊java异常,异常是致使程序中断执行的一种指令流。咱们在提升代码稳定性和健壮性的时候,经常会花更多的时间去考虑,代码可能存在的异常。编码中对可能的发生的异常先一步正确处理,就能够确保异常不会致使程序不可用。说了这么多异常,那么异常是什么呢?程序员

Java异常是一种致使程序中断的执行指令流。它存在应用服务器硬件错误、程序编写的时候未考虑数组越界、也多是网络通讯中网络抖动的客观缘由致使的异常等状况。异常多是主观代码设计不周全也多是客观硬件报错,那么认识异常就是避免异常的第一步。咱们先从异常家族的认识开始,下面异常的族谱:数据库

图片描述

Throwable类做为全部异常的发源,他是整个Java异常体系的超体,其下面分为ErrorException两大类。编程

Error与其子类实例表明严重系统错误,应用程序没法处理,如硬件层面的错误、JVM错误或内存不足等问题,这种错误发生时Java应用程序自己无力恢复。Error对象抛出时,基本上不用处理,任其传播至JVM为止,应用程序能作的最多留下日志信息。数组

Exception表明程序运行时发送的各类不指望发生的事件。能够被Java异常处理机制使用,是异常处理的核心。Exception及其子类能够被程序处理,也就是所在应用程序中正确的处理了Exception及其子类就能提升代码的稳定性和健壮性。服务器

Exception类下面分为检测异常非检测异常网络

检测异常,是JVM强制要求程序员为可能出现的异常作预备处理工做。JVM规定检测异常要么使用try-catch语句捕获它并进行处理,要么使用throws子句声明并抛出它,否者javac在编译程序会不经过。这类异常通常是程序运行环境致使的,为了预防未知环境对程序的影响,规定程序员须要处理这类异常。函数

非检测异常,javac在编译时,不会提示和发现异常的存在,JVM不强制要求程序员处理这样的异常。固然,做为程序员咱们应该预防这样的异常致使程序崩溃,因此建议使用try-catch-finally处理它。这类异常缘由多半是代码写的逻辑有问题或考虑不周全编码

2.当一个Exception在程序中发生的时候,JVM是怎么作的呢?spa

对java总体异常家族有了大体的认识以后,那么当一个Exception在程序中发生的时候,JVM是怎么作的呢?

认识这个问题,咱们首看看JVM是如何执行java代码的,JVM将class文件转换为JVM的java类。JVM为java类创建方法表,方法表中的索引能够引导JVM找到须要执行的方法体和JVM方法执行栈。固然,invokemethod调用执行一个方法的时候,Java虚拟机把描述该方法的栈结构置入方法执行栈栈顶,位于栈顶的方法为正在执行的方法。 JVM会为每个方法创建执行的堆和栈用于存放执行中的变量,若是此时程序出现一个Exception,抛出的异常先转移给合适的异常处理语句。代码的执行会被相应的Exception执行流接管将方法表信息、发生异常的位置信息和方法的堆栈信息压入Exception的堆栈,当程序中断的时候IDE就会将Exception的堆栈信息打印出来。

若是咱们经过try…..catch….finally语句来处理异常,处理流程又是怎样的呢?在try代码块中抛出的异常,代码执行流会跳转到catch代码块执行,catch代码块能够对发生的异常进行补救。让代码回归到正常的执行流程。finally语句,不管在try模块中是否发生异常,都会执行finally语句,使用finally语句主要是为了释放被占用的资源,好比打开的文件或连接的通讯资源等。

整体来讲,Java语言的异常处理流程,从程序中获取异常信息。根据Java的源文件和用户调用的包列表,JVM能够获取该程序包括Java API所引起的异常在内的异常处理的信息,这些信息包括:异常引起位置、异常抛出顺序、引起异常的方法名和类名等。这些异常信息在程序异常的排查和修改的时候很是重要,后面会讲到如何正确处理这些异常。

3.当咱们编写程序的时候如何对待可能出现的异常呢?

一般在发生异常的时候咱们有两种处理模型:终止与恢复
终止模型:前提是假设错误很是关键,以致于程序没法返回到程序正常运行轨迹,一旦异常抛出就意味着程序将中止提供服务。如:数据库链接异常发生。

恢复模型:也就是异常程序发生错误,错误能够被修复而后从新回到正常程序执行的轨迹上。例如,咱们能够将数据库链接try。。。catch置于循环中,一次链接不成功能够循环下一次进行链接。

配合终止和恢复模型,咱们会配合使用throw和throws语法。throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常。throws 能够理解成是一种通知行为,没有实际的抛出异常的动做,而仅仅是告诉调用他的上层函数,这里可能会抛出这个异常;

throw用于在函数体内语句中,表示抛出一个实际的异常的实际动做,若是在函数内没有捕获并处理,那么将会一直向上抛出这个异常直到被main()/Thread.run()抛出。

咱们了解了Java的异常内容以后,在程序中遵循怎样的行业规则和大牛的经验合理使用异常,提升代码的稳定性呢?

下面整理了包括Effective Java异常使用指导原则和网上博客内容:

  1. 不要讲异常处理用于正常的控制流(设计良好的API不该该强迫它的调用者为了正常的控制流而使用异常)。
  2. 对能够恢复的状况使用了受检异常,对编程错误使用运行时异常。
  3. 避免没必要要的使用受检异常(能够经过一些状态检测手段来避免异常的发生)。
  4. 优先使用标准异常。
  5. 每一个方法抛出的异常都要有文档。
  6. 保持异常的原子性。
  7. 不要再catch中忽略掉捕获到的异常。
  8. 处理运行时异常,采用逻辑合理规避同时辅助try…catch处理。
  9. 在多重catch快后面,能够加一个catch(Exception)来处理可能会被遗漏的异常。
  10. 对于不肯定的代码,也能够加上try…catch,处理潜在的异常。
  11. 尽可能去处理异常,切忌只是简单的调用printStackTrace()打印输出。
  12. 具体如何处理异常,要根据不一样的业务需求和异常类型去决定。
  13. 尽可能添加finally语句块去释放占用的资源。

不要被这么多规则吓到了,不须要逐条强记他们。我对异常的理解,首先态度上要谦虚明白代码中很难避免由于考虑不周出现的异常,因此编码时应该采用防卫式编码。其次在编码处理过程当中使用try…catch…finally语句预防可能的异常,采用合适的异常处理模式对待程序可能的异常。

相关文章
相关标签/搜索