【问题标题】:"assert" in java [duplicate]java中的“断言”
【发布时间】:2011-12-10 22:29:18
【问题描述】:

可能重复:
What does assert do?

什么是“断言”? “assert”关键字是干什么用的?它何时何地有用?

这是一个来自红黑树实现的方法示例:

public Node<K,V> grandparent() {
    assert parent != null; // Not the root node
    assert parent.parent != null; // Not child of root
    return parent.parent;
}

我不知道这段代码中使用了什么“断言”。我们不能以其他方式键入此代码,例如使用“if's”代替吗?

【问题讨论】:

标签: java assert


【解决方案1】:

断言用于测试关于运行代码的假设。它们与if 检查在许多方面不同:

  • 默认情况下,断言在运行时被禁用
  • 不应将断言用于参数检查或程序正常运行所需的任何其他内容。
  • 断言通常测试您之前可能在评论中看到的状态假设。例如,您可以使用断言来验证您没有违反循环不变量或方法的先决条件是否已得到满足。

if 语句用于控制流、参数检查等。断言用于在开发和调试过程中推理内部方法的正确性等。

在实践中,这两行:

assert parent != null; // Not the root node
assert parent.parent != null;

...强制调用此方法时parentparent.parent 都不是null。如果其中任何一个断言失败,程序将抛出AssertionError

【讨论】:

  • 另请注意,该 sn-p 的作者很可能mis使用了assert。正如你所说,断言用于参数检查。
  • 所以上面的方法是错误断言应用的例子。
  • 事实上,assert 的这种用法并没有“错误”,但它可能并不像它可能的那么有用。如果父parentnull,则在解引用时会在return语句中抛出NullPointerException。因此,第一个断言更多地用作文档,而不是在开发和测试期间可以检测到null 值的实用方法。第二个assert 语句将“提前失败”,这可能很有用,而不是等待稍后可能需要更多工作才能追溯的失败。但是,assert 语句只是生产代码的文档。
【解决方案2】:

如果条件 (parent != null) 为假,assert parent != null 将抛出 AssertionError。这可用于检测应用程序中的错误。

您可以对if 执行相同的操作,但可以在运行时使用-ea JVM 参数启用或禁用断言。当它们被禁用时,它们对性能的影响为 0,而ifs 始终会被执行。

当然,这确实意味着您不应该将它们用于关键检查,例如检查异常用户输入或 IO 错误的检查。大多数情况下,您无论如何都希望使用if,除非它们对性能有重大影响。

【讨论】:

    【解决方案3】:

    来自Java Language Specification, section 14.10

    断言是包含布尔表达式的语句。断言被启用或禁用。如果启用了断言,则对断言的评估会导致对布尔表达式的评估,如果表达式评估为 false,则会报告错误。如果断言被禁用,则对断言的评估没有任何影响。

    点击链接了解更多详情。

    就个人而言,我通常更喜欢始终启用的检查 - 我不喜欢在生产中更改代码的行为(以危险的方式,即允许在奇怪的情况下继续执行)。这有点像决定在慢速行驶时系上安全带,但在比赛中解开它......

    【讨论】:

    • 关于最后一段:虽然我同意你可以在那里找到一些很难找到的错误(经典的assert mutatingFunction()),但我喜欢能够将一些非常昂贵的测试放入断言中(即检查某些大型数据结构完整性的功能),我在生产代码中确实无法做到。另一方面,我在断言中看到的另一个问题是,它们导致程序员在他们显然应该担心的情况下不担心错误处理。
    【解决方案4】:

    Assert 是一个调试工具:它测试一个条件并在条件不成立时抛出一个AssertionError。您可以使用它来检查算法的前置条件、不变量和后置条件是否成立。不要将其用于输入验证;它旨在捕捉程序员的错误。

    【讨论】:

      【解决方案5】:

      在这种情况下,断言用于确保先决条件为真。详情见design by contract

      【讨论】:

        猜你喜欢
        • 2014-01-15
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多