话不多说,先引入一张图,然后再做具体讨论:
Java 异常类型及处理
什么是异常?

若程序运行时,发生了不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。

一. Java 异常分类

异常的根接口为: Throwable , 其下有2个子接口,Error 和 Exception 。

  • Error:指的是 JVM 错误,这时的程序并没有执行,无法处理;
  • Exception:指的是程序运行中产生的异常,用户可以使用处理格式进行处理。

1.免检异常(红色部分为特别常见的异常)
Java 异常类型及处理
2.必检异常(红色部分为特别常见的异常)
Java 异常类型及处理

二. Java 异常机制

Java异常机制用到的几个关键字:try、catch、finally、throw、throws。

  • try – 用于监听,将要被监听的代码(可能抛出异常的代码)放在try语句块之中,当 try 语句块内发生异常时,异常就被抛出。
  • catch – 用于捕获异常,catch 用来捕获 try 语句块中发生的异常。
  • finally – finally 语句块总是会被执行。它主要用于回收在 try 块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有 finally 块里面的内容执行完成之后,才会回来执行 try 或者 catch 块中的 return 或者 throw 语句,如果 finally 中使用了 return 或者 throw 等终止方法的语句,则就不会跳回执行,直接停止。
  • throw – 用于明确抛出一个异常对象。
  • throws – 用在方法签名中,用于声明该方法可能抛出的异常类型。主方法上也可以使用 throws 说明。如果在主方法上使用了 throws 抛出,就表示在主方法里面可以不用强制性的对异常进行异常处理,如果出现了异常,就交给 JVM 进行默认处理,则此时会导致程序中断执行。

三.异常的捕获方法

  • try…catch
  • try…catch…finally
  • try…finally

注意:

  1. catch 不能独立于 try 存在。
  2. catch里面不能没有内容
  3. 在 try/catch 后面添加 finally 块并非强制性要求
  4. try 代码后不能既没 catch 块也没 finally 块
  5. try 里面内容越少越好
  6. try, catch, finally 块之间不能添加任何代码
  7. finally 里面的代码一定会被执行(除了 JVM 退出)
  8. 如果程序可能存在多个异常,需要多个 catch 进行捕获
  9. 异常如果是同级关系,catch 谁前谁后没有关系
  10. 如果异常之间存在上下级关系,上级需要放在后面

四.典型问题

1.Error 与 Exception 的区别?

Error(错误)是系统中的错误,程序员是不能改变的和处理的,是在程序编译时出现的错误,只能通过修改程序才能修正。一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等等情况。对于这类错误导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序立刻终止。

Exception(异常)表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

2.在 catch 捕获异常时,为什么不考虑使用 Throwable 类型,而只是使用Exception 来进行接收?

Throwable 表示的范围要比 Exception 大。实际上程序使用 Throwable 来进行处理,没有任何语法问题,但是却会存在逻辑问题。因为此时出现的(或者说用户能够处理的)只有 Exception 类型,而如果使用 Throwable 接收,还会表示可以处理 Error 类型的错误,而用户是处理不了 Error 类型的错误的,所以在开发中用户可以处理的异常都要求以 Exception 类为主。

3.异常是一起处理好还是分开处理好?

根据实际的开发要求是否严格来决定。在实际的项目开发工作中,所有的异常是统一使用 Exception 处理还是分开处理,完全根据开发者的项目开发标准来决定。如果项目开发要求比较严谨,基本上要求针对每一种异常分别进行处理,并且要详细记录异常产生的时间以及产生的位置,这样可以方便程序维护人员进行代码的维护。另外还要注意:处理多个异常时,捕获范围小的异常要放在捕获范围大的异常之前处理。

4.throw 和 throws 的区别?

throw 和 throws 都是在异常处理中使用的关键字,区别如下:

  • throw:指的是在方法中人为抛出一个异常对象(这个异常对象可能是自己实例化的一个异常类型 )
  • throws:在方法的声明上使用,表示此方法在调用时必须处理异常。

5.必检异常(Checked Exception)与免检异常(Unchecked Exception)的区别?

所有的必检异常都继承自 java.lang.Exception ;所有的免检异常都继承自java.lang.RuntimeException

必检异常和免检异常最主要的区别在于其处理异常的方式不同:

  • 必检异常必须使用 try catch 或者 throws 等关键字进行处理,否则编译器会报错
  • 免检异常一般是程序代码写的不够严谨而导致的问题,可以通过修改代码来避免

常见的运行时异常:空指针异常(NullPointerException)、除零异常(ArithmeticException)、数组越界异常(ArrayIndexOutOfBoundsException)等;
常见的必检异常:输入输出异常(IOException)、文件不存在异常(FileNotFoundException)、SQL语句异常(SQLException)等。

此篇文章来源于他人的总结和自己的见解。

相关文章: