【问题标题】:What does the "assert" keyword do? [duplicate]“assert”关键字有什么作用? [复制]
【发布时间】:2011-03-02 09:54:51
【问题描述】:

assert 是做什么的? 例如在函数中:

private static int charAt(String s, int d) {
    assert d >= 0 && d <= s.length();
    if (d == s.length()) return -1;
    return s.charAt(d);
}

【问题讨论】:

    标签: java assert assertion


    【解决方案1】:

    如果你使用-enableassertions(或简称-ea)启动你的程序,那么这个语句

    assert cond;
    

    等价于

    if (!cond)
        throw new AssertionError();
    

    如果您在没有此选项的情况下启动程序,则断言语句将无效。

    例如,assert d &gt;= 0 &amp;&amp; d &lt;= s.length();,在您的问题中发布,相当于

    if (!(d >= 0 && d <= s.length()))
        throw new AssertionError();
    

    (如果您使用-enableassertions 启动。)


    Java Language Specification: 14.10. The assert Statement 正式地说如下:

    14.10。 assert 语句
    断言是包含布尔表达式的 assert 语句。断言启用或禁用。如果启用了断言,则执行断言会导致对布尔表达式求值,如果表达式求值为 false,则报告错误。如果断言被禁用,则断言的执行没有任何效果。

    其中“启用或禁用” 由-ea 开关控制,“报告错误” 表示抛出AssertionError。


    最后,assert 的一个鲜为人知的功能:

    您可以像这样附加: "Error message":

    assert d != null : "d is null";
    

    指定抛出的 AssertionError 的错误信息应该是什么。


    此帖已改写为文章here。

    【讨论】:

    • 同意,断言不应用于确保论证的有效性,而应用于指出强有力的假设。
    • 使用assert 测试非公开 方法的precondition 是完全有效的IMO。
    • 如果客户有责任确保参数在范围内,那么使用断言是一种很好的编码风格。正如 Bertrand Meyer(按合同设计)所论证的那样,这种假设避免了重复检查。在公共 API 中使用 IllegalArgumentException 是一种很好的方式。另请参阅此 answer 到相关的 stackoverflow 问题。
    • 我看到 java 中的 assert 很像 c 或 c++ 中的调试宏。如果你运行一些非常大的测试,你可以使用它们。但是,当您“运行”应用程序时,您可以将它们排除在外,这样您可以获得更快的性能。我认为它并没有真正用作参数变量检查,而是更深入地用于可以检查各种变量的代码。就像 ' 我们做了 4 或 5 个循环,而在所有条件下都只需要 4 个。
    • 我们应该从生产代码中删除包含assert 的代码吗?
    【解决方案2】:

    虽然我已经阅读了很多关于这个的文档,但我仍然对如何、何时以及在何处使用它感到困惑。

    让它很容易理解:

    当你遇到类似这样的情况时:

        String strA = null;
        String strB = null;
        if (2 > 1){
            strA = "Hello World";
        }
    
        strB = strA.toLowerCase(); 
    

    您可能会收到警告(在 strB = strA.toLowerCase(); 上显示黄线)strA 可能会为 strB 生成 NULL 值。虽然你知道strB最后绝对不会为null,但以防万一,你用assert来

    1.禁用警告。

    2。如果发生最糟糕的事情(运行应用程序时),则抛出异常错误。

    有时,当您编译代码时,您没有得到结果,这是一个错误。但是应用程序不会崩溃,而且您要花很长时间才能找到导致此错误的原因。

    所以,如果你把断言,像这样:

        assert strA != null; //Adding here
        strB = strA .toLowerCase();
    

    你告诉编译器 strA 绝对不是空值,它可以“和平地”关闭警告。如果它为 NULL(最坏的情况发生),它将停止应用程序并向您抛出一个错误来定位它。

    【讨论】:

      【解决方案3】:

      assert 是一个调试工具,如果条件不成立,会导致程序抛出AssertionFailed 异常。在这种情况下,如果程序后面的两个条件中的任何一个评估为假,程序就会抛出异常。 一般来说,assert 不应该用在生产代码中

      【讨论】:

      • 不一定会导致程序崩溃。事实上,您可以捕获AssertionError,就像任何其他异常一样。
      • 而且由于断言需要显式启用才能产生任何效果,因此在生产代码中使用它们并没有什么坏处。
      • 啊我的错,是不是在C语言中它们更麻烦?那可能是我从……那里记住那个范式的地方。
      • 好吧,我必须说我同意。 Java 断言不应在生产代码中使用。 IE。不应告知客户端使用-ea 开关启动。
      【解决方案4】:

      断言通常主要用作检查程序预期行为的一种手段。在大多数情况下它会导致崩溃,因为程序员对程序状态的假设是错误的。这就是断言的调试方面的用武之地。它们创建了一个检查点,如果我们想要正确的行为,我们根本不能忽略它。

      在您的情况下,它会对传入参数进行数据验证,尽管它不会阻止客户端将来滥用该函数。特别是如果它们没有(也不应该)包含在发布版本中。

      【讨论】:

        【解决方案5】:

        如果您在打开断言的情况下运行应用,Assert 确实会引发 AssertionError。

        int a = 42;
        assert a >= 0 && d <= 10;
        

        如果你运行它,说:java -ea -jar peiska.jar

        它会抛出一个java.lang.AssertionError

        【讨论】:

          【解决方案6】:

          如果条件不满足,将抛出AssertionError。

          但是必须启用断言;否则 assert 表达式什么也不做。见:

          http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html#enable-disable

          【讨论】:

            【解决方案7】:

            使用此版本的 assert 语句为 AssertionError 提供详细消息。系统将 Expression2 的值传递给相应的 AssertionError 构造函数,该构造函数使用该值的字符串表示形式作为错误的详细消息。

            详细消息的目的是捕获和传达断言失败的详细信息。该消息应该允许您诊断并最终修复导致断言失败的错误。请注意,详细消息不是用户级别的错误消息,因此通常没有必要将这些消息孤立地理解,或者将它们国际化。详细消息旨在结合包含失败断言的源代码在完整堆栈跟踪的上下文中进行解释。

            JavaDoc

            【讨论】:

              【解决方案8】:

              它确保表达式返回 true。否则,它会抛出一个java.lang.AssertionError。

              http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.10

              【讨论】:

                猜你喜欢
                • 2020-08-23
                • 1970-01-01
                • 2019-09-17
                • 2017-10-11
                • 2012-07-01
                • 2019-09-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多