运行时是否忽略断言语句?

Are assert statements ignored during runtime?

使用以下代码,

public Some persist(final Some entity) {
    if (flag) {
        super.persist(entity);
        entity.credentials();
        update(entity);
        return entity;
    }
    assert super.persist(entity).equals(entity);
    assert entity.credentials().equals(entity);
    assert update(entity);
    return entity;
}

如果 flag 为假,语句似乎被忽略且未执行。

正常吗?或者某些断言失败了?

更新

我已经知道如何启用断言。

我想知道的是,无论是否启用 -ea 选项,整个 assert ... 语句都会被忽略。

更新

我正在用我的 spring 库尝试它们,似乎整个语句意味着生成布尔标志的代码被忽略了。

我想知道的是

  1. 是唯一忽略断言的功能,还是
  2. 忽略整个语句。

更新

我正在分享我学到的东西。这让我很震惊。

public Some persist(final Some entity) {

    // WORKS!
    super.persist(entity);
    entity.generate();
    update(entity);
    return entity;

    // WORKS!
    final Some persisted = super.persist(entity);
    assert persisted.equals(entity);
    final Some generated = entity.credentials();
    assert generated.equals(persisted);
    final boolean updated = update(generated);
    assert updated;
    return generated;

    // DOES NOT WORK!!! SHOULDN'T DO THIS!!!
    assert super.persist(entity).equals(entity);
    assert entity.generate().equals(entity);
    assert update(entity);
    return entity;
}

它们可以在 运行 时通过 java 命令的 -ea 选项激活,但默认情况下不打开。

您必须启用断言。程序启动时可以启用或禁用断言,默认情况下禁用。

禁用断言可以完全消除它们的性能损失。一旦禁用,它们本质上等同于 semantics 中的 empty 语句和性能。您可能想在 dev 中即时测试您的代码,但不想在不更改任何代码的情况下降低 prod 中的性能。

Is the only the functionality of assertion ignored

我想这就是 assertions 的全部意义所在,它使您能够测试您对程序的假设。

The whole statement are ignored

是的,当 Java 程序编译时,带有断言 enabled/disabled,它在生成的 class 文件中被标记。因此,当 class-loader 加载您的文件并且 run 如果断言被禁用,指令或行将被完全忽略。

What I want to know is that the whole assert ... statement is ignored or not regardless of enabling the -ea option.

是的,除非启用断言,否则它将被完全忽略。这可用于检测它们是否在运行时启用:

boolean assertionsEnabled = false;
assert assertionsEnabled = true;
System.out.println("Assertions enabled: " + assertionsEnabled);

我正在为我自己的问题添加一个答案以供参考。

https://docs.oracle.com/javase/8/docs/technotes/guides/language/assert.html

Do not use assertions to do any work that your application requires for correct operation. Because assertions may be disabled, programs must not assume that the boolean expression contained in an assertion will be evaluated. Violating this rule has dire consequences. For example, suppose you wanted to remove all of the null elements from a list names, and knew that the list contained one or more nulls. It would be wrong to do this:

// Broken! - action is contained in assertion
assert names.remove(null);

The program would work fine when asserts were enabled, but would fail when they were disabled, as it would no longer remove the null elements from the list. The correct idiom is to perform the action before the assertion and then assert that the action succeeded:

// Fixed - action precedes assertion
boolean nullsRemoved = names.remove(null);
assert nullsRemoved;  // Runs whether or not asserts are enabled

As a rule, the expressions contained in assertions should be free of side effects: evaluating the expression should not affect any state that is visible after the evaluation is complete. One exception to this rule is that assertions can modify state that is used only from within other assertions. An idiom that makes use of this exception is presented later in this document.