Java 断言是否损坏?
在浏览问题时,我最近在Java中发现了关键字。起初,我很兴奋。一些我不知道的有用的东西!一种更有效的方法来检查输入参数的有效性!耶学习!assert
但后来我仔细看了一眼,我的热情与其说是“缓和”,不如说是“完全扼杀”,因为一个简单的事实是:你可以把断言关掉。
这听起来像是一场噩梦。如果我断言我不希望代码继续运行,如果输入是,我为什么要忽略这个断言呢?这听起来像是,如果我正在调试一段生产代码,并怀疑可能被错误地传递了一个,但没有看到任何日志文件证据证明该断言被触发,我不能相信实际上发送了一个有效的值;我还必须说明断言可能已被完全关闭的可能性。listOfStuff
null
listOfStuff
null
listOfStuff
这假设我是调试代码的人。不熟悉断言的人可能会看到这一点,并假设(非常合理地)如果断言消息没有出现在日志中,则可能不是问题所在。如果你第一次遇到是在野外,你会想到它可以完全关闭吗?毕竟,这并不是说有一个命令行选项可以让你禁用try/catch块。listOfStuff
assert
所有这些都把我带到了我的问题(这是一个问题,而不是咆哮的借口!我保证!
我错过了什么?
有没有一些细微差别使Java的实现比我给予它的信任更有用?在某些情况下,从命令行启用/禁用它的能力是否真的非常有价值?当我设想在生产代码中使用它来代替像这样的语句时,我是否以某种方式误解了它?assert
if (listOfStuff == null) barf();
我只是觉得这里有一些重要的东西,我没有得到。
*好的,从技术上讲,它们实际上是默认关闭的;你必须不厌其烦地打开它们。但是,您仍然可以完全淘汰它们。
编辑:要求开悟,接受开悟。
首先是调试工具的概念对于使其对我有意义有很长的路要走。assert
我仍然对在生产环境中禁用非平凡私有方法的输入检查的概念提出异议,因为开发人员认为糟糕的输入是不可能的。根据我的经验,成熟的生产代码是一个疯狂、庞大的东西,由具有不同程度技能的人多年来开发,针对的是不同程度的理智的快速变化的需求。即使糟糕的输入真的是不可能的,六个月后草率的维护编码也可以改变这一点。gustafc提供的链接(谢谢!)包括以下示例:
assert interval > 0 && interval <= 1000/MAX_REFRESH_RATE : interval;
在生产中禁用如此简单的检查让我感到愚蠢乐观。但是,这是编码理念的差异,而不是损坏的功能。
此外,我绝对可以看到这样的东西的价值:
assert reallyExpensiveSanityCheck(someObject) : someObject;
我感谢所有花时间帮助我理解此功能的人;非常感谢。