Java的异常处理机制

发现错误的最佳时机是在编译阶段,然而编译期间并不能找出所有的错误,余下的问题必需在运行期间解决。

异常是指阻止当前代码继续执行的问题,Java的异常处理机制为编写健壮的程序提供了有力的保障。

Java异常的层次结构

Java的异常处理机制_第1张图片
image.png

抛出异常

if(t == null) {
    throw new PointerException();
}

异常抛出后,首先会在堆上创建一个异常对象,当前的执行路径被终止,并且从弹出异常对象的引用,可以抛出任意类型的Throwable对象,因为所有异常类都继承或者间接继承自Throwable类,抛出异常后,在当前环境就不必再为这个问题操心了,这个问题将由方法的调用方去解决。

捕获异常

try{
    // 可能产生异常的代码
} catch (NullPointerException e) {
    // 异常处理程序1
} catch (NumberFormatException e) {
    // 异常处理程序2
}

将可能产生异常的代码用try块包起来,如果在try块内部抛出了异常,这个方法将在抛出异常的过程中结束,如果不希望方法就此结束,则可以使用catch块来捕获异常,然后在catch块中处理相对应的异常,异常处理程序必须紧跟在try块之后,异常被抛出后,Java的异常处理机制将负责搜寻参数与异常类型相匹配的第一个处理程序。
在Java1.7中,catch块得到了升级,可以使用单个catch处理多个异常

try {
    // 可能产生异常的代码
} catch(NullPointerException | NumberFormatException e) {
    // 异常处理程序
}

创建自定义异常

Java的异常体系不可能预见所有的错误,所以可以自己定义异常来表示程序中可能会遇到的问题
要自己定义异常类,必须从已有的异常类继承,例如

public class MyException extends RuntimeException{
    public MyException(String msg) {
        super(msg);
    }
}

throws

出现在方法声明中,表示该方法可能抛出异常,允许抛出多个异常。

public void method()throws NullPointerException, NumberFormatException{
        
}

方法的调用方必须捕获或者将该异常抛出,否则无法通过编译。

捕获所有异常

通过捕获异常类型的基类Exception可以做到这一点:

try {
    // 可能产生异常的代码       
}catch (Exception e){
    // 异常处理程序            
}

栈轨迹

printStackTrace()方法将返回一个由栈轨迹中的元素所构成的数组,其中每个元素都表示栈中的一帧,元素0是栈顶元素,并且是调用序列中的最后一个方法调用。

使用finally进行清理

对于一些代码,可能会希望无论try块中的异常是否抛出,它们都能得到执行,可以在异常处理程序后面加上finally子句

try {
    // 可能产生异常的代码
}catch (Exception e){
    // 异常处理程序
}finally {
    // 无论try块中是否有异常产生,这里的代码都会执行
}

finally子句中可以清理一些资源,比如已经打开的文件或者网络连接。
即使在try块中有return语句,finally块中的代码依然会执行。

面试题

1.Exception和Error的区别

error指恢复比较困难的问题,比如内存溢出,无法通过程序来处理。异常是在特定情况下产生的错误,比如用0作为被除数等

2.运行时异常和其它异常的区别

运行时异常是RuntimeException的子类,通常是指程序的缺陷,可以选择处理也可以选择不处理,非运行时异常则必须要捕获或者抛出。

3.请写出常见的5个运行时异常

NullPointerException、NumberFormatException、 ArithmeticException、ClassCastException、IndexOutOfBoundsException等。

你可能感兴趣的:(Java的异常处理机制)