Motang的网络日志

目录

1. JAVA异常分类

异常分为3种: Error - 是表示系统级错误,如内存耗尽了,我们一般情况下不用管 编译时异常Exception - 这种异常必须在代码里被显示的捕获语句包住 运行时RuntimeException - 表示运行时异常,不强制要求写出显示的捕获代码,但如果没有被捕获到,则线程会被强制中断

2. 原则

编译时异常Exception,给了几条禁止的原则,他们是: 1)不要直接忽略异常; 2)不要用try-catch包住过多语句; 3)不要用异常处理来处理程序的正常控制流; 4)不要随便将异常迎函数栈向上传递,能处理尽量处理。

向上传播异常: 如果不能用上述恢复措施,就检查能不能向上传播,什么情况下可以向上传播呢?有多种说法,一种说法是当本方法恢复不了时,这个说法显然是错误,因为上层也不一定能恢复。另外还有两种说法是:1.当上层逻辑可以恢复程序时;2.当本方法除了打印之外不能做任何处理,而且不确定上层能否处理。这种两种说法都是正确的,但还不够,因为也有的情况,明确知道上层恢复不了也需要上层处理,所以我认为正确的做法是:当你认为本异常应该由上层处理时,才向上传播。

何时选用编译时异常:一、如果调用者可以恢复此异常情况,二、如果调用者不能恢复,但能做出有意义的事,如转译等。如果你不确定调用者能否做出有意义的事,就别使编译时异常,免得被抱怨。还有一条原则,应尽最大可能使用编译时异常来代替错误码,这条也是编译时异常设计的目的。另外,必须注意使用编译时异常的目的是为了恢复执行,所以设计异常类的时候,应提供尽量多的异常数据,以便于上层恢复,比如一个解析错误,可以在设计的异常类写几个变量来存储异常数据:解析出错的句子的内容,解析出错句子的行号,解析出错的字符在行中的位置。这些信息可能帮助调用恢复程序。

何时选用运行时异常:首先,运行时异常肯定是不可恢复的异常,否则按上段方法处理。这个不可恢复指的是运行时期不可恢复,如果可以修改源代码来避免本异常的发生呢,那说明这是一个编程错误,对于编程错误,一定要抛运行时异常,编程错误一般可以通过修改代码来永久性避免该异常,所以这种情况应该让程序挂掉,相当于爆出一个bug,从而提醒程序员修改代码。这种编程错误可以总结一下,API是调用者与实现者之间的契约,调用者必须遵守契约,比如传入的参数不允许为空,这一点是隐含契约,没必要明确写出来的,如果违反契约,实现者就可以抛运行时异常,让程序挂掉以提醒调用者。 其它情况是否应使用运行时异常,上面提到过,就是谁都无能为力的异常情况,还有就是你不确定到底能不能恢复,除此之外,你可以这样判断:如果你希望程序挂掉,就用运行时异常。需要说明的是,请尽量使用系统自带异常,而不是新写。网上还有一条建议是使用运行时异常时, 一定要将所有可能的异常写进文档。这认为只要把不常用的写上即可,像NullPointException每个方法都有可能抛,但没必要每个方法都写说明。

UI层处理异常的注意点:UI层和其下逻辑层的区别是UI层的出错信息是被用户看,而其下层逻层出错信息是被程序员看到,用户可不希望看一个打印的异常栈,更不希望程序无缘无故挂掉,用户希望看到友好的提示信息。为到达这一目的,我们可以设一个屏障,屏障可以捕获所有遗漏的异常,从而阻止程序直接挂掉,屏障当然恢复不了运行,但可以记录错误便于日后调试,还可以输出友好信息给用户。

目前,项目中的自定义的异常,设计有code编码字段,目的是异常来代替错误码,方便上层或调用者区分原因。在程序上在common包中设计了2个基础异常类,一个是运行时异常类、一个是用编译时异常类,在项目中,所有自定义的异常类都需要继承这两个类中的一个。另外,在各自的service中声明自己的异常类,可放置在serivce包中。异常类是否需要往上抛,采用那种异常,可按照上面提到的思路。

在ui上的异常处理,springmvc的controller类中的异常处理的方法(声明@ExceptionHandler)会优先处理,没有在controller层处理的异常,将会被系统所定义的@ControllerAdvice下的@ExceptionHandler统一类处理,根据定义的异常code读取资源文件,友好的展现给用户。

© 2015 Morly Tang. All Rights Reserved.

版权归属:寂寞的男人