struts:异常处理通用做法

来源:互联网 发布:无线网卡找不到网络 编辑:程序博客网 时间:2024/04/27 16:23

总结一下常见异常处理情况。并建议处理如下:

捕获的异常一定要再次抛出

       我们写的FormAction不具备处理异常的能力或者说处理能力非常有限,异常信息层层上报是明智的选择。

Action中的public 函数都有throws子句,它的作用就是要把异常交给服务器。所以在catch 一个异常后马上抛出它,这样其他人便容易获得异常的类型及出处。

Form 或其他类中可能抛出异常的函数(特别是public类型 )一定要有throws子句标明异常的出处。

抛出的异常用BaseRunException包装一下。HighSoft包中的BaseRunException就是专门包装异常的,可以在异常信息里加入一些说明。

不要在异常块内retrun

       你也许写过或者见过类似的代码:

       try{

//someThing may throws Exceptions

return 1;

}catch(Exception e){

  throw new BaserunException(**);

return  2;

}finally{

//**

retrun 3;

}

return  4

 

你能描述它是怎样工作的么?他最终返回什么?(如果你说返回 3 那么你就错了,因为它编译都通不过)

进入finally区块的情形:

1.  Try语句正常结束。

2.  Try语句中执行了retrunbreakcontine等被迫离开。

3.  Try语句异常抛出并且catch语句处理完毕。

由此看出

1.  finally里返回,意味你永远不可能正确的结束了。(finally以下的正常retrun都无效了)。

2.  Catch里返回,意味着你不能再将异常抛出。(即,返回和抛出只能选其一)。

3.  Try里返回,就是这些混乱逻辑的源泉。

 

有一段这样的代码,它主要想这样:执行一个sql语句,成功了返回1try块内),出错了返回-1catch块内);然后在action里得到返回值报告给用户。这代码无疑非常愚蠢:出了错我知道错了(-1)除此之外错在那里、那种类型一无所知;幸好它没有在finally里在返回一下,否则连是否出错都看不出来了。

正确的写法应当是这样:

public int function() throws BaseRunException {

  int result;

  try{

   /*****/

   result = ***;

}catch(**Exception e){

  throws BaseRunException(***);  //抛出即可

}finally{

  /**/

}

retrun result;//正常的返回

}

你要坚信:函数内一旦发生异常,程序当立即转入异常处理,此时任何的返回都没有意义。

异常块不应置于循环内

现在我们已经很少这样写了:

for(**){

DBTool =null;

try{

/***/

tool.excute**(**);

}catch(Exception e){***}***

} 

但这样的写法也还会有:

for(**) {

  functionCyc();

}

functionCyc(){

DBTool =null;

  try{

/***/

tool.excute**(**);

}catch(Exception e){**}***

}

其实,程序中真正造成危害的不是第一种----它只是带来了效率的问题:try-cach执行消耗的资源。第二种才是真正致命的。

1.              函数间的关联。即便是priavte/static促成了内联(inline)它还是会有虚拟机频繁调用的效率问题。(所以,循环内的函数要尽量的“小”,当然与清晰的语义相比“关联消耗”可不予考虑)。

2.              Try-catch块资源消耗问题。与第一种情况相同。

3.              Non-memery“大对象”的资源占用问题。采取第二种做法,不得不在每次循环内占用一个数据库连接----这显然比连接不关闭来的直接。一般来说数据库链接有限--------公司的orcal 8.17只能支持200个连接,for一下是不是很快就满了?!

如果不得不循环调用某一函数执行数据库的操作时,就应该这样写:

  。。。。。。。。

  DBTool  tool = null;

 Try{

   For(*****){

*****

functionCyc(****,tool);

     *****

}

}catch(Exception e){

***

}finally{

  if(**)**;

}

 

private void functionCyc(****,tool)  throws **Exception{

    **********

  tool.excute**(****);

    ********

}

异常的抛出不能随意

也许曾经尝试这么做:

  if(***)  throw new **Exception(**);///并不在catch块里。

那么现在应该马上把它注释掉。

“「异常处理」exception handling)只用于处理异常情况,不要把它拿来用于流程控制贯穿你的程序”、 “这个代码可以运作但性能地下含义模糊而且难以维护” 《Practical Java》。

    确实,我写过这样的程序,问题多多。

给异常块瘦瘦身

try-catch模块只对“非同寻常的情况”负责。

习惯性的朝try块里塞一大堆东西,比如接收传来的参数、构造查询的参数等等,把它拿到外面,它一样工作,并且程序更有效率更容易读。

与此同时,也要净化以下程序,无用的代码统统去掉,一句废话会让别人琢磨半天。

“工蜂函数”早早抛出异常

“工蜂函数”既是常常(多处)被调用的函数,如果它有异常处理或将来可能会有,就早早抛出个异常,让所有调用端处理以下。

反面的例子:highsoft.yxgl.common.util.OptPostUtilgetOperListBySpcRoles()

它有异常处理却没有再次抛出,于是大家调用的时候也没有对它包装进try/catch块里。由于被多次调用,再想重构已经很难。

原创粉丝点击