【发布时间】:2014-02-26 21:08:35
【问题描述】:
我在 Java 中以标准方式使用断言,并在我的 IDE 中打开它们。所以它们不是生产版本的一部分。最近我看到throw new AssertionError() 的代码示例,我开始思考应该使用AssertionError 而不是断言的情况。
我的猜测是,主要区别在于断言的可选性,因此它们不会降低生产性能,因此它们可以在代码中经常出现,但修复用户报告的难以重现的错误更难。
对于AssertionError,正好相反。
我还发现AssertionError 在代码中不应执行的地方更实用,而不是使用assert false //We should not be here。特别是如果需要返回值。例如:
int getFoo(AnEnum a){
if (a == AnEnum.ONE)
return bar();
else if (a == AnEnum.TWO)
return SOME_VALUE;
//else
assert false; //throw new AssertionError();
return -1; //not necessary when usin AssertionError
}
- 我的推理正确吗?
- 还有哪些其他差异/用例/最佳实践/限制 哪种方法?
- 关于在
AssertionError中提供描述 - 是否应该提供或者仅仅是它是Error的事实(以及 断言类型)足以或多或少地确定堆栈跟踪 发现错误时会提供吗?
【问题讨论】:
-
您的断言实际上有多慢?就我个人而言,我喜欢在现实世界中开车时系好安全带,而不仅仅是在学习时:)到达无效状态,您可能会擦除真实的生产数据。)仅当您有证据表明它们正在显着减慢您的程序时,才考虑删除断言。
-
基本上你是对的。尽管有些人希望从生产代码中删除断言,因为无效行为被视为比彻底的应用程序失败更好。使用 AssertionError 提供至少一个基本的错误描述可能是一个好主意,这样就可以完成第一级调试而无需深入研究源文件(如果某些 bozo 只报告错误消息,而没有堆栈跟踪)。
-
@JonSkeet 但是你可以只为那部分代码保留断言。使用
AssertionError你没有任何选择,即使断言被故意禁用,它也会被抛出。 -
@HotLicks 您也可以使用
assert false "Should not be reached"给出原因代码,这样就不会区分assert false和throw AssertionError()。 -
根据 Java 技术说明 "Programming With Assertions",如果
getFoo可公开访问,则您的示例无效
标签: java exception-handling assertions