Posted on 2005-12-02 23:00
canonical 阅读(1049)
评论(0) 编辑 收藏 所属分类:
Witrix开发平台
在witrix平台中,异常处理没有采用java语法支持的checked exception,
也不提倡使用自定义的异常类,
而是定义了少数几个RuntimeException基类,一般是CommonException(RuntimeException的派生类)。
在我自己的经验中,checked exception从未发挥过实质性的作用。checked
exception在某种程度上破坏了封装性原则。我们一般不会在最细的粒度上处理异常,而是在某个统一的模块节点处进行。如果使用checked
exception,
则从最底层的调用到具体异常处理层的整个调用堆栈上的函数都必须明确标记自己不处理该异常,这是完全不必要的负担。这种细粒度上的负担往往将程序员引导到
错误的方向上去,例如编写catch块直接捕获异常
try{
...
}catch(MyException e){
e.printStackTrace();
}
在witrix平台中通过包装类来将checked exception包装为RuntimeException, 而且除了在最终代码处理模块决不屏蔽异常。
try{
...
}catch(IOException e){
throw Exceptions.source(e); // 此时会自动trace异常堆栈及异常消息
}
(后来看到Bruce Eckel的文章Does Java need Checked Exception,发现大家在对待checked exception的态度上倒是心有戚戚焉。)
一般使用自定义的异常类似乎是要将类名作为错误返回码使用,利用java编译器可以做所谓的强类型检查,这实在是一种概念上的浪费。毕竟创建并维护一个
java类还是有一定的代价的,特别是错误码经常变动而且数量不菲。实际上,java类库的设计中也是尽量重用已有的异常类,例如整个jdbc包只抛出
SQLException异常,xml包只抛出SAXException异常。
使用异常,常见的方法是抛出一个字符串消息,例如 throw new
MyException("the object manager does not contains the object :" +
objectName);
这种做法的主要问题是,字符串异常消息无法进行进一步的处理,因而只能直接显示给最终用户,这一方面限制了错误显示的格式和方式,另一方面也不利于程序的多语言支持。
witrix平台中抛出异常的标准方法为
throw Exceptions.code(errorCode).param(paramValue).param(paramName,paramValue);
例如
throw Exceptions.code("web.CAN_err_missing_object_in_manager").param(objectName).param(objectManager);
class Exceptions{
public static CommonException code(String errorCode){
return new CommonException(code);
}
}
class CommonException extends RuntimeException{
public CommonException param(Object paramValue){
...
return this;
}
}
Exceptions规定只使用规范格式的错误码而不是任意格式的异常消息。这样在捕获异常之后,就可以根据错误码和当时的语言Locale设置来决定最终显示的消息格式。
同时CommonException采用流式设计来支持任意数量的自定义参数。这一方面减少了自定义异常类的需求,另一方面也避免了将参数与错误码混合的倾向,即我们就不会倾向于
使用 throw Exceptions.code("the object manager does not contains the object :" + objectName);