大多数时候我会使用异常检查代码中的条件,我想知道何时适合使用断言?
例如,
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 :(得分:160)
在我的脑海里(列表可能不完整,而且评论太长而无法填写),我会说:
换句话说,异常解决了应用程序的健壮性,而断言解决了它的正确性。
断言的编写成本很低,几乎可以在任何地方使用它们而且我使用这个经验法则:断言语句看起来越愚蠢,它越有价值,嵌入的信息就越多。在调试不正常的程序时,您一定会根据您的经验检查更明显的故障可能性。然后你将检查那些不可能发生的问题:这正是断言有助于节省时间的时候。
答案 1 :(得分:78)
应该使用断言来检查不应该发生的事情,而应该使用异常来检查可能发生的事情。
例如,函数可能除以0,因此应该使用异常,但可以使用断言来检查硬盘是否突然消失。
断言会阻止程序运行,但异常会让程序继续运行。
请注意if(group != null)
不是断言,只是一个条件。
答案 2 :(得分:25)
请记住,可以在运行时使用参数和are disabled by default禁用断言,因此除了调试目的外,不要依赖它们。
此外,您应该阅读Oracle article about assert以查看更多使用或不使用的案例 - 断言。
答案 3 :(得分:15)
作为一般规则:
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
(特别是不记录它),您将更难以诊断/调试问题,并可能允许应用程序造成更多损害。
答案 4 :(得分:3)
好吧,回到微软,建议在你公开提供的所有API中抛出异常,并在你对内部代码做出的各种假设中使用Asserts。这是一个松散的定义,但我想这取决于每个开发人员画线。
关于异常的使用,正如名称所示,它们的用法应该是例外的,因此对于上面提到的代码,如果不存在服务,则getGroup
调用应返回null
。只有在网络链接出现故障或类似情况时才会发生异常。
我想结论是,每个应用程序的开发团队都需要定义断言与异常的界限。
答案 5 :(得分:3)
根据此文档http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general,“断言语句适用于非公共前置条件,后置条件和类不变检查。公共前置条件检查仍应通过检查内部方法来执行,这些方法会导致特定的,记录在案的异常,例如IllegalArgumentException和IllegalStateException。“
如果您想了解有关前置条件,后置条件和类不变量的更多信息,请查看以下文档:http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions。它还包含断言用法的示例。
答案 6 :(得分:1)
测试null只会捕获导致问题的空值,而try / catch就会捕获任何错误。
从广义上讲,try / catch更安全,但速度稍慢,你必须小心抓住可能发生的各种错误。所以我会说使用try / catch - 有一天getGroup代码可能会改变,你可能需要更大的网络。
答案 7 :(得分:1)
我承认我对你的问题感到有些困惑。如果不满足断言条件,则抛出异常。令人困惑的是,这被称为AssertionError。请注意,它是未经检查的,例如(例如)IllegalArgumentException,它在非常类似的情况下被抛出。
所以在Java中使用断言
答案 8 :(得分:1)
您可以在使用时考虑这种简单的区别。异常将用于检查称为已检查和未检查错误的预期和意外错误,而断言主要用于运行时的调试目的,以查看假设是否经过验证。
答案 9 :(得分:1)
请参阅以下链接中的Sun文档的第6.1.2节(断言与其他错误代码)。
http://www.oracle.com/technetwork/articles/javase/javapch06.pdf
本文档提供了关于何时使用断言的最佳建议。引自文件:
“一个好的经验法则是你应该对你想要忘记的特殊情况使用断言。断言是处理和忘记你不期望的条件或状态的最快方法。必须处理。“
答案 10 :(得分:0)
不幸的是,可以禁用断言。在投入生产时,您需要在追踪无法预料的事情时获得的所有帮助,因此断言会使自己失去资格。