返回

自定义异常用 Exception 还是 RuntimeException?

后端

在软件开发中,异常处理是不可或缺的一部分。当程序运行时遇到无法预料的情况时,就会抛出异常。异常可以分为两大类:受检异常(Checked Exception)和非受检异常(Unchecked Exception)。受检异常是编译器强制检查的异常,在编译阶段就必须处理。非受检异常是编译器不强制检查的异常,在运行时才会被发现。

在Java中,Exception和RuntimeException是两个最常用的异常类。Exception是所有受检异常的父类,RuntimeException是所有非受检异常的父类。也就是说,所有受检异常都是Exception的子类,所有非受检异常都是RuntimeException的子类。

那么,在编写Java程序时,我们应该选择使用Exception还是RuntimeException来定义自定义异常类型呢?

首先,我们需要了解Exception和RuntimeException之间的区别。

  • 受检异常(Exception) :受检异常是编译器强制检查的异常。在编译阶段,如果程序中存在未处理的受检异常,编译器就会报错。常见的受检异常包括IOException、SQLException等。
  • 非受检异常(RuntimeException) :非受检异常是编译器不强制检查的异常。在编译阶段,即使程序中存在未处理的非受检异常,编译器也不会报错。常见的非受检异常包括NullPointerException、IndexOutOfBoundsException等。

一般来说,我们应该尽量使用受检异常来定义自定义异常类型。受检异常可以强制编译器检查异常处理,从而提高程序的健壮性和可靠性。只有在特殊情况下,我们才应该使用非受检异常来定义自定义异常类型。

例如,如果我们编写一个方法,该方法可能会抛出IOException异常,那么我们就应该使用受检异常Exception来定义一个自定义异常类型,如下所示:

public class MyException extends Exception {

    public MyException(String message) {
        super(message);
    }

}

然后,我们可以在方法中抛出这个自定义异常,如下所示:

public void myMethod() throws MyException {
    // ...
    throw new MyException("Something went wrong!");
    // ...
}

这样,在编译阶段,编译器就会强制检查MyException异常是否已被处理。如果MyException异常未被处理,编译器就会报错。

当然,在某些情况下,我们也可能需要使用非受检异常来定义自定义异常类型。例如,如果我们编写一个方法,该方法可能会抛出NullPointerException异常,那么我们就应该使用非受检异常RuntimeException来定义一个自定义异常类型,如下所示:

public class MyRuntimeException extends RuntimeException {

    public MyRuntimeException(String message) {
        super(message);
    }

}

然后,我们可以在方法中抛出这个自定义异常,如下所示:

public void myMethod() {
    // ...
    throw new MyRuntimeException("Something went wrong!");
    // ...
}

这样,在编译阶段,编译器不会强制检查MyRuntimeException异常是否已被处理。只有在运行时,如果MyRuntimeException异常被抛出,才会被发现。

总之,在编写Java程序时,我们应该根据业务需求选择合适的异常类型来定义自定义异常类型。一般来说,我们应该尽量使用受检异常Exception来定义自定义异常类型,只有在特殊情况下,我们才应该使用非受检异常RuntimeException来定义自定义异常类型。