自定义异常

在大多数情况下,从代码设计的角度来看,在抛出异常时使用现有的通用 Exception 类更为简单。如果你只需要异常来携带简单的错误消息,则尤其如此。在这种情况下,通常首选 RuntimeException ,因为它不是一个经过检查的 Exception。常见的错误类存在其他异常类:

确实想要使用自定义异常类的情况包括以下内容:

  • 你正在编写供其他人使用的 API 或库,并且你希望允许 API 的用户能够专门捕获和处理 API 中的异常,并能够将这些异常与其他更通用的异常区分开来
  • 你在程序的某个部分中抛出了特定类型错误的异常,你希望在程序的另一部分中捕获并处理这些异常,并且你希望能够将这些错误与其他更通用的错误区分开来。

你可以通过为未经检查的异常扩展 RuntimeException 来创建自己的自定义异常,或者通过扩展任何不是 RuntimeException 的子类的 Exception 检查异常,因为:

不是 RuntimeException 子类的 Exception 子类是已检查的异常

public class StringTooLongException extends RuntimeException {
    // Exceptions can have methods and fields like other classes
    // those can be useful to communicate information to pieces of code catching
    // such an exception
    public final String value;
    public final int maximumLength;

    public StringTooLongException(String value, int maximumLength){
        super(String.format("String exceeds maximum Length of %s: %s", maximumLength, value));
        this.value = value;
        this.maximumLength = maximumLength;
    }
}

这些可以用作预定义的异常:

void validateString(String value){
    if (value.length() > 30){
        throw new StringTooLongException(value, 30);
    }
}

并且可以在捕获和处理异常的地方使用这些字段:

void anotherMethod(String value){
    try {
        validateString(value);
    } catch(StringTooLongException e){
        System.out.println("The string '" + e.value + 
                "' was longer than the max of " + e.maximumLength );
    }
}

请记住,根据 Oracle 的 Java 文档

[…]如果可以合理地期望客户端从异常中恢复,则将其作为已检查的异常。如果客户端无法执行任何操作以从异常中恢复,请将其设置为未经检查的异常。

更多: