首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么异常被认为比显式错误测试更好?

问为什么异常被认为比显式错误测试更好?
EN

Software Engineering用户
提问于 2012-09-24 23:46:18
回答 10查看 15.4K关注 0票数 49

可能重复: 防御性编程与异常处理? if/else语句或例外

我经常看到一些热门的博客文章,其中作者使用了这样的论点:“异常与显式错误检查”来倡导他/她喜欢的语言而不是其他语言。普遍的共识似乎是,使用异常的语言天生比依赖于通过显式函数调用进行错误检查的语言更好/更干净。

是否认为使用异常比显式错误检查更好的编程实践,如果是,为什么?

EN

回答 10

Software Engineering用户

回答已采纳

发布于 2012-09-25 00:03:31

在我看来,最大的争论是程序员犯错误时会发生什么变化。忘记处理错误是一个很常见且容易犯的错误。

如果您返回错误代码,则可以默认忽略错误。例如,如果malloc失败,它将返回NULL并设置全局errno。所以正确的代码应该

代码语言:javascript
复制
void* myptr = malloc(1024);
if (myptr == NULL) {
    perror("malloc");
    exit(1);
}
doSomethingWith(myptr);

但是,只写一篇文章是非常容易和方便的:

代码语言:javascript
复制
void* myptr = malloc(1024);
doSomethingWith(myptr);

这将意外地将NULL传递到其他过程中,并可能丢弃精心设置的errno。代码没有明显的错误表明这是可能的。

在一种使用异常的语言中,您可以编写

代码语言:javascript
复制
MyCoolObject obj = new MyCoolObject();
doSomethingWith(obj);

在这个(Java)示例中,new操作符要么返回一个有效的初始化对象,要么抛出OutOfMemoryError。如果程序员必须处理这个问题,他们可以抓住它。在通常(也是方便地,也是懒惰的)情况下,异常传播以相对干净和显式的方式终止程序。

这就是为什么异常,如果使用得当,可以使编写清楚和安全的代码更加容易。这种模式适用于许多可能出错的事情,而不仅仅是分配内存。

票数 66
EN

Software Engineering用户

发布于 2012-09-25 01:09:42

虽然史蒂文的回答提供了一个很好的解释,但我发现还有一点是相当重要的。有时,当您检查错误代码时,您无法立即处理失败案例。您必须通过调用堆栈显式地传播错误。当您重构一个大函数时,您可能必须将所有错误检查样板代码添加到您的子函数中。

除了例外情况,您只需照顾您的主流。如果一段代码抛出一些InvalidOperationError,您仍然可以将该代码移动到一个子函数中,并且错误管理逻辑将被维护。

因此,异常允许您更快地重构和避免锅炉板。

票数 60
EN

Software Engineering用户

发布于 2012-09-25 08:05:12

从不同的角度来看:错误处理都是关于安全性的。未经检查的错误破坏了以下代码所基于的所有假设和先决条件。这可能会打开许多外部攻击矢量:从简单的DoS对未经授权的数据访问到数据损坏和完全系统渗透。

当然,这取决于具体的应用程序,但是当假设和先决条件被打破时,所有的赌注就都取消了。在一个复杂的软件中,您根本无法确定从那时起什么是可能的,什么是可以和不能从外部使用的。

考虑到这一点,有一个基本的观察:当安全性被视为一个可选的附加组件,以后可以附加,那么它通常会失败。它最好的工作,当它已经考虑在第一个基本设计阶段和内置的权利从一开始。

这基本上是你得到的例外:一个已经内置的错误处理基础设施,是活跃的,即使你不关心。通过显式测试,您必须自己构建它。你必须建立它作为第一步。刚开始编写返回错误代码的函数,直到您进入应用程序开发的最后阶段,才会考虑全局,这实际上是一个附加错误处理,注定会失败。

一个内置的系统在任何方面都不起作用。大多数程序员不知道如何进行错误处理。大多数时候都太复杂了。

  • 有那么多的错误是可能发生的,每个错误都需要自己的处理和自己的行动和反应。
  • 即使是相同的错误也可能需要基于上下文的不同操作。没有找到的文件或者内存不足的文件呢?
    • FNF -运行应用程序所需的第三方库?终止。
    • FNF -应用程序的启动配置文件?从默认设置开始。
    • FNF -网络共享上的数据文件用户希望您的应用程序打开?消失的文件可以在任何时候发生,甚至在in ()和Open()之间的微秒内也可以发生。它甚至不是这个词字面意义上的“例外”。
    • 为了2GB的分配?没什么奇怪的。
    • 一个100字节的分配?你有大麻烦了。

  • 处理所有经过仔细分隔的抽象层的漏洞时出错。最低级别的错误可能需要用GUI消息通知用户。它可能需要用户来决定现在该做什么。可能需要伐木。它可能需要另一部分的恢复操作,例如开放的数据库或网络连接。等。
  • 那州呢?当您对调用状态更改并引发错误的对象调用方法时:
    • 对象是否处于不一致的状态,需要重新构建?
    • 对象状态是否一致,但(部分)已更改,并需要额外的回滚或重新构建?
    • 是否在对象内完成回滚,并且对调用方保持不变?
    • 做什么才是明智的呢?

只要给我看一本学习者的书,在这本书中,错误处理从一开始就经过严格的设计,并最终在所有的例子中使用,而不会因为简洁和可读性而被遗漏,并作为读者的摘录。如果这适用于教育POV是另一个问题,但不足为奇的是,错误处理往往是足够的第二次或第三次思考,当它应该是第一次。

票数 19
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/166039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档