断言声明真的有什么好处。我不明白为什么我需要使用它。我阅读了近 100 个关于断言语句的问题/答案,但仍然不知道它有什么好处。我认为这个说法有太多的冲突。
例如,有些人说“永远不要在生产中使用它”,但有些人说“你可以在生产级别使用它们”。有些人说“总是在生产中处理 assertionErrors”,但有些人说“永远不要在生产或开发级别处理 assertionErrors”。
为什么这是不正确的用法,例如https://stackoverflow.com/a/2758262/1379734
断言声明真的有什么好处。我不明白为什么我需要使用它。我阅读了近 100 个关于断言语句的问题/答案,但仍然不知道它有什么好处。我认为这个说法有太多的冲突。
例如,有些人说“永远不要在生产中使用它”,但有些人说“你可以在生产级别使用它们”。有些人说“总是在生产中处理 assertionErrors”,但有些人说“永远不要在生产或开发级别处理 assertionErrors”。
为什么这是不正确的用法,例如https://stackoverflow.com/a/2758262/1379734
为什么这会被认为是不正确的?
public int pop() {
// precondition
assert !isEmpty() : "Stack is empty";
return stack[--num];
}
assert
应该表达一个不变的条件。如果pop()
是一个private
方法,那么您可以期望它只应该由检查空堆栈的代码调用。因为此方法是public
,所以您无法控制可以在调用者中强制执行的假设。在这种情况下,堆栈下溢应该导致Exception
.
再一次,是对必须assert
为真的事情的声明,而不是可能为真的事情。“可能”条件应该通过其他运行时检查来强制执行,而不是在断言中声明。
是否在生产中启用断言取决于偏好。这样做的理由是断言不应该失败,因此它们在生产中应该是安全的。反对这样做的论据是性能损失(某些assert
条件的计算成本可能很高),以及投掷投掷物的破坏性Error
。
你似乎在寻找简单的东西,它总是一个好主意,或者它从来都不是一个好主意。不是这种情况。它有一些有意义的用例,在有限的情况下,您希望避免使用它们以提高性能,但这非常罕见。
有些人对断言的了解并不比你多,但很乐意发表意见。我建议您得出自己的结论,并在适合您的地方使用它。
关于错误和异常,我建议只处理这些地方
出于这个原因,我在线程的最高级别(就在它死之前)捕获 Throwable 并确保它被正确记录。在所有其他情况下,我只捕获我可以做一些有用的异常。
断言需要处理开销。从理论上讲,如果它们通过了测试,就没有理由在生产中重新运行它们。您的测试可能不完整,并且断言可能会捕获测试期间未解决的意外情况,但希望日志可以让您找出问题所在,而无需运行断言。