什么是异常
在理想情况下, 程序总会运行在很完美的环境中, 网络不会终端, 文件一定存在, 程序不会有 BUG. 但是, 理想很丰满, 现实很骨干, 实际生产环境中, 网络可能会中断, 文件可能会找不到, 内存可能会溢出, 程序可能会有 BUG. 而这些意料之外的情况就是异常.
在未处理的情况下, 异常会导致程序无法继续执行, 从而影响软件整体的功能, 但这是多数情况下不允许的, 所以我们需要在程序中将可处理的异常处理掉, 至少保证当前任务可以安全退出.
Java 异常
Java 异常体系中, Throwable 为超类, 其子类包括 Error 和 Exception 两类, Error 主要包括 JVM 本身的问题, 这一类问题很少出现且无法被程序所解决, 所以代码中可以不考虑此部分.
Java 异常体系将异常分为检查异常 (checked exception) 和未检查异常(unchecked exception).
未检查异常也可叫做运行时异常, 因为其在 Java 异常体系中仅包含 RuntimeException, 主要包括代码编写时人为因为做成的异常, 而这些异常在代码编译阶段无法发现, 常见的有 IndexOutOfBoundsException,NullPointerException 和 IndexOutOfBoundsException 等, 当出现未检查异常时可确定是代码 BUG.
检查异常包括除 RuntimeException 以外的所有异常, 常见的主要为 IOException 和 SQLExcetion 两类, 此部分异常虽然可能为人为造成, 但在代码编译阶段就可以被编译器发现, 所以需要在代码中做好相应的处理.
Java 异常处理
对应异常体系, Java 提供了异常处理机制, 常用的关键字有 try,catch,finally,throw 和 throws.
try,catch 和 finally 的用法比较简单, 只需要符合标准语法即可, try 对代码块进行监听, 当出现异常时 catch 捕获异常进行异常处理, 最后执行 finally 代码块. 需要注意几个点:
是无论是否出现异常, finally 代码块是一定执行, 且在最后执行
catch 可以出现多次, 但出现多次时需要注意异常的父子级关系, 后面的异常不能为前面的子类
- try{
- // 代码块
- } catch (异常){
- // 异常处理代码
- } finally {
- // 需要确保一定执行的代码, 例如关闭流资源占用的代码
- }
throw 和 throws 比较容易混淆. throw 用于在代码中手动抛出异常, 而 throws 则用于在方法签名后声明需要抛出的异常, 涉及到继承关系时, 子类方法抛出异常时, 父类方法必须抛出异常, 不能为子类异常的子类且数量不能少于子类, 代码结构如下:
- public void testMethod() throw Exception{
- throw new RuntimeException();
- }
Java 异常的使用建议
仅当有需要或者能处理时对异常进行捕获, 否则将异常抛向调用者, 直至到与页面进行交互时统一处理或记录日志
finally 代码块建议只用来释放占用的资源, 不要用来处理业务逻辑
不要通过异常处理机制处理 RuntimeException, 因为此类异常可以通过修改代码来解决, 同时增加程序的健壮性
异常处理记录日志时记录对问题排查有用的信息, 无法确定时则将异常堆栈信息及方法运行参数记录下来
catch 捕获异常时粒度尽可能, 例如捕获 FileNotFoundException 时不要用 IOException 代替
try 监听的代码尽可能少, 不要将整个方法体都放在 try 语句中
来源: https://www.cnblogs.com/aotian/p/9567358.html