Java 异常与断言

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1276308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 07:42:24  来源:igfitidea点击:

Exception Vs Assertion

javaassert

提问by JavaResp

What is the difference between Java exception handling and using assertconditions?

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

It's known that Assert is of two types. But when should we use assertkeyword?

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

采纳答案by Jon Skeet

Use assertions for internal logic checks within your code, and normal exceptions for error conditions outside your immediate code's control.

使用断言进行代码中的内部逻辑检查,并使用正常异常来处理直接代码控制之外的错误情况。

Don't forget that assertions can be turned on and off - if you care about things like argument validation, that should be explicit using exceptions. (You could, however, choose to perform argument validation on privatemethods using assertions, on the grounds that a violation at that point is due to an internal bug rather than an external error.)

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

Alternatively it's entire reasonable (IMO) to use exceptions for everything. I personally don't use assertions much at all, but it's a matter of personal preference to some extent. (There can certainly be objective arguments for and against assertions, but it's not sufficiently clear cut to remove preference altogether.)

或者,对所有事情都使用异常是完全合理的(IMO)。我个人根本不怎么使用断言,但这在某种程度上是个人喜好的问题。(当然可以有支持和反对断言的客观论据,但还不够明确以完全消除偏好。)

回答by Lliane

Assert is for debugging purpose only and its trigger condition should not happen (null pointer when there shouldn't be, etc.)

断言仅用于调试目的,其触发条件不应发生(不应该发生时为空指针等)

Exception is for special system events that may always happen : FileNotFound, ConnectionToServerLost, etc.

例外是针对可能总是发生的特殊系统事件:FileNotFound、ConnectionToServerLost 等。

回答by firstthumb

Exception is a mechanism of checking if the implementation is executing without any expected or unexpected errors or not. So, we see that exceptions are basically used for handling even the unforseen conditions during the execution of an application in a better way and hence using exceptions effectively results into a robust application.

异常是一种检查实现是否在没有任何预期或意外错误的情况下执行的机制。因此,我们看到异常基本上用于以更好的方式处理应用程序执行期间甚至不可预见的情况,因此有效地使用异常会产生健壮的应用程序。

Assertions should never be a part of the implementation of some functionality of the application. They should only be used to verify the assumptions - just to be sure that whatever we assumed while desinging the solution is actually valid in practical as well.

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

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

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

回答by Stephen C

Java assertions are built on top of Java exceptions and exception handling. Indeed, when a Java assertion fails, the result is an AssertionError exception that can be caught like any other Java exception. The key differences between exceptions and assertions are:

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

  • Assertions are intendedto be used solely as a means of detecting programming errors, aka bugs. By contrast, an exception can indicate other kinds of error or "exceptional" condition; e.g. invalid user input, missing files, heap full and so on.
  • The Java language provides syntactic support for assertions, in the form of the assertstatement. Compare the following:

    if (x != y) {
         throw new SomeException("x != y");
    }
    
    assert x != y;
    
  • Most importantly, Java allows you to enable or disable assertion checking globally or on individual classes when you start the JVM.

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

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

Note: some people say that you should alwaysrun production code with assertion checking turned off. I tend to disagree with this as a blanket statement. If your production code is known to be stable AND you need to squeeze that last bit of performance out of it, then turning off assertions is good. But, if a (say) 10% performance hit is not a real problem, I'd prefer to have an application die with an assertion error if the alternative is continue and corrupt my database.

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

@Mario Ortegón commented thus:

@Mario Ortegón 评论道:

The "turning off" is because assertions can be used to verify the result of an optimized algorithm by comparing its implementation against a well-known, but slow, algorithm. So, in development it is OK to invoke that O(N^3)method to assert that the O(log N)algorithm works as intended. But this is something that you do not want in production.

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

Whether or not you think it is good practiceto turn off assertions in production, it is definitely bad practiceto write assertions that have a significant impact on performance when enabled. Why? Because it means that you no longer have the option of enabling assertions in production (to trace a problem) or in your stress / capacity testing. In my opinion, if you need to do O(N^3)pre/post-condition testing, you should do it in your unit tests.

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

回答by Tim Abell

Example of a good use of Assert:

正确使用 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

I personally think that Assert should onlybe used when you know something is outside desirablelimits, but you can be sure it's reasonably safe to continue. In all other circumstances (feel free point out circumstances I haven't thought of) use exceptions to fail hard and fast.

我个人认为只有当您知道某些事情超出了理想的限制时才应该使用Assert ,但您可以确定继续操作是相当安全的。在所有其他情况下(随意指出我没有想到的情况)使用异常来快速失败。

The key tradeoff for me is whether you want to bring down a live/production system with an Exception to avoid corruption and make troubleshooting easier, or whether you have encountered a situation that should never be allowed to continue unnoticed in test/debug versions but could be allowed to continue in production (logging a warning of course).

对我来说,关键的权衡是您是否想关闭带有异常的实时/生产系统以避免损坏并简化故障排除允许继续生产(当然会记录警告)。

cf. http://c2.com/cgi/wiki?FailFastsee also my c# copy of this answer: Debug.Assert vs. Specific Thrown Exceptions

参见 http://c2.com/cgi/wiki?FailFast另请参阅此答案的我的 c# 副本:Debug.Assert 与特定抛出的异常

回答by SBTec

Assertion is used for debugging of the required assumptions to be checked at runtime only by enabling the assert feature while exception is to check the specific conditions to be checked during execution of the program to prevent the program from terminating.

断言用于调试需要在运行时检查的假设,仅通过启用断言功能即可,而异常则用于检查程序执行期间要检查的特定条件,以防止程序终止。

回答by SBTec

Assertions are very similar to exceptions, in fact just like exceptions they will flag a problem, but unlike exceptions - they won't suggest any alternative execution path, but will simply fail. Why use assertions, if you can do the same thing, plus more with exceptions ?

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

Use them when the problems should not be fixed, and actually SHOULD NEVER HAPPEN IN THE FIRST PLACE. This sounds weird at first: don't we want to safeguard our code from ALL potential problems ? Usually yes. But there is a case where we don't. This case is called: “Design by contract”.

当问题不应该被修复时使用它们,实际上不应该首先发生。乍一看这听起来很奇怪:难道我们不想保护我们的代码免受所有潜在问题的影响吗?通常是的。但也有我们不这样做的情况。这个案例被称为:“合同设计”。

Let say you are writing an application for a bank. As a developer you can not possibly support all possible financial conditions. So before starting to code, you get a spec from the bank which gives you the valid ranges that this application should support. So your application is designed by a contract (by the spec from the bank). This contract will define the fundamental principles that should always be true in order for your application to work. These fundamental principles are called “invariants” (because they can't change). Design by contract simplifies your life as a developer - you are only responsible to support the scope of work defined in the contract.
Its important to check the values of these invariants in your code, but you shouldn't check them as if they are exceptions and try to work around them. If they are wrong - you must fail because the inputs have not fulfilled their contractual obligations.

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

The interesting thing is: if you don't put an assertion into the critical place and invariants become invalid - your code will fail anyway. You just won't know why. So to summarize - assertions are used for verifying the invariants. They go hand-in-hand with the “design by contract” principle. Use them to debug a problem, thats why they are turned off in production.

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

Another use case: if you are relying on an external library that you don't completely trust - you may want to use assert statements when calling it.

另一个用例:如果您依赖于您不完全信任的外部库 - 您可能希望在调用它时使用 assert 语句。

Some also use assertions as a quick and dirty substitute for an exception (since its so easy to do), but conceptually that is not the proper thing to do.

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

回答by Manjitha teshara

Assertion and Exception Handling both can assure programme correctness and avoid logic error,

断言和异常处理都可以保证程序的正确性和避免逻辑错误,

but assertion can enable and disable as programmer wish,

但是断言可以根据程序员的意愿启用和禁用,

in compiler if you use "java -ea JavaFileName" or "java -enableasserations JavaFileName" you can compile with assertion

在编译器中,如果您使用“java -ea JavaFileName”或“java -enableasserations JavaFileName”,您可以使用断言进行编译

if programmers don't need it ,"java -da JavaFileName " or "java -disableasserations JavaFileName " they can disable assertion.

如果程序员不需要它,“java -da JavaFileName”或“java -disableasserations JavaFileName”他们可以禁用断言。

this facility not in Exception handling

此设施不在异常处理中

回答by Sazzad Hissain Khan

Although, I have posted the answerin se.stackexchange site, that might be still helpful to post here.

虽然,我已经在 se.stackexchange 网站上发布了答案,但在这里发布可能仍然有帮助。

Assertions are used,

使用断言,

  1. When you want to stop the program immediately rather to proceed with an unwanted state. This is often related to the philosophy of the Fail-fast[ 1 ]system design.

  2. When there are certain possibilities of cascading failures (i.e. in microservices) for the first unexpected condition that might lead the application into severe inconsistent or unrecoverable states.

  3. When you want to detect bugs in your system exclusively in the debugging period. You might want to disable them in production if language supports.

  4. When you already know that the unexpected conditions arose due to your internal miss-implementation and external system (i.e the callers) has no control over the unwanted state.

  1. 当您想立即停止程序而不是继续进行不需要的状态时。这通常与快速失败[1]系统设计的理念有关。

  2. 当第一个意外情况可能导致应用程序进入严重不一致或不可恢复的状态时,存在一定的级联故障(即在微服务中)的可能性。

  3. 当您只想在调试期间检测系统中的错误时。如果语言支持,您可能希望在生产中禁用它们。

  4. 当您已经知道由于您的内部错误实现和外部系统(即调用方)无法控制不需要的状态而导致意外情况时。

Exceptions are used,

使用异常,

  1. When you know that the unexpected conditions arose due to external systems fault (i.e. wrong parameters, lack of resources etc).

  2. When you know that the conditions can be backed up with alternative paths keeping the application functional qualities still intact (i.e. might work well for another call with proper parameters from the caller or external system).

  3. When you want to log and let the developers know about some unwanted state but not a big deal.

  1. 当您知道由于外部系统故障(即错误的参数、缺乏资源等)而出现意外情况时。

  2. 当您知道可以使用替代路径备份条件时,保持应用程序功能质量仍然完好(即可能适用于具有来自调用方或外部系统的适当参数的另一个调用)。

  3. 当您想记录日志并让开发人员知道一些不需要的状态但没什么大不了的时候。

Note:“The more you use assertions, the more robust system you get”. In contrast “The more you use exceptions and handle them, the more resilient system you get“.

注意:“你使用断言的次数越多,你得到的系统就越健壮”。相比之下,“您使用和处理异常的次数越多,您获得的系统就越有弹性”。



[ 1 ] Fail fast- In systems design, a fail-fast system is one which immediately reports at its interface any condition that is likely to indicate a failure. Fail-fast systems are usually designed to stop normal operation rather than attempt to continue a possibly flawed process. Such designs often check the system's state at several points in an operation, so any failures can be detected early. The responsibility of a fail-fast module is detecting errors, then letting the next-highest level of the system handle them.

[ 1 ] 快速失败- 在系统设计中,快速失败系统是在其界面上立即报告任何可能指示失败的情况的系统。快速故障系统通常旨在停止正常操作,而不是尝试继续可能有缺陷的过程。此类设计通常会在操作中的多个点检查系统状态,因此可以及早发现任何故障。快速故障模块的职责是检测错误,然后让系统的下一个最高级别处理它们。