Java 标准库内建了一些通用的异常, 这些类以 Throwable 为顶层父类. Throwable 又派生出 Error 类和 Exception 类.
错误: Error 类以及他的子类的实例, 代表了 JVM 本身的错误. 错误不能被程序员通过代码处理, Error 很少出现.
异常: Exception 以及他的子类, 代表程序运行时发送的各种不期望发生的事件. 可以被 Java 异常处理机制使用.
try 块不能单独使用, 必须和 finally 块或者 catch 块一起
catch 块不能单独使用, 必须始终与 try 块在一起
finally 块不能单独使用, 必须始终与 try 块在一起
try,catch,finally 中都有 return 语句, 先执行 try 或者 catch 中的 return 语句, 将返回值放在一个零时缓存上, 再执行 finally 中的 return 语句, 最终返回 finnally 中的值.
每一个 catch 块用于处理一个异常. 异常匹配是按照 catch 块的顺序从上往下寻找的, 只有第一个匹配的 catch 会得到执行. 匹配时, 不仅运行精确匹配, 也支持父类匹配, 因此, 如果同一个 try 块下的多个 catch 异常类型有父子关系, 应该将子类异常放在前面, 父类异常放在后面, 这样保证每个 catch 块都有存在的意义.
throws 是另一种处理异常的方式, 它不同于 try...catch...finally,throws 仅仅是将函数中可能出现的异常向调用者声明, 而自己则不具体处理, 让方法的调用者处理程序员也可以通过 throw 语句手动显式的抛出一个异常. throw 语句的后面必须是一个异常对象.
throw 语句必须写在函数中, 执行 throw 语句的地方就是一个异常抛出点, 它和由 JRE 自动形成的异常抛出点没有任何差别.
非检查异常 (unckecked exception):Error 和 RuntimeException 以及他们的子类. javac 在编译时, 不会提示和发现这样的异常, 不要求在程序处理这些异常. 所以如果愿意, 我们可以编写代码处理(使用 try...catch...finally) 这样的异常, 也可以不处理. 对于这些异常, 我们应该修正代码, 而不是去通过异常处理器处理 . 这样的异常发生的原因多半是代码写的有问题, 例如: ArithmeticException, 错误的强制类型转换错误 ClassCastException, 数组索引越界 ArrayIndexOutOfBoundsException, 使用了空对象 NullPointerException 等等.
检查异常(checked exception): 除了 Error 和 RuntimeException 的其它异常. javac 强制要求程序员为这样的异常做预备处理工作(使用 try...catch...finally 或者 throws). 在方法中要么用 try-catch 语句捕获它并处理, 要么用 throws 子句声明抛出它, 否则编译不会通过. 这样的异常一般是由程序的运行环境导致的. 因为程序可能被运行在各种未知的环境下, 而程序员无法干预用户如何使用他编写的程序, 于是程序员就应该为这样的异常时刻准备着. 如 SQLException , IOException,ClassNotFoundException 等.
来源: https://yq.aliyun.com/articles/680925