Java 何时使用断言以及何时使用异常
大多数时候,我都会使用异常来检查代码中的条件,我想知道什么时候是使用断言的合适时机 比如说,Java 何时使用断言以及何时使用异常,java,exception,assertion,Java,Exception,Assertion,大多数时候,我都会使用异常来检查代码中的条件,我想知道什么时候是使用断言的合适时机 比如说, Group group=null; try{ group = service().getGroup("abc"); }catch(Exception e){ //I dont log error because I know whenever error occur mean group not found } if(group !=null) { //do something
Group group=null;
try{
group = service().getGroup("abc");
}catch(Exception e){
//I dont log error because I know whenever error occur mean group not found
}
if(group !=null)
{
//do something
}
你能指出一个断言如何适用于这里吗?我应该使用断言吗
似乎我从未在生产代码中使用断言,而只在单元测试中看到断言。我确实知道,在大多数情况下,我可以使用exception来执行上述检查,但我想知道“专业地”执行检查的适当方法。我想(列表可能不完整,太长,无法放入注释),我想说:
- 检查传递给公共或受保护的方法和构造函数的参数时使用异常
- 与用户交互时,或当您希望客户端代码从异常情况中恢复时,请使用异常
- 使用异常来解决可能出现的问题
- 在检查私有/内部代码的前置条件、后置条件和不变量时使用断言
- 使用断言向您自己或您的开发团队提供反馈
- 在检查不太可能发生的事情时使用断言,否则这意味着应用程序中存在严重漏洞
- 使用断言来陈述你(假设)知道是真实的事情
断言的设计成本很低,您几乎可以在任何地方使用它们,我使用的是这个经验法则:断言语句看起来越愚蠢,它就越有价值,它所嵌入的信息也越多。当调试一个行为不正确的程序时,您肯定会根据自己的经验检查更明显的失败可能性。然后,您将检查不可能发生的问题:这正是断言帮助很大并节省时间的时候。测试null只会捕获导致问题的null,而try/catch会捕获任何错误
一般来说,try/catch更安全,但速度稍慢,您必须小心捕获可能发生的各种错误。所以我会说使用try/catch-有一天getGroup代码可能会更改,而您可能只需要更大的网络。记住,断言可以在运行时使用参数禁用,因此除了调试目的之外,不要指望它们
您还应该阅读,以了解更多使用或不使用断言的情况。断言应用于检查不应该发生的事情,而异常应用于检查可能发生的事情
例如,函数可以除以0,因此应该使用异常,但可以使用断言检查硬盘驱动器是否突然消失 断言将停止程序运行,但异常将使程序继续运行
请注意,
如果(group!=null)
不是一个断言,那只是一个条件。好吧,回到微软,我们的建议是在您公开提供的所有API中抛出异常,并在您对内部代码所做的各种假设中使用断言。这是一个有点松散的定义,但我想这取决于每个开发人员来划定界限
关于异常的使用,顾名思义,它们的使用应该是异常的,因此对于上面显示的代码,getGroup
调用应该返回null
,如果不存在服务。只有当网络链接断开或类似情况时,才会发生异常
我想结论是,对于每个应用程序,定义断言与异常的界限有点留给开发团队了。我承认我对你的问题有点困惑。当不满足断言条件时,将引发异常。令人困惑的是,这被称为。注意,它是未选中的,比如(例如)在非常类似的情况下抛出 所以在Java中使用断言
不幸的是,可以禁用断言。在生产过程中,你需要在追踪不可预见的事情时所能得到的所有帮助,因此断言自己不合格 一般来说:
- 使用断言进行内部一致性检查,如果有人关闭它们,这一点都不重要。(请注意,
命令默认情况下关闭所有断言。)java
- 使用常规测试进行任何不应关闭的检查。这包括防御性检查,以防止由bug、任何验证数据/请求/用户或外部服务提供的任何内容造成的潜在损害
您问题中的以下代码风格不好,可能存在错误
try {
group = service().getGroup("abc");
} catch (Exception e) {
//i dont log error because i know whenever error occur mean group not found
}
问题是您不知道异常意味着找不到该组。也可能是service()
调用引发了异常,或者它返回了null
,然后导致了NullPointerException
当捕获“预期”异常时,应该只捕获预期的异常。通过捕获
java.lang.Exception
(尤其是不记录),您将使诊断/调试问题变得更加困难,并可能使应用程序造成更大的损害。您可以在使用它们时记住这一简单的区别。异常将用于检查称为“已检查和未检查的错误”的预期错误和意外错误,而断言主要用于运行时的调试目的,以查看假设是否得到验证 见第6.1.2节(断言与o