Java中如何自定义异常

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

  • UnsupportedOperationException - 不支持某个操作
  • IllegalArgumentException - 传递给方法的参数值无效
  • IllegalStateException - API 在内部达到了不应该发生的情况,或者由于以无效方式使用 API 而发生的情况

我们确实想要使用自定义异常类的情况包括:

  • 我们正在编写供他人使用的 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 文档:

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

日期:2020-06-02 22:15:20 来源:oir作者:oir