【问题标题】:Should methods that throw RuntimeException indicate it in method signature?抛出 RuntimeException 的方法是否应该在方法签名中指出它?
【发布时间】:2010-10-23 21:05:15
【问题描述】:

例如,框架/JDK 中的许多方法可能会抛出

java.lang.SecurityException 

但这并没有在方法签名中指出(因为这通常是为检查的异常保留的做法)。 我想说在方法 sigs 中声明 RuntimeExceptions 有很多好处(例如类似于静态类型检查)。我喝醉了吗?

【问题讨论】:

    标签: java exception oop exception-handling


    【解决方案1】:

    我不会在签名中声明未经检查的异常,因为它会误导该 API 的用户。是否必须显式处理异常不再明显。

    在 javadoc 中声明它是一种更好的方法,因为它允许某人在认为有必要时处理它,但知道如果他们愿意可以忽略它。这使得选中和未选中之间的区别变得清晰。

    【讨论】:

    • java 编译器不会强迫你处理声明的 RuntimeExceptions。因此,您可以声明它们,目的是为开发人员提供“提示”。如果 JavaDoc 是一个更好的地方,这是可以讨论的。关于已检查和未检查异常的这一点很重要。 Checked 和 unchecked Exceptions 就是 Java 对 (Compiletime-)Exceptions (checked) 和 RuntimeExceptions (unchecked) 的真正含义。
    • 在 Spring 中,在方法签名中声明未经检查的异常开始成为一种常见的做法。
    【解决方案2】:

    来自the Oracle Java tutorial

    "如果记录方法的 API 非常好,包括异常 它可以抛出,为什么不指定运行时异常呢?” 运行时 异常表示编程导致的问题 问题,因此,API 客户端代码不能合理地 期望从他们身上恢复或以任何方式处理他们。这样的 问题包括算术异常,例如除以零; 指针异常,例如试图通过 null 访问对象 参考;和索引异常,例如尝试访问 通过索引太大或太小的数组元素。

    运行时异常可以发生在程序的任何地方,并且在典型的 他们可以是非常多的。 必须添加运行时异常 每个方法声明都会降低程序的清晰度。

    【讨论】:

    • 因此,编译器不需要您捕获或指定运行时异常(尽管您可以)。
    【解决方案3】:

    查看 Collection#add 的 javadoc

    提到了一大堆未经检查的异常:

    Throws:
    UnsupportedOperationException - add is not supported by this collection.
    ClassCastException - class of the specified element prevents it from being added to this collection.
    NullPointerException - if the specified element is null and this collection does not support null elements.
    IllegalArgumentException - some aspect of this element prevents it from being added to this collection.
    

    如果您有耐心,我建议您以这种方式彻底记录您的方法可能引发的异常。在某种程度上,对未经检查的异常执行此操作更为重要,因为检查的异常在某种程度上是自记录的(编译器强制调用代码确认它们)。

    【讨论】:

    • 这个答案是错误的。您正在谈论 Javadoc 语句,而方法签名中的问题是 throws。这些不是一回事。是的,你绝对应该记录你的 API 抛出的所有异常,但问题不在于这个。
    【解决方案4】:

    在我看来,至少在方法的 javadoc 中声明运行时异常会更好。在签名中声明它可以更清楚地说明出现问题时可能发生的情况。这是我建议提供此信息的主要原因。

    仅供参考:随着时间的推移(现在是 2017 年),我现在更倾向于仅在 javadoc 中记录它们并尽可能避免检查异常。

    【讨论】:

    • 不应该避免未检查的异常而不是“避免检查的异常”吗?
    • 不,因为检查异常是一个痛苦的背后。它迫使您处理或声明它们。有时你不能(lambdas!),那么你必须将它包装在运行时异常中。所以最好声明它们,让程序员决定什么 get 的句柄在哪里以及什么应该传播到顶部。
    【解决方案5】:

    在我看来,未经检查的异常不应该在方法签名中声明,因为这与其性质相反。

    但是,如果某个方法可能会抛出一些未经检查的异常,请注意 Javadoc 中 @throws 中可能出现的情况,这可能有助于其他调用该方法的人了解可能出现的问题。这仅对调用者可能能够处理的异常(例如由于输入错误等导致的 NPE)有用。

    【讨论】:

      【解决方案6】:

      如果您正在编写供他人使用的 api,那么有充分的理由在 api 中明确记录您的意图,并且在方法签名中声明 RuntimeExceptions 没有任何不利之处。

      【讨论】:

        【解决方案7】:

        这与关于checked exceptions 的讨论有关。大多数人都同意不应在方法签名中声明异常。

        还有一个discussion 关于应该如何使用运行时异常。我同意一位发帖者的观点,即运行时异常应该表示编程错误或致命情况。因此,在签名中声明它们并没有多大价值。每种方法都可能通过一种方法。

        【讨论】:

        • 解析异常或其他一些数据验证类型异常在哪里适合。您是在暗示您不应该使用受检异常,而是限制未受检异常的用途。
        • 我的意思是,不应该强迫开发人员捕获已检查的异常。所以不需要在方法签名中声明它们。在 Java 中,您可以在运行时异常中转换它们,就像 Spring 所做的那样。我还说运行时异常应该只在不可恢复的情况下抛出。
        猜你喜欢
        • 2015-08-27
        • 2011-03-19
        • 1970-01-01
        • 1970-01-01
        • 2017-07-09
        • 1970-01-01
        • 2013-03-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多