[JAVA]异常

异常的类型

  • 每一个异常都是一整个类,它们都继承自Exception类。
  • 异常的类型本质依然是类的对象,但是异常类型支持在程序运行出现问题时抛出,也可以提前声明,高速使用者需要处理可能会出现的异常。

  • 异常分为运行时异常和编译时异常。

    运行时异常

  • 在编译阶段无法感知代码是否会出现问题,只有在运行的时候才知道会不会出错(正常情况下是不会出错的。
  • 这样的异常称为运行时异常,异常也是由类定义的,所有的运行时异常都继承自RuntimeException

编译时异常

  • 编译时异常明确指出可能会出现的异常,在编译阶段就需要进行处理(捕获异常)必须要考虑到出现异常的情况,如果不进行处理,将无法通过编译!
  • 默认继承自Exception类的异常都是编译时异常。

自定义异常

  • 编译时异常之需要继承Exceptio就行了。
  • 运行时异常之需要继承RuntimeException就行了。
  • RuntimeException继承自Exception,Exception继承自Throwable

抛出异常

  • 当别人调用我们的方法时,如果传入了错误的参数导致程序无法正常运行,这时我们就可以手动抛出一个异常来终止程序继续运行下去,同时告知上一级方法执行出现了问题:
    1
    2
    3
    4
    5
    6
    7
    public static int test(int a, int b) {
    if(b == 0)
    throw new RuntimeException("被除数不能为0"); //使用throw关键字来抛出异常
    return a / b;
    }
    out:
    Exception in thread "main" java.lang.RuntimeException: 被除数不能为0
  • 异常的抛出同样需要创建一个异常对象出来,我们抛出异常实际上就是将这个异常对象抛出.
  • 异常对象携带了我们抛出异常时的一些信息,比如是因为什么原因导致的异常,在RuntimeException的构造方法中我们可以写入原因。
  • 程序会终止,并且会打印栈追踪信息.
  • 如果我们在方法中抛出了一个非运行时异常,那么必须告知函数的调用方我们会抛出某个异常,函数调用方必须要对抛出的这个异常进行对应的处理才可以:
    1
    2
    3
    4
    private static void test() throws Exception {    //使用throws关键字告知调用方此方法会抛出哪些异常,请调用方处理好
    throw new Exception("我是编译时异常!");
    }

  • 如果不同的分支条件会出现不同的异常,那么所有在方法中可能会抛出的异常都需要注明:
    1
    2
    3
    4
    5
    6
    7
    private static void test(int a) throws FileNotFoundException, ClassNotFoundException {  //多个异常使用逗号隔开
    if(a == 1)
    throw new FileNotFoundException();
    else
    throw new ClassNotFoundException();
    }

异常的处理

  • 当程序没有按照我们理想的样子运行而出现异常时(默认会交给JVM来处理,JVM发现任何异常都会立即终止程序运行,并在控制台打印栈追踪信息)。
  • 现在我们希望能够自己处理出现的问题,让程序继续运行下去,就需要对异常进行捕获,比如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static void main(String[] args) {
    try { //使用try-catch语句进行异常捕获
    Object object = null;
    object.toString();
    } catch (NullPointerException e){ //因为异常本身也是一个对象,catch中实际上就是用一个局部变量去接收异常

    }
    System.out.println("程序继续正常运行!");
    }
    out:
    程序继续正常运行!

  • 当我们希望,程序运行时,无论是否出现异常,都会在最后执行任务,可以交给finally语句块来处理:

    1
    2
    3
    4
    5
    6
    7
    8
    try {
    //....
    }catch (Exception e){

    }finally {
    System.out.println("lbwnb"); //无论是否出现异常,都会在最后执行
    }