异常与断言

Jav*_*esp 54 java assert

Java异常处理和使用assert条件之间有什么区别?

众所周知,Assert有两种类型.但什么时候应该使用assert关键字?

Jon*_*eet 85

在代码中使用断言进行内部逻辑检查,在正常代码控制之外使用错误条件的正常异常.

不要忘记断言可以打开和关闭 - 如果你关心参数验证之类的东西,那应该是明确的使用异常.(但是,您可以选择使用断言对私有方法执行参数验证,理由是此时的违规是由于内部错误而不是外部错误.)

或者,对所有事情都使用例外是完全合理的(IMO).我个人根本不使用断言,但这在某种程度上是个人偏好的问题.(当然可以存在支持和反对断言的客观论据,但它并不足以明确地删除偏好.)

  • 值得注意的是,某些语言实际上使用异常来实现断言.在这些语言中,你的声明"对一切事物使用例外是合理的"是如此真实,这是多余的.:) (6认同)

Ste*_*n C 25

Java断言建立在Java异常和异常处理之上.实际上,当Java断言失败时,结果是AssertionError异常,可以像任何其他Java异常一样被捕获.异常和断言之间的主要区别是:

  • 断言旨在仅用作检测编程错误(即bug)的手段.相反,异常可以指示其他类型的错误或"异常"条件; 例如,无效的用户输入,丢失的文件,堆满等等.
  • Java语言以assert语句的形式为断言提供语法支持.比较以下内容:

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

注意:有人说你应该总是在关闭断言检查的情况下运行生产代码.作为一揽子声明,我倾向于不同意这一点.如果您的生产代码已知是稳定的并且您需要从中挤出最后一点性能,那么关闭断言是好的.但是,如果(例如)10%的性能损失不是一个真正的问题,如果替代方案继续并损坏我的数据库,我宁愿让应用程序死于断言错误.

@MarioOrtegón评论如下:

"关闭"是因为断言可以用于通过将其实现与众所周知但缓慢的算法进行比较来验证优化算法的结果.因此,在开发中,可以调用该O(N^3)方法来断言O(log N)算法按预期工作.但这是你不想要的东西.

无论你是否认为这是很好的做法,关闭断言在生产中,它肯定是不好的做法写启用时对性能有显著影响的断言.为什么?因为这意味着您不再可以选择在生产中启用断言(跟踪问题)或在压力/容量测试中启用断言.在我看来,如果你需要进行O(N^3)前/后条件测试,你应该在单元测试中进行.


fir*_*umb 6

异常是一种检查实现是否正在执行而没有任何预期或意外错误的机制.因此,我们看到异常基本上用于处理应用程序执行期间不可预见的条件,从而以更好的方式使用异常,因此有效地使用异常会导致强大的应用程序.

断言永远不应该是应用程序某些功能的实现的一部分.它们只应用于验证假设 - 只是为了确保在设计解决方案时我们所假设的任何内容在实际中也是有效的.

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


小智 5

断言与异常非常相似,事实上就像异常一样,它们会标记一个问题,但与异常不同 - 它们不会建议任何替代执行路径,但只会失败.为什么要使用断言,如果你可以做同样的事情,还有更多的例外?

当问题不能解决时使用它们,实际上不应该在第一个地方发生.这听起来很奇怪:我们不想保护我们的代码免受所有潜在问题的影响吗?通常是的.但有一种情况我们没有.这种情况称为"按合同设计".

假设您正在为银行撰写申请.作为开发人员,您无法支持所有可能的财务状况.因此,在开始编码之前,您会从银行获得一个规范,该规范为您提供此应用程序应支持的有效范围.所以你的申请是由合同设计的(根据银行的规范).该合同将定义应始终为真,以使您的应用程序正常工作的基本原则.这些基本原则被称为"不变量"(因为它们不能改变).合同设计简化了您作为开发人员的生活 - 您只负责支持合同中定义的工作范围.
检查代码中这些不变量的值很重要,但是不应该将它们检查为异常并尝试解决它们.如果他们错了 - 你必须失败,因为投入没有履行他们的合同义务.

有趣的是:如果你没有将断言放入关键位置并且不变量变为无效 - 那么你的代码无论如何都会失败.你只是不知道为什么.总而言之 - 断言用于验证不变量.它们与"按合同设计"原则齐头并进.使用它们来调试问题,这就是它们在生产中被关闭的原因.

另一个用例:如果你依赖的是一个你不完全信任的外部库 - 你可能想在调用它时使用assert语句.

有些人还使用断言作为异常的快速和脏的替代(因为它很容易做到),但从概念上讲,这不是正确的做法.