大多数时候我会使用异常来检查代码中的条件,我想知道什么时候是使用断言的合适时机?

例如,

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
}

您能指出断言如何适合这里吗?我应该使用断言吗?

看来我从来没有在生产代码中使用断言,只在单元测试中看到断言。我确实知道在大多数情况下,我可以像上面那样使用异常来进行检查,但我想知道“专业”地进行检查的适当方法。

有帮助吗?

解决方案

断言应该用来检查一番不应该发生的,而异常应被用来检查的东西可能发生。

例如,函数可以除以0,所以异常应被使用,但一个断言可以用来检查硬盘突然消失。

断言将停止运行的程序,但一个例外会让程序继续运行。

请注意if(group != null)不是断言,这仅仅是一个条件。

其他提示

在我的脑海中(列表可能不完整,并且太长,无法容纳评论),我会说:

  • 检查传递给公共或受保护方法和构造函数的参数时使用异常
  • 在与用户交互或希望客户端代码从异常情况中恢复时使用异常
  • 使用异常来解决可能发生的问题
  • 检查私有/内部代码的前置条件、后置条件和不变量时使用断言
  • 使用断言向您自己或您的开发团队提供反馈
  • 在检查不太可能发生的事情时使用断言,否则意味着您的应用程序存在严重缺陷
  • 使用断言来陈述您(应该)知道是真的事情

换句话说,异常解决应用程序的稳健性,而断言解决应用程序的正确性。

断言的设计成本低廉,您几乎可以在任何地方使用它们,我正在使用以下经验法则:断言语句看起来越愚蠢,它就越有价值,并且嵌入的信息就越多。当调试一个行为不正确的程序时,您肯定会根据您的经验检查更明显的失败可能性。然后你将检查那些不可能发生的问题:这正是断言有很大帮助并节省时间的时候。

请记住,可以使用参数在运行时禁用断言,并且 默认情况下禁用, ,所以除了调试目的之外不要指望它们。

您还应该阅读 Oracle 关于断言的文章 查看更多使用或不使用断言的情况。

作为基本规则:

  • 使用断言进行内部一致性检查,即使有人将其关闭也完全无关紧要。(请注意, java 命令默认关闭所有断言。)
  • 使用定期测试来检查不应关闭的内容。这 包括 防御性检查,防止错误以及任何验证数据/请求/用户或外部服务提供的任何内容造成的潜在损害。

您的问题中的以下代码风格不好 潜在的错误

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 (尤其是不记录它),您会加大诊断/调试问题的难度,并可能导致应用程序造成更多损害。

根据该文档 http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general ,“assert语句是适用于非公开的前提条件,后置条件和类不变检查。公共前提检查应该仍然由内导致特别是,记录异常,如抛出:IllegalArgumentException和IllegalStateException异常检查方法来进行。“

如果您想了解更多有关先决条件,后置条件和类不变,检查此文档:的 http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions 。它还包含与断言用法的示例。

好了,回到了微软的建议是扔在所有API异常你提供的信息公开和使用您做出代码内部各种假设的断言。这有点松散定义的,但我想这是由每个显影剂画线。

关于使用例外,因为它的名字说,它们的用法应该是例外这样对你提出上面的代码,如果没有服务存在getGroup调用应该返回null。如果网络链路发生故障或类似的东西只应发生的异常。

我猜的结论是,这是一个有点左下开发团队为每个应用程序定义断言的界限VS例外。

测试为空只会赶上导致问题空值,而一个try / catch因为你拥有它会赶上的任何的错误。

从广义上讲,try / catch语句是安全的,但稍微慢一点,你要小心,你捕捉到所有可能发生的各种错误的。所以,我要说使用try / catch语句 - 有一天getGroup代码可能会改变,你只可能需要这更大的净

您可以使用一点,而他们使用这种简单的区别。异常将被用于同时断言,主要用于在运行时调试目的看假设是否被验证或不检查预期,并呼吁意外的错误检查,未经检查的错误。

我承认我对你的问题有点困惑。当不满足断言条件时,将引发异常。令人困惑的是,这被称为 断言错误. 。请注意,它是未选中的,例如(例如) 非法参数异常 这是在非常相似的情况下抛出的。

所以在Java中使用断言

  1. 是编写条件/抛出块的更简洁的方法
  2. 允许您通过 JVM 参数打开/关闭这些检查。通常我会一直保留这些检查,除非它们影响运行时性能或有类似的惩罚。

请参阅第6.1.2节Sun的文档的(断言与其它出错代码)在下面的链接。

http://www.oracle.com/technetwork/articles/javase/ javapch06.pdf

此文件提供了我所见过何时使用断言最好的建议。从文档引用:

“一个好的经验法则是,你应该使用的特殊情况下,你想快要忘记的断言。断言是来处理,而忘记,一个条件或状态,你不要指望最快的方法有处理。“

不幸的是断言可以被禁用。当生产环境中,需要各方面的帮助追踪不可预见的东西时,你可以得到的,所以断言放弃资格。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top