编译Java与assert someBoolean()之间禁用的断言有区别吗?和verifySomeBoolean();后者包含断言?

时间:2012-11-09 18:56:10

标签: java design-patterns assert assertions

我有一个后置条件我想定期检查,跨很多方法。我相信我正在使用断言correctly,即只检查一些东西以确保我的代码没有做任何愚蠢的事情,我打算在一段时间后关闭断言。但我不确定我现在写的后置条件正是我一直想要的条件。所以我把它放入一个方法中。但后来我遇到了以下问题:

public class Foo
{
    public void doSomethingRisky()
    {
        //...
        assert someBoolean();
    }

    private boolean someBoolean()
    {
        return bar && baz;
    }
}

VS

public class Foo
{
    public void doSomethingRisky()
    {
        //...
        verifySomeBoolean();
    }

    private void verifySomeBoolean()
    {
        assert bar && baz;
    }
}

我知道如果编译w / disabled断言,前一段代码将没有性能命中,因为someBoolean()永远不会被调用。但Java是否“足够聪明”,如果禁用断言,第二种形式也会在禁用断言时没有性能损失?

显然,更重要的问题是哪种更好的做法?

我喜欢assert someBoolean(),因为它是明确的,不会受到重复或误解,但似乎另一种形式可能会更加未来的证明,因为我可能会想要扩展其行为verifySomeBoolean()除了声明相同的底层布尔值之外还要做一些事情。虽然我的直觉说如果是这样的话,我最好重新编码,而不是试图将旧代码刷新。任何来自智者的话都会非常感激。

1 个答案:

答案 0 :(得分:2)

我以为你没有编译掉断言?我认为它们已经编译,只能由java -ea的JVM启用。

在这种情况下,当未使用-ea时,JVM将优化掉空呼叫。但是你已经成熟地进行了优化。使代码易于理解和编写。然后优化第二。调用空方法不会导致性能问题。

更新

就风格而言,我会尽可能接近问题。我不喜欢在方法中断言只是为了检查。

其次,assert()和Guava Preconditions有两个不同的应用程序。应该使用assert来检查您的世界是否仍然是您认为的世界。它更像是assert (1+1 == 2)类型的东西。你不要在callee参数上使用assert()。你使用assert检查你知道的东西必须是真的,但无论如何都要检查它。

番石榴先决条件看起来应该是你应该使用的。这是输入验证,用于检查合同合规性。例如:检查空参数,仅使用自然数时的负数,正确格式化的字符串等。

总而言之,断言()是“让我确保引力仍在这里,即使我知道它是”,前提条件是“让我确保我试图快速行驶然后警察允许”< / p>