为什么java中没有默认启用断言

Sun*_*.V. 7 java assert jvm

我的问题是从语言设计的角度来看.

为什么断言处理方式不同,即它引发错误而不是异常,默认情况下不启用等等.

它看似优雅(非常主观的意见),易于阅读(再次主观)进行验证,还有工具(IDE)可以对其进行实时评估并根据断言提供警告.

Mat*_*zok 6

我要说的原因是Java的默认设置是为了构建软件的"发布"版本 - 如果用户需要构建你的代码,他们将使用提供的默认值,如果你是开发人员,并希望有更好的报告,你总是可以做一些额外的努力.

通常,您不希望发布具有发布版本的断言.为什么?你总是可以设计你的代码来执行一些不令人不安的背景错误处理,并且抛出AssertionError用户面孔并不总是那样.

大多数情况下,我将它们用作额外的代码测试 - 当您运行回归测试并且代码覆盖率很高时,没有断言错误表明代码中没有(明显发现)错误.如果发生某些情况,您可以从堆栈跟踪中推断出出现了什么问题以及原因.另一方面,客户不应该看到描述性错误信息.

那么你应该如何使用它们呢?根据我的经验,您应该设计代码以不使用断言来执行错误处理.如果你想在某处抛出异常,请自己明确抛出它.一旦代码可以自己处理,你可以添加断言来检查前置条件和后置条件以及不变量 - 所以基本上用它们来检查算法的正确性而不是数据的正确性.它对开发人员而不是用户有价值.一旦您对解决方案有足够的信心,就可以禁用断言,程序仍然可以正常运行,并且用户不必运行带有额外运行时开销的程序.


Ray*_*Ray 6

断言是开发人员的工具。

默认情况下不启用它的核心原因是断言通过assert并不意味着为生产代码提供运行时验证/保护。

assert 是在开发过程和测试期间使用的工具,在生产环境中的实际运行期间不应影响性能。

想象一下在构建新功能或针对整个允许输入范围进行更改时检查非常重要的权重断言,但一旦构建并正确测试,就不需要运行直到再次更改代码。


Uni*_*rsE -1

它会引发错误,因为断言违规的严重性足够高,足以这样做。

异常的一个例子是这样的ArrayIndexOutOfBounds。在某些情况下这可能是合理的,您甚至可能期望(并处理)这种情况。

但是断言违规(例如内存不足)并不是您所期望或想要处理的。这是一个错误,没有任何借口。

默认情况下不启用断言,因为它们应该始终被填充。您让他们能够对此进行测试,但随后您“知道”(据您所知)它们没有受到侵犯。因此,您不需要每次在生产代码中检查条件(这可能是性能密集型的)。

Java 中断言的好处是,当未启用断言时,实际执行检查的代码永远不会执行。

例如:

if (!doComplexChecks()) throw new AssertionError("Damn!");
Run Code Online (Sandbox Code Playgroud)

可能需要很多时间,并且您希望在单元测试或调试时验证这一点,但在生产中您只是不希望这样做。

但是这段代码

assert doComplexChecks();
Run Code Online (Sandbox Code Playgroud)

仅在启用断言时执行,因此它可以在生产代码中节省大量时间。