2

我在 Java 中的一些方法会抛出 NoSuchElementException、IllegalArgumentException 等异常。但是在使用这些方法时,这些异常似乎是未经检查的。换句话说,我的方法的调用者不需要对抛出这些异常的方法进行尝试/捕获。我读到似乎默认情况下异常是“检查”的,只有错误是“未检查”的。但不知何故,我抛出的异常也是未经检查的。真奇怪。

如何确保当我的方法抛出异常时,调用者必须在编译时捕获异常?简单地说,我怎样才能抛出一个已检查的异常?

谢谢!

4

6 回答 6

6

只有RuntimeException及其子类未选中。(好吧,Error它的子类也是如此,但你不应该弄乱Errors。)你需要做的就是抛出一个检查的异常是确保它不扩展RuntimeException

于 2011-06-10T04:42:43.120 回答
4

看到这个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;
    }
}
于 2016-06-10T12:56:09.280 回答
3

检查或不检查异常不是您如何抛出或声明它,它仅取决于您选择的异常是否源自 RuntimeException。您在上面列出的所有内容都派生自 RuntimeException,因此您的方法的客户端不需要捕获它们。

于 2011-06-10T04:41:35.177 回答
3

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。

于 2011-06-10T07:05:45.127 回答
1

我认为您应该退后一步,了解为什么要抛出已检查异常与未检查异常背后的理论。Java 异常教程是一个很好的资源。

从标题为未经检查的例外 - 争议的页面:

运行时异常表示由编程问题引起的问题,因此,不能合理地期望 API 客户端代码从它们中恢复或以任何方式处理它们。

于 2011-06-10T04:53:41.740 回答
0

扩展的异常RuntimeException不必声明。

您可以声明方法:throws Exception甚至throws Throwable必须处理(尽管不建议这样做)。

于 2011-06-10T04:39:08.330 回答