为什么在java中默认情况下不启用assert

为什么在java中默认情况下不启用assert,java,jvm,assert,Java,Jvm,Assert,我的问题是从语言设计的角度 为什么assert会被区别对待,即它会引发错误而不是异常,默认情况下未启用等等 它看起来很优雅(非常主观的意见),易于阅读(同样主观),用于进行验证&还有一些工具(IDE)可以根据断言对其进行实时评估并提供警告。它会引发一个错误,因为断言违反的严重性足够高 异常的一个示例类似于ArrayIndexOutOfBounds。在某些情况下,这可能是合理的,您甚至可能期望(并处理)这样的情况 但是断言冲突(例如,内存不足)是您从未期望或希望处理的事情。这是一个错误,没有任何借

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

为什么assert会被区别对待,即它会引发错误而不是异常,默认情况下未启用等等


它看起来很优雅(非常主观的意见),易于阅读(同样主观),用于进行验证&还有一些工具(IDE)可以根据断言对其进行实时评估并提供警告。

它会引发一个错误,因为断言违反的严重性足够高

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

但是断言冲突(例如,内存不足)是您从未期望或希望处理的事情。这是一个错误,没有任何借口

默认情况下不会启用断言,因为它们应该始终是满的。您可以让它们进行测试,但是您“知道”(就您所知)它们没有被违反。因此,您不需要每次在生产代码中检查条件(这可能是性能密集型的)

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

例如:

if (!doComplexChecks()) throw new AssertionError("Damn!");
可能需要很多时间,您希望在单元测试或调试时验证这一点,但在生产中您不希望这样

但是这个代码

assert doComplexChecks();

只有在启用断言时才会执行,因此它在生产代码中为您节省了大量时间。

我想说的原因是Java的默认值是针对生产代码的(软件的“发布”版本)-如果用户需要构建您的代码,他们将使用提供的默认值,如果您是开发人员,并且希望有更好的报告,您可以随时进行一些额外的工作

通常,您不希望在发布版本中附带断言。为什么?您可以将代码设计为执行一些不干扰后台的错误处理,并在用户面前抛出
AssertionError
,这并不总是正确的做法

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


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

断言是开发人员的工具

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

assert
是一种用于开发过程和测试的工具,在生产环境中实际运行时不应影响性能


设想一个非常重的断言,在构建一个新特性或针对整个允许输入范围的更改时,这些断言非常重要,但一旦构建并正确测试,就不需要运行,直到代码再次更改。

这可能会帮助您,问与答确实是一个很好的解释。我真的很想知道为什么现在是这样。为什么断言失败必须使程序不可恢复(至少引发的错误倾向于它)。为什么默认情况下不必启用它。