Java的异常

异常也是对象,而对象都用类来定义。异常类的根类是java.lang.Throwable。

抛出的异常都是这个图中给出的类的实例,或者是这些类的子类的实例。

我们也可以定义自己的异常类。

Throwable类是所有异常类的根。所有异常类都直接或间接地继承自Throwable。这些异常可以分为三种类型:系统错误、异常和运行时异常。

RuntimeException和Error都称为免检异常(unchecked exception)。所有的其他异常都称为必检异常(checked exception),表示编译器会强制程序员检查并通过try-catch块处理它们,或在方法头处理它们。

Java语言不强制要求编写代码捕获或声明免检异常。

异常的处理器是通过从当前的方法开始,沿着方法调用链,按照异常的反向传
播方向找到的。

Java的异常处理模型基于三种操作:声明异常、抛出异常和捕获异常。

Java对面向对象的语言。在Java中,当前执行的语句必须属于某个方法。Java解释器调用main方法开始执行一个程序。每个方法都必须声明它可能抛出的必检异常的类型。这称为声明异常。这样方法的调用者会被告知有异常。

处理异常的这段代码称为异常处理器(exception handler)

可以从当前的方法开始,沿着方法调用链,按照异常的反向传播方向找到这个处理器。如果调用链找不到处理器,程序就会终止并且在控制台上打印出错信息。寻找处理器的过程称为捕获一个异常。

JDK7可以使用同样的处理代码处理多个异常的情况。

catch(exception1 | exception2 | exception3){ //code }

何时使用异常?

异常处理可以分离正常的程序和错误处理程序。异常处理需要初始化新的对象,需要从调用栈返回,还要沿着方法调用链来传播异常以便找到它的异常处理程序,所以异常处理通常需要花费更多的时间。如果想让该方法的调用者处理异常,应该创建一个异常对象并将其抛出。

当必须处理不可预料的错误状况时应该使用try-catch块。不要用异常处理来处理简单、可预料的情况。不要把异常处理当作逻辑判断。

允许异常处理器再抛出异常。这样是为了让调用者注意到这个异常。

在异常处理器中同原始异常一起再抛出一个新的异常叫链式异常(chained exception)。

自定义异常最好不要继承免检异常。继承必检异常可以让编译器在程序中强制捕获这些异常。