【问题标题】:Precondition and postcondition checks in public methods公共方法中的前置条件和后置条件检查
【发布时间】:2017-11-12 23:03:47
【问题描述】:

我正在阅读 Oracle documentation 关于使用 assert 关键字来验证方法前置条件和后置条件的内容。

文档说可以使用assert 关键字来验证public 方法的后置条件,但您应该只使用assert 关键字来验证private 方法的前置条件。

这是为什么?

【问题讨论】:

标签: java assert preconditions post-conditions


【解决方案1】:

一个完整的答案,而不是把它倾倒在 cmets 中。

为什么我不应该在公共方法中使用断言来检查参数?

依赖于assert 的断言可以被 JVM 标志禁用。因此,当您的用户运行您的代码时,无法保证断言确实会运行。这就是为什么如果你不能保证它会发生,那么在你的 API 中抛出验证错误是不好的。因此,您允许您的用户使用无效参数调用您,而不会抛出异常来警告他们。您应该改用运行时异常。

那么,为什么可以将它用于公共方法中的后置条件?

您引用的文档定义了前置条件和后置条件:

前提条件——调用方法时必须满足的条件。 后置条件——方法完成后必须为真 成功。

您可以看到前置条件取决于调用者,而后置条件取决于被调用者。如果满足前置条件,后置条件可能失败的唯一原因是方法中的代码有问题。这不是用户的错误,而是库本身的问题。我猜这就是为什么文档认为最终禁用后置条件断言的问题更小。

我不确定我个人是否同意,因为如果不满足后置条件,则可能意味着该方法的合同已被违反并且应该停止执行。取决于后置条件的关键程度。 API 编写者可能希望在动态数组调整大小结束时检查某个比率是否对性能而言是最佳的,但如果不是这种情况,则不一定会抛出异常,因为即使使用次优比率,程序仍会按预期运行。

【讨论】:

    【解决方案2】:

    在所有情况下,您都应该检查 public 函数的参数。如果assert被禁用,那么如果通过assert实现,这种检查将无法完成。

    【讨论】:

    • 我在问为什么可以在公共方法中验证后置条件而不是前置条件。我仍然很困惑,我认为我的问题没有得到解答。
    • @Ogen 依赖于assert 的断言可以被JVM 标志禁用。因此,当您的用户运行您的代码时,无法保证断言确实会运行。这就是为什么如果你不能保证它会发生,那么承诺在你的 API 中抛出验证错误是不好的。您应该改用运行时异常。
    • 好吧,你的意思是断言不应该用来代替公共方法中的参数检查,因为调用者可能关闭了断言——在这种情况下,你的断言检查将不会运行。如果是这样,为什么要使用断言来验证公共方法中的后置条件呢?为什么不在那里也使用标准参数检查?
    • @Ogen 我不相信在文档中看到这一点,但我没有阅读所有内容。我想说断言不适合任何公共运行时检查。老实说,它们产生的错误不如异常好,所以我个人不会在任何情况下推荐它们
    • @Dici 我知道这是一个固执己见的事情。但是 oracle 文档清楚地表明您可以将 assert 用于公共后置条件和私有前置条件。我认为它们的用处超出了这个问题的范围。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多