当前位置:  开发笔记 > 编程语言 > 正文

特殊错误是否真的例外?

如何解决《特殊错误是否真的例外?》经验,为你挑选了4个好方法。

我的理解是,普遍的智慧说只使用异常才能获得真正特殊的条件(事实上,我已经多次在SO上看到过这种说法).

然而,Krzysztof Cwalina说:

关于例外的最大误解之一是它们用于"特殊条件".现实情况是它们用于传达错误条件.从框架设计的角度来看,没有"特殊条件"这样的东西.条件是否异常取决于使用的上下文,但可重用的库很少知道如何使用它们.例如,对于简单的数据输入应用程序,OutOfMemoryException可能是例外; 对于进行自己的内存管理的应用程序(例如SQL服务器)来说,这并不是那么特别.换句话说,一个人的特殊情况是另一个男人的慢性病.

然后,他接着说,例外情况应该用于:

使用错误

程序错误

系统故障

考虑到Krzysztof Cwalina是MS CLR团队的PM,我问:你如何看待他的陈述?



1> Jay..:

这听起来过于简单,但我认为在适当的地方使用异常是有意义的.在Java和Python等语言中,异常非常常见,特别是在某些情况下.异常适用于您希望通过代码路径冒出的错误类型,并强制开发人员明确捕获.在我自己的编码中,我认为在错误要么无法忽略时添加异常的正确时间,或者抛出异常而不是向函数调用返回错误值等更优雅.

我可以随意思考的一些最合适的例外场所:

NotImplementedException - 指定特定方法或函数不可用的非常合适的方式,而不是简单地返回而不做任何事情.

OutOfMemory异常 - 很难想象一种更好的方法来处理这种类型的错误,因为它代表了一个进程范围或操作系统范围的内存分配失败.当然,这对于处理至关重要!

NullPointerException - 访问null变量是一个程序员错误,而IMO这是另一个强制错误冒泡到表面的好地方

ArrayIndexException - 在像C这样的无用语言中,缓冲区溢出是灾难性的.较好的语言可能返回某种类型的空值,或者在某些实现中,甚至包围数组.在我看来,抛出异常是一种更优雅的反应.

这绝不是一个全面的清单,但希望它说明了这一点.在优雅和合乎逻辑的情况下使用例外.与编程一样,正确工作的正确工具是很好的建议.毫无意义的例外 - 无所事事,但完全忽略一个强大而优雅的工具同样是不明智的.



2> S.Lott..:

对于编写框架的人来说,也许这很有趣.

对于我们其他人来说,这是令人困惑的(也可能是无用的.)对于普通应用程序,必须将异常作为"特殊"情况搁置.异常会中断程序的普通顺序显示.

你应该谨慎地打破常规的从上到下顺序处理你的程序.异常处理是 - 故意 - 难以阅读.因此,为标准方案之外的事物保留例外.

示例:不要使用异常来验证用户输入.人们总是犯输入错误.这不是特例,这就是我们编写软件的原因.这就是if语句的用途.

当您的应用程序获得OutOfMemory异常时,抓住它是没有意义的.这是特殊的."顺序执行"假设超出了窗口.您的应用程序注定失败,只是崩溃并希望您的RDBMS事务在崩溃之前完成.


解释我的downvote,我完全不同意你提出的每一点.这是最大的,但是:*"异常处理是故意难以阅读的"*什么?是什么让你觉得**任何**语言设计师会故意让其中一个功能难以阅读?
嘿,伙计,我不是故意粗鲁,但你不支持你的陈述有任何理由.
@ S.Lott:感谢您的补充.但是,我不认为顺序呈现必然是好的 - 特别是在事件驱动的环境中.此外,我不认为异常处理难以阅读.但那只是我.再次感谢!

3> coobird..:

确实很难确定究竟是什么构成了"特殊条件",它保证在程序中使用例外.

一个对使用沟通错误原因非常有帮助的实例.正如Krzysztof Cwalina的引述所提到的:

关于例外的最大误解之一是它们用于"特殊条件".现实情况是它们用于传达错误条件.

举一个具体的例子,假设我们有一个getHeader(File f)方法是从文件中读取一些头并返回一个FileHeader对象.

尝试从磁盘读取数据可能会产生一些问题.也许指定的文件不存在,文件包含无法读取的数据,意外的磁盘访问错误,内存不足等.有多种失败方法意味着应该有多种方法来报告出错的地方.

如果没有使用异常,但是需要传达发生的错误类型,使用当前的方法签名,我们最好的办法就是返回一个null.由于获得的null信息不是很丰富,我们从该结果中获得的最佳沟通是"发生了某种错误,所以我们无法继续,抱歉." - 它不会传达错误原因.

(或者可替换地,我们可具有用于其指示FileNotFound条件等,仿真错误代码FileHeader里的对象类的常量,但真正具有恶臭用布尔型的TRUE,FALSE,FILE_NOT_FOUND.)

如果我们得到了一个FileNotFoundDeviceNotReady异常(假设),至少我们知道错误的来源是什么,如果这是最终用户应用程序,我们可以通过解决问题的方式来处理错误.

使用异常机制提供了一种通信方式,不需要回退使用错误代码来通知不在正常执行流程内的条件.

但是,这并不意味着一切都应该由例外处理.正如S.Lott所指出的那样:

例如,不要使用异常来验证用户输入.人们总是犯错误.这就是if语句的用途.

这是一件无法强调的事情.不知道何时使用例外的危险之一是倾向于异常快乐; 使用输入验证就足够的例外.

InvalidUserInput当处理这种情况所需要的只是通知用户期望输入的内容时,定义和抛出异常确实没有意义.

此外,应该注意的是,用户输入在某些时候预计会有错误的输入.在将来自外部世界的输入传递给程序内部之前,验证输入是一种防御性措施.

决定什么是特殊的,什么不是什么有点困难.



4> Federico A. ..:

因为我通常使用Python编程,并且在那种语言中,异常无处不在,对我来说异常可能代表从系统错误到完全合法条件的任何事情.

例如,检查字符串是否包含整数的"pythonic"方法是尝试int(theString)并查看它是否引发异常.这是一个"特殊错误"吗?

同样,在Python中,for循环总是被认为是作用于迭代器,并且迭代器必须在完成其作业时引发'StopIteration'异常(for循环捕获该异常).这种"特殊"无论如何?


+1来这里说"取决于语言.在Python ......"
请注意,在Python中这可能有用,但在Java,C++,VB和C#中,捕获异常非常慢,比if语句慢40到400倍.根据您的输入(您是否期望偶尔出现非数字,或经常会发生这种情况),这可能是也可能不是好的设计.这也是为什么当预期情况恰好时应该使用例外的原因:与正常情况相比例外.
推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有