Java异常体系概述

Java的异常体系结构

Java异常体系的根类是 Throwable, 因此当写在java代码中写throw抛出异常时,后面跟的对象必然是Throwable或其子类的对象。
其中Exception异常是指一些能够恢复的异常, 例如常见的NullPointerException空指针异常。
Error指的是一些致命的错误,没法经过程序代码手段恢复的异常,例如OutOfMemoryError内存溢出错误。java

unchecked异常

在上图中除了RuntimeException、Error及其子类都是属于unchecked的异常类型外,其余的都是受编译器checked检查的异常。
unchecked不受编译器检查的异常, 是由于这些错误在程序运行过程当中是能够经过编程手段去控制住的,
例如常见的NullPointerException空指针异常和IndexOutOfBoundsException数组下标越界的异常,这些均可以事先使用if (xx != null) 以及 if (xxx.size() > i)来控制,
或者就是彻底没法经过程序手段控制,
例如OutOfMemoryError内存溢出异常和StackOverflowError栈溢出异常,这种Error由于没法经过代码层面if就能避免的,因此也属于unchecked。程序员

checked异常

checked在编译过程当中受到编译器的检查,若是程序没有对该异常作catch处理或者向上一层抛出的话,程序将没法编译经过,
常见的checked异常有FileNotFoundException文件不存在异常等,由于这种异常在编写阶段就能够预见,例如这个文件极有多是不存在的,因此这种异常必需要抛出并要求程序做出处理。面试

总结

Throwable任何异常/错误的祖先类,属于checked异常。
Exception异常,能够从异常中恢复执行的异常,属于checked异常。
RuntimeException异常,预料以外的异常例如空指针、数组越界,属于unchecked异常。
...Exception除了RuntimeException及其子类是unchecked异常,其余的Exception类都是checked异常。
Error错误,致命问题,没法从错误中恢复, 也属于unchecked异常。
在开发过程当中,若是一些能够预料的到的错误抛出异常时,尽可能抛出checked异常,例如那个文件、某个数据必定可能会不存在的状况下,就要提示该方法的调用者,须要对这种状况进行处理,
若是是一些预料以外的异常,则能够使用RuntimeException,例如某个值规定必定是必须不为空,可是程序判断时为空了,则要进行RuntimeException的抛出。编程

面试题

什么是checked/unchecked/runtime exception?

  • checked exception指的是除了Error、Runtime Exception及其子类以外的全部异常,
  • unchecked exception指的是Error、Runtime Exception及其子类的异常,
  • runtime exception属于unchecked异常。

try/catch/finally的执行顺序

  • try用于包含运行时的代码块,第一步执行,
  • catch用于捕获代码运行时可能发生的异常,第二步执行
    当代码块执行到某一步发生错误时,后面的代码将不会进行执行,
    而是跳转到catch的代码块中,catch顺序由上而下,以第一个能够捕获到当前异常的catch进行执行其中的内容,
  • finally是程序无论有没有发生异常,这里的代码最终必定会执行,因此是第三步执行。

在finally中return数据会怎么样

因为finally在无论什么状况下都会执行,因此finally中的return或覆盖掉其余地方的return,最终以finally返回的为主,图中最终返回结果是2。数组

throw和throws的区别

  • throw是用于在程序运行过程当中,若是碰到了以为不正确的值或者结果,能够经过throw new XXX()来抛出一个异常,终止当前程序的继续执行。
  • throws是用于在方法签名上指出该方法将抛出什么异常,告诉调用者,调用此方法可能会产生的异常,让调用者作相应的处理。

final、finally、finalize的区别

  • final用于修饰类、方法、变量,在类上该类不可被继承,在方法上,该方法不可被重写,在变量上,该变量引用不可被更改。
  • finally用于在try语句中,意味着finally包含的代码必须执行,无论有没有异常。
  • finalize是全部对象的一个方法,在该对象被回收前,将会被垃圾回收器调用,可是只会调用一次,通常能够在该方法中挽救当前将被回收的对象,例如使用一个变量引用当前对象,可是这种方式不可取,由于垃圾回收器不会保证该方法被执行完毕,可能正在赋值的过程当中该对象就被回收了,
    这个方法相似C++的析构函数,可是不稳定,官方也不推荐使用,只是由于历史缘由,为了让C++程序员更适应Java做出的一个妥协。

结语

欢迎关注微信公众号『码仔zonE』,专一于分享Java、云计算相关内容,包括SpringBoot、SpringCloud、微服务、Docker、Kubernetes、Python等领域相关技术干货,期待与您相遇!
微信

相关文章
相关标签/搜索