Java 断言编程第三部分
介绍
在上一篇指南《使用 Java 断言编程第 2 部分》中,我讨论了一些使用断言的最佳实践以及在哪里不应该使用它们。
在本指南中,我将讨论有关断言的一些误解并总结本系列。
关于断言的误解
让我们来谈谈一些关于断言的常见误解。
生产代码应在断言开启的情况下运行
断言是开发时的工具,仅用于测试目的。它们不适用于生产环境。它们验证您的假设,以帮助开发人员避免后续错误。
为什么在测试这个或执行那个时假设不成立?回答这个问题,找到根本原因并修复它。但要在开发阶段这样做。使用断言的目的是防止在代码变得值得生产时发生这些错误。
此外,请记住,我们不应该使用断言来处理错误……这让我想到了下一个误解。
无需断言条件,只需抛出 RuntimeException
有时是的,您可以抛出异常而不是使用断言。事实上,断言是建立在异常之上的,AssertionError 可以像任何其他 Java 异常一样被捕获(我们不应该这样做)。
但在某些情况下你不能用异常代替断言。
再次强调,断言与异常的用途截然不同。断言旨在测试假设并检测错误。而异常则表示异常情况 - 开发人员可能未考虑到的问题。
您可以使用断言来检查代码中的内部逻辑,使用未经检查的异常来检查直接代码无法控制的错误情况,使用已检查的异常来检查业务错误和可恢复错误。
不要忘记可以启用或禁用断言(全局或针对单个包或类)。
如果您确实关心某个特定过程是否无缝进行,那么异常可能会更好。
例如,您可以首先使用一个假设来检查执行流程是否到达程序的某个点:
switch(type) {
case 1:
//...
break;
case 2:
//...
break;
case 3:
//...
break;
default:
assert false : "Default case reached";
}
这相当于:
switch(type) {
case 1:
//...
break;
case 2:
//...
break;
case 3:
//...
break;
default:
throw new AssertionError("Default case reached");
}
但其优点在于可以选择禁用异常的抛出。
并且,与可自定义的断言消息一样,最好的做法是尽可能使用有意义的异常:
switch(type) {
case 1:
//...
break;
case 2:
//...
break;
case 3:
//...
break;
default:
throw new IllegalStateException("Illegal type: " + type);
}
单元测试是断言的替代品
在某些方面,assert 语句可作为代码测试。但是,单元测试不应替代断言,断言也不应替代单元测试。相反,assert 语句可以作为单元测试的补充。
断言验证了有关程序内部状态的假设 - 例如先决条件、后置条件和不变量。
相比之下,单元测试检查程序的外部行为。通常,它们遵循Arrange-Act-Assert结构。换句话说,它们设置先决条件(不测试它们)、执行操作并断言结果;所有这些都从被测试类或方法的外部角度进行。
是的,它们之间可能存在一些重叠。单元测试的断言可能与后置条件断言相同,但它们的目的不同。
断言语句的作用有限。单元测试比断言更灵活,适用范围也更大,因为它们是专门针对某些任务而定制的。事实上,单元测试通常会推动软件开发过程,正如测试驱动开发模型所见。
结论
断言背后的想法很简单:检查布尔条件,如果为真则不执行任何操作,如果为假则抛出错误。
尽管这个功能不常用(或者在某些情况下不太知名),但它可能会很有用。
断言更像是一种开发时工具,它们可以帮助您发现可能导致错误的无效条件。换句话说,它们可以确保您的应用程序逻辑是正确的。
断言与异常的区别:
- 异常可以被捕获,断言则不能被捕获。
- 断言可以被禁用,异常不能被禁用。
断言与单元测试的区别:
- 断言检查程序的内部状态,单元测试检查程序的外部行为。
- 单元测试的范围比断言更大。单元测试可以驱动软件开发过程(测试驱动开发)。
Java 断言可用于使用契约式设计风格进行编程。Eiffel 是一种将契约式设计紧密集成到其构造中的编程语言。它不使用类似 assert 关键字的东西,但在 Java 中,您可以使用断言以同样的方式构造逻辑。
在 JVM 生态系统中,Groovy 是比 Java对断言支持更强大的语言的一个例子。例如,它们提供更多信息,并且默认情况下启用它们。
在Oracle 有关断言的文档末尾,您可以在 FAQ 部分找到这样的答复:
... 还请注意,断言包含在 James Gosling 的 Java 编程语言原始规范中。断言已从 Oak 规范中删除,因为时间限制阻碍了令人满意的设计和实现。
我想知道,如果断言更加正式(比如 Eiffel 实现)或者具有更多特性(比如 Groovy 的断言),那么它们是否会在 Java 程序员中变得更受欢迎?
如果本指南有用,请点赞。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~