【问题标题】:Throw checked exceptions抛出检查异常
【发布时间】:2011-06-10 04:37:47
【问题描述】:

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

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

谢谢!

【问题讨论】:

    标签: java exception exception-handling checked-exceptions


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      看到这个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;
          }
      }
      

      【讨论】:

        【解决方案3】:

        检查或不检查异常是NOT你如何抛出或声明它,它只取决于你选择的异常是否来自RuntimeException。你上面列出的,都是从 RuntimeException 派生的,所以你的方法的客户端不需要捕获它们。

        【讨论】:

          【解决方案4】:

          检查 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。

          【讨论】:

          • 这个方法在十多年前就被弃用了,将在未来的版本中删除。永远不应该使用。 docs.oracle.com/javase/9/docs/api/java/lang/…
          • @Miha_x64 它在 Java 8 中被禁用。还有其他方法可以做同样的事情,这个答案应该更新。
          【解决方案5】:

          我认为你应该退后一步,了解为什么抛出受检异常与未受检异常背后的理论。关于异常的Java tutorial 是一个很好的资源。

          来自标题为Unchecked Exceptions — The Controversy的页面:

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

          【讨论】:

            【解决方案6】:

            扩展RuntimeException 的异常不必声明。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-07-21
              • 1970-01-01
              • 2011-06-01
              • 1970-01-01
              • 1970-01-01
              • 2011-09-21
              • 2016-11-13
              • 1970-01-01
              相关资源
              最近更新 更多