1

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

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

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

对比

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

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

我知道如果我用禁用的断言编译,以前的代码不会有性能影响,因为someBoolean()永远不会被调用。但是,Java 是否足够“智能”,以至于在禁用断言的情况下,第二种形式在禁用断言的情况下也不会对性能造成影响?

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

我喜欢它,assert someBoolean()因为它是明确的,不受重新或误解的影响,但似乎另一种形式可能更适合未来证明,因为verifySomeBoolean()除了断言相同的基础之外,我可能还想扩展做某事的行为布尔值。虽然我的直觉说如果是这样的话,我最好重新编码而不是试图弄脏旧代码以适应。智者的话将不胜感激。

4

1 回答 1

2

我以为你没有编译出断言?我以为它们是编译过的,只能由 JVM 启用java -ea

在这种情况下,将由 JVM 在-ea不使用时优化空调用。但是您正在过早地进行优化。使代码易于理解和编写。然后进行第二次优化。调用空方法不会导致性能问题。

更新:

就风格而言,我会使用尽可能接近问题的断言。我不喜欢仅用于检查的方法中的断言。

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

Guava Preconditions 看起来是你应该使用的。这是输入验证,用于检查合同合规性。诸如:检查空参数、仅应使用自然数时的负数、格式正确的字符串等。

总而言之,assert() 是“让我确保重力仍然在这里,即使我知道它是”,前提条件是“让我确保我试图以比警察允许的速度更快的速度行驶”

于 2012-11-09T19:00:12.630 回答