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