在 Java 中,所有的异常都有一个共同的祖先 java.lang
包中的 Throwable
类。Throwable
类有两个重要的子类:
Exception
:程序本身可以处理的异常,可以通过 catch
来进行捕获。Exception
又可以分为 Checked Exception (受检查异常,必须处理) 和 Unchecked Exception (不受检查异常,可以不处理)。Error
:Error
属于程序无法处理的错误 ,catch
来进行捕获catch
捕获 。例如 Java 虚拟机运行错误(Virtual MachineError
)、虚拟机内存不够错误(OutOfMemoryError
)、类定义错误(NoClassDefFoundError
)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。Java异常处理原则之一:延迟捕获
意思是,当异常发生时不会立即捕获,而是应该考虑当前作用域是否有能力处理这一异常,如果没有,则应该将该异常向上抛出,交由更上层的作用域来处理。
一个例子:某方法 String readFile(String filename),会去读取指定文件的内容并且返回,若其使用 FileInputStream 来读取指定文件,而 FileInputStream 的构造方法会抛出 FileNotFoundException,这是一个 CheckedException。
那么 readFile 方法是应该捕获这个异常,还是抛出这个异常呢?答案是抛出。因为 readFile 这个方法可能会在不同的场景下,被不同的代码调用。在这些场景中,出现”文件未被找到“的处理逻辑可能是不一样的。只有抛出之后再捕获才可以获得多种多样的处理方式,若直接捕获那么就只有那一种固定的处理方式了。