exception与断言

Javaexception处理和使用assert条件有什么区别?

众所周知,Assert有两种types。 但是什么时候应该使用assert关键字呢?

在你的代码中使用断言来进行内部逻辑检查,以及在你的直接代码控制之外的错误条件的正常例外。

不要忘记,断言可以打开和closures – 如果你关心的东西,如参数validation,应该明确使用exception。 (但是,您可以select使用声明对私有方法执行参数validation,理由是此时的违规是由于内部错误而不是外部错误。)

另外,它是完全合理的(IMO)使用例外的一切。 我个人根本不使用断言,但在某种程度上这是个人偏好的问题。 (当然可以有客观的论点来支持和反对断言,但是没有足够明确的理由去完全消除偏好。)

Java断言build立在Javaexception和exception处理之上。 事实上,当一个Java断言失败时,结果是一个AssertionErrorexception,可以像其他任何Javaexception一样捕获。 exception和断言之间的主要区别是:

  • 断言旨在仅用于检测编程错误,即错误。 相反,例外可以指示其他types的错误或“例外”情况; 例如无效的用户input,缺less文件,堆满等等。
  • Java语言以assert语句的forms为断言提供语法支持。 比较以下内容:

     if (x != y) { throw new SomeException("x != y"); } assert x != y; 
  • 最重要的是,Java允许您在启动JVM时启用或禁用断言检查全局或个别类。

注意:有些人说你应该总是运行产品代码断言检查closures。 我倾向于不同意这个作为一个全面的说法。 如果您的生产代码已知是稳定的,并且您需要将最后一点的性能排除在外,那么closures断言是很好的。 但是,如果(说)10%的性能命中不是一个真正的问题,我宁愿有一个申请与断言错误死亡,如果替代是继续和损坏我的数据库。

@MarioOrtegón如此评论道:

“closures”是因为断言可以用来通过将其实现与众所周知的慢速algorithm进行比较来validation优化algorithm的结果。 因此,在开发过程中,调用O(N^3)方法来声明O(log N)algorithm按预期工作是可以的。 但这是你不想在生产中的东西。

不pipe你认为在生产中closures断言是否是好的做法 ,在启用时编写对性能具有显着影响的断言绝对是不好的做法 。 为什么? 因为这意味着你不再有权在生产(追踪问题)或压力/容量testing中启用断言。 在我看来,如果你需要做O(N^3)前/后条件testing,你应该在你的unit testing中做。

exception是检查实现是否正在执行而没有任何预期或意外错误的机制。 因此,我们看到,exception基本上用于处理应用程序执行过程中未知的情况,因此使用exception有效地导致了一个强大的应用程序。

断言不应该是应用程序的某些function的实现的一部分。 他们只能用来validation假设 – 只要确定我们在devise解决scheme时所采取的任何事情,实际上也是有效的。

参考: http : //geekexplains.blogspot.com/2008/06/asserions-in-java-assertions-vs.html

良好使用Assert的例子:

 assert flibbles.count() < 1000000; // too many flibbles indicate something is awry log.warning("flibble count reached " + flibbles.count()); // log in production as early warning 

我个人认为, 只有当你知道什么东西超出了理想的范围时才应该使用断言,但是你可以确定继续是合理安全的。 在所有其他情况下(我没有想到的情况下指出情况)使用例外来强制失败。

对于我来说,关键的权衡是你是否想用一个exception来降低实时/生产系统,以避免腐败并简化故障排除,或者是否遇到了一个永远不应该被允许在testing/debugging版本中不被注意的情况,被允许继续生产(当然logging警告)。

比照 http://c2.com/cgi/wiki?FailFast另请参阅我的这个答案的C#副本:; Debug.Assert与特定的抛出exception

断言与exception非常相似,事实上就像exception他们将标记问题一样,但与例外不同 – 他们不会build议任何可选的执行path,但只会失败。 为什么使用断言,如果你可以做同样的事情,再加上exception呢?

问题不应该固定的时候使用它们,实际上从来不应该在第一个地方发生。 这听起来很奇怪:我们不想保护我们的代码免受所有潜在的问题吗? 通常是的。 但有一种情况我们不这样做。 这个案例被称为:“按合同devise”。

假设你正在为银行写一份申请。 作为开发人员,您不可能支持所有可能的财务状况。 所以在开始编码之前,你会从银行得到一个规范,它给你这个应用程序应该支持的有效范围。 所以你的申请是由合同(由银行的规范)devise的。 该合同将定义为使您的应用程序正常工作而应始终如一的基本原则。 这些基本原则被称为“不variables”(因为它们不能改变)。 按合同devise简化了您作为开发人员的生活 – 您只负责支持合同中定义的工作范围。
在你的代码中检查这些不variables的值很重要,但是你不应该检查它们是否是exception,并试图解决它们。 如果他们错了 – 你必须失败,因为投入没有履行合同义务。

有趣的是:如果你不把断言放在关键位置,并且不变式变得无效,那么你的代码将会失败。 你只是不知道为什么。 所以总结 – 断言用于validation不variables。 他们与“按合同devise”原则携手共进。 用他们来debugging一个问题,这就是为什么他们在生产中被closures。

另一个使用案例:如果您依赖的是您不完全信任的外部库,则在调用它时可能需要使用assert语句。

有些也使用断言作为一个exception的快速和肮脏的替代(因为它很容易做),但从概念上说,这是不正确的事情。

断言仅用于debugging目的,其触发条件不应该发生(不应该有空指针等)

exception是可能经常发生的特殊系统事件:FileNotFound,ConnectionToServerLost等

断言用于debugging在运行时只需启用断言function所需的假设,而exception则用于在执行程序期间检查要检查的特定条件,以防止程序终止。