在大多数情况下,从代码设计的角度来看,在抛出异常时使用现有的通用 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