我在 Java 中的一些方法会抛出 NoSuchElementException、IllegalArgumentException 等异常。但是在使用这些方法时,这些异常似乎是未经检查的。换句话说,我的方法的调用者不需要对抛出这些异常的方法进行尝试/捕获。我读到似乎默认情况下异常是“检查”的,只有错误是“未检查”的。但不知何故,我抛出的异常也是未经检查的。真奇怪。
如何确保当我的方法抛出异常时,调用者必须在编译时捕获异常?简单地说,我怎样才能抛出一个已检查的异常?
谢谢!
我在 Java 中的一些方法会抛出 NoSuchElementException、IllegalArgumentException 等异常。但是在使用这些方法时,这些异常似乎是未经检查的。换句话说,我的方法的调用者不需要对抛出这些异常的方法进行尝试/捕获。我读到似乎默认情况下异常是“检查”的,只有错误是“未检查”的。但不知何故,我抛出的异常也是未经检查的。真奇怪。
如何确保当我的方法抛出异常时,调用者必须在编译时捕获异常?简单地说,我怎样才能抛出一个已检查的异常?
谢谢!
只有RuntimeException
及其子类未选中。(好吧,Error
它的子类也是如此,但你不应该弄乱Error
s。)你需要做的就是抛出一个检查的异常是确保它不扩展RuntimeException
。
看到这个hack,它可能会有所帮助(希望它不是 OT)。
public class Test {
// No throws clause here
public static void main(String[] args) {
doThrow(new SQLException());
}
static void doThrow(Exception e) {
Test.<RuntimeException> doThrow0(e);
}
@SuppressWarnings("unchecked")
static <E extends Exception> void doThrow0(Exception e) throws E {
throw (E) e;
}
}
检查或不检查异常不是您如何抛出或声明它,它仅取决于您选择的异常是否源自 RuntimeException。您在上面列出的所有内容都派生自 RuntimeException,因此您的方法的客户端不需要捕获它们。
Throwable 的所有子类都被检查,除了 Error 和 RuntimeException 的子类。(你可以直接继承Throwable)
编译器检查这些异常,但是它们在运行时没有特殊的位置。即你可以在编译器不知道的情况下抛出一个检查异常,它会正常运行。
例如
public static void throwChecked(Throwable t) /* no throws clause */ {
Thread.currentThread().stop(t);
}
public static void main(String... args) /* no throws clause */ {
throwChecked(new Throwable());
}
如您所料,这将编译并打印 Throwable。
我认为您应该退后一步,了解为什么要抛出已检查异常与未检查异常背后的理论。Java 异常教程是一个很好的资源。
从标题为未经检查的例外 - 争议的页面:
运行时异常表示由编程问题引起的问题,因此,不能合理地期望 API 客户端代码从它们中恢复或以任何方式处理它们。
扩展的异常RuntimeException
不必声明。
您可以声明方法:throws Exception
甚至throws Throwable
必须处理(尽管不建议这样做)。