作者:taowen
不知道你用什么来应对程序出错的情况。从返回错误号到返回错误对象,从设置全局错误号到setjmp longjmp,从使用异常到知道不使用异常,似乎错误处理总是一件因为很难考虑,从而不知如何应对,进而往往被忽略的东西。

我们是否需要错误处理?答案当然是肯定的。无论你写的是什么样的程序,都需要一个很好的品质。对于高性能的系统级别的软件,我不大清楚那个世界之中应该如何做才能满足要求。近日研究了一下java中的Exception,也就是高级语言中的Exception,所以对于这种普通应用的错误处理稍微比以前多了解了一点,在这里和大家分享一下。

我首先要区分的是错误出现时间
1 开发的时候
2 发布了之后

对于这两个情况我们处理的办法是完全不一样的。对于开发的时候,Exception出现了,我们会去找代码中的错误,然后通过对代码的修改把出错的地方调试好。对于发布了之后,我们对于那个时候的错误是无法预期的。因为原因是无法与其的,所以我们不能通过修改代码达到修正错误的目的。这个时候利用的就是Exception的层次,通过对可疑代码进行try,catch可能的Exception,并且通过Exception的类型大概的了解了出错的原因,然后根据这么一点点的信息进行可能的应对。

我们应对两种时间出现的Exception的办法是截然不同的,而Exception在这两种场合下的职责也是不同的。对于开发的时候,Exception主要的目的是让程序员了解错误是出在了哪里,是怎么一回事。对于发布了之后的情况,Exception主要是通过其自身的类型,选择程序员预先猜测的catch。然后catch的代码之中有可能是retry这个操作,或者抛出一个比较明确的对话框给用户,让用户去面对出错的场景,因为出错的时候是他在场,而不是程序员在场。

区分了这两种情况,我们也就把Exception分成了两种,前一种需要的是对于程序员有意义的描述,不一定需要一个类层次。第二种是要让try catch的代码进行分类捕捉,一般需要一个类层次。

区分了错误发生的时间之后,我们来关注错误发生的原因
从我最近的观点来说,主要要区分的就是错误发生的职责到底是哪个方面的,使调用方,还是执行方。Exception是从执行方给调用方的,对于Exception的类型,描述都是由执行方给出的,因为错误是处在执行方进行执行的过程中的,只有它才知道到底是在一个什么样的情况下发生了一个什么样的错误。
然后我们就把自己比作一个执行方,我们在遇到了一个出错的情况的时候,我们会怎么办。所谓出错,也就是程序执行不下去了,为什么执行不下去了,1 调用方没有满足执行方要正确执行的条件,这些条件可以用一些if语句或者assert来具体表现。 2 在执行方进行“正常”操作的时候(暗含的意思就是调用下层代码的时候没有违背它的契约),执行方要调用的下层代码出现了问题,而执行方根本不知道如何处理。在这两种情况下,对于第一种,我们理解这种错误就是程序员的bug,因为他在写代码的时候没有满足执行方给出的契约。对于第二种,我们理解为真正的异常,虽然有可能这个异常只是下层代码中的一个bug,但是对于调用下层代码的执行方来说,我满足了你要的条件,你还是抛出了Exception,我干不下去了,然后它就把异常传递,或者自己进行一些可能的尝试。
所以对于所有的调用方来说,执行方就是会给出两种Exception,一种反映的是它能肯定的程序员的bug, 一种是它不能肯定,情况不明的异常。对于第一种,我们没得选择就是在编写程序的时候及早发现,如果没有处理,在发布之后对于这种异常只能给出一个“程序内部错误”。对于第二种,我们应该用try catch进行一些尝试,也可能是给用户一个很好的提示,如果不是最终的GUI代码,则还可以选择把异常继续上报。

最后:
其实,这样说来第一种异常就不能说是异常,应该在发现的时候就中断程序,提示开发者。这个就是Assert的行为。也就是说,异常/Exception 不应该用来表示程序员编写的代码对于契约的违背,而且程序员也不一定需要一个Exception才能知道自己哪里搞错了,日志,Assert窗口,别的什么的,都行。为了程序员方便调试,为了程序员能够知道更多信息,这个目的去设计一个异常类层次是不值得的。
posted on 2004-05-25 02:15  taowen  阅读(551)  评论(0编辑  收藏  举报