assert语句是否在运行时被忽略?

时间:2017-11-06 06:47:06

标签: java assert

使用以下代码

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为假,则似乎忽略语句而不执行。

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

更新

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

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

更新

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

我想知道的是

  1. 是否仅忽略断言的功能,或
  2. 整个陈述都被忽略了。
  3. 更新

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

    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;
    }
    

4 个答案:

答案 0 :(得分:3)

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

禁用断言完全消除了它们的性能损失。一旦禁用,它们基本上等同于<?php $dom=simplexml_load_string($your_html_source_string); $results=$dom->xpath('//div[@id="first"]/*'); $innerHtml=""; foreach($results as $result) { $innerHtml.=$result->saveXML(); } echo $innerHtml; 中的empty语句和性能。您可能希望在semantics中快速测试代码,但不希望在不更改任何代码的情况下降低dev中的效果。

  

断言的唯一功能是否被忽略

我想这是prod的重点,它可以让你测试你对程序的假设。

  

整个陈述被忽略

是,编译assertions程序时,如果启用/禁用断言,则会在生成的类文件中标记它。因此,当类加载器加载文件并Java时,如果禁用断言,则完全忽略指令或行。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

  

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

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

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

答案 3 :(得分:1)

我正在为自己的问题添加一个答案,以提供信息。

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

  

不要使用断言来执行应用程序正确操作所需的任何工作。   因为断言可能被禁用,所以程序不能假定将评估断言中包含的布尔表达式。违反这一规则会产生可怕的后果。例如,假设您要从列表名称中删除所有null元素,并且知道该列表包含一个或多个空值。这样做是错误的:

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

当启用断言时,程序可以正常工作,但是当它们被禁用时会失败,因为它不再从列表中删除null元素。正确的习惯用法是在断言之前执行操作,然后断言操作成功:

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

通常,断言中包含的表达式应该没有副作用:评估表达式不应该影响评估完成后可见的任何状态。此规则的一个例外是断言可以修改仅在其他断言中使用的状态。本文后面将介绍使用此异常的习语。