程序健壮性之“异常处理”

定义

异常处理(Exceptional Handing)是代替Error Code的新法,分离了接收和处理错误代码。

基本模型

终止模型:将假设错误非常关键,将以致于程序无法返回到异常的地方继续执行,一旦异常被跑出就    表明错误已无法挽回,不能再继续执行。

恢复模型:异常处理程序的工作是修正错误,然后重新尝试调动出问题的方法,并认为第二次能够成功。

异常处理原则

反面示例:

 1   OutputStreamWriter out = ...
 2   java.sql.Connection conn = ...
 3   try { // ⑸  
 4        Statement stat = conn.createStatement();  
 5        ResultSet rs = stat.executeQuery(  "select uid, name from user");  
 6        while (rs.next())  {  
 7               out.println("ID:" + rs.getString("uid")
                +",姓名:" + rs.getString("name"));  }// ⑹
 8       conn.close(); // ⑶  
 9       out.close(); }  10  catch(Exception ex){// ⑵
 11      ex.printStackTrace();}//⑴,⑷ 

1 不要轻易丢弃异常

如(1),仅仅printStackTrace是不够的,异常(几乎)总是意味者某些事情不对劲了但是作为程序员对这种求救信号保持沉默和无动于衷。

对于捕获到的异常通常有4个选择:

a、处理异常。针对改异常采取行动,如修正问题、给出提醒。

b、分析处理后继续抛出异常。

c、转换异常。将一个低级异常转换成应用级异常

2 要指定具体异常

如果不指定具体异常,系统就会尝试去判断所有的异常可能,这样会造成性能的损耗。在这个例子中,最想要捕获的异常是SQLException,另外一个异常是IOExcepiton,。显然在同一个catch块里处理这两个异常是不合适的。所以合适的做法是catch(SQLException){}catch(IOExcepiton){}。至于其他的异常留给上层调用处理

3 占用资源不释放

异常改变了程序的正常执行流程。这个道理很简单,却容易被忽视。如果程序用到了文件、Socket、JDBC连接之类的资源,即使遇到异常,也要正确释放占用的资源。为此可以用finally来保证资源的正确释放。但是一定要注意在finally里不要发生异常,因为finally是执行清理任务的最后机会。

4 说明异常详细信息

简单的pringStackTrace给调试程序带来困难,没有具体明确的说明,即使发现错误也无法快速的定位和判断错误原因。所以出现异常时,最后能够提供一些文字说明,比如当前正在执行的类、方法和其他状态信息。

5 过于庞大的try块

经常把大量的代码放入单个try块不是个好习惯。一旦这么做了,就意味这你不愿意去仔细分析这   段代码会抛出什么异常,也不会为这些异常做一些针对性的处理。这样的话就违反了原则1、2、   4。

6 输出数据不完整

在这段循环中输出数据发生了异常,catch块执行,循环中断,那么已经输出的数据怎么办?用户得到一份不完整的数据?还是系统产生了脏数据?较为理想的做法是使用缓存或者使用事务处理。

最后给出优化过的代码:

   OutputStreamWriter out = ...
   java.sql.Connection conn = ...
   try {  
          Statement stat = conn.createStatement();  
          ResultSet rs = stat.executeQuery(  "select uid, name from user");  
          while (rs.next())  {  
                  out.println("ID:" + rs.getString("uid") + ",姓名: " + rs.getString("name"));  } }
   catch(SQLException sqlex) {  
          out.println("警告:数据不完整");          throw new ApplicationException("读取数据时出现SQL错误", sqlex); }   catch(IOException ioex) {            throw new ApplicationException("写入数据时出现IO错误", ioex); }    finally {          if (conn != null) {                 try {  conn.close();  }               catch(SQLException sqlex2)  {                      System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString());  }  }          if (out != null) {                 try {  out.close();  }               catch(IOException ioex2)  {                      System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());  }  } }
时间: 2024-08-26 14:14:11

程序健壮性之“异常处理”的相关文章

异常处理(程序健壮性→功能→性能)

异常 (Exception):发生于程序执行期间,表明出现了一个非法的运行状况.许多JDK中的方法在检测到非法情况时,都会抛出一个异常对象.例如:数组越界和被0除. try{   //可能发生运行错误的代码:  }  catch(异常类型     异常对象引用){   //用于处理异常的代码  }  finally{   //用于"善后" 的代码  } ①把可能会发生错误的代码放进try语句块中.②当程序检测到出现了一个错误时会抛出一个异常对象.异常处理代码会捕获并处理这个错误.  

程序try-catch的绝对健壮性之嵌套

写程序的过程中,我们对try-catch在熟悉不过了,捕获异常进行处理,以保证程序的健壮性. 今日突发一想,如果我们catch中的代码异常了怎么办?我们做以下一种假设 static void Main(string[] args) { try{ //Code A } catch{ //Code B } finally{ //Code C } } 按照我们平时经常用的,我们在Code A的位置执行出错之后,我们最后可能在Code B进行错误处理,然后可能在Code C处写错误日志. 那么问题来了,

关于提高代码质量的思考之提高代码健壮性

接着上期的拓展性之后,今天谈谈代码的健壮性.代码的健壮性又称鲁棒性,是高质量代码的一个重要指标. 有人分析了印度软件行业比中国好的一个原因:印度的一个老程序员,月代码量在一千行左右,这一千行代码,算法平实,但都是经过仔细推敲,实战检验的代码,不会轻易崩溃的代码.我们的程序员,一天就可以写出一千行代码,写的代码简短精干,算法非常有技巧性,但往往是不安全的,不完善的.印度人的程序被称作:傻壮.但程序就得这样! 那么如何写出一个代码简短精干,算法非常有技巧性,而又非常安全的代码呢?我逛了很多论坛,发现

【软件构造】第七章第一节 健壮性和正确性的区别

第七章第一节  健壮性和正确性的区别 第七章:进入软件构造最关键的质量特性 --健壮性和正确性. 本节在1-2节的基础上,重申了Robustness and Correctness的重要性,澄清了二者之 间的差异,并指明了在软件构造中处理二 者的典型技术(防御式编程.异常处理. 测试.调试等) Outline 健壮性(Robustness)和正确性(correctness) 如何测量健壮性和正确性 Notes ## 健壮性(Robustness)和正确性(correctness) [健壮性] 定

健壮性与可靠性

健壮性(鲁棒性)和可靠性是有区别的,两者对应的英文单词分别是 robustness 和 reliability.健壮性主要描述一个系统对于参数变化的不敏感性,而可靠性主要描述一个系统的正确性,也就是在你固定提供一个参数时,它应该是产生稳定的,能预测的输出.例如一个程序,它的设计目标是获取一个参数并输出一个值.假如它能正确完成这个设计目标,就说它是可靠的.但在这个程序执行完毕后,假如没有正确释放内存,或者说系统没有自动帮它释放占用的资源,就认为这个程序及其"运行时"不具备健壮性或者鲁棒性

用ORACHK自动化检查数据库系统的健壮性

1.orachk工具主要用途 (1)主动检查您的整个软件在操作系统.CRS.数据库.高可用等层面中的严重问题,以便于IT部门整改,提升系统的稳定性 (2)对于您系统中存在的风险提供简单化和合理化的诊断和分析建议. (3)对系统中存在的健康风险提供汇总信息,并且能够向下钻取到特定的问题和对应的解决方案 (4)对检查结果进行量化评分(100分制),内容非常的全面,通过得分直观判断健康程度 2.运行注意要点 (1)orachk不支持在root用户下运行,需要在oracle或grid用户下运行 (2)如

安装第三方Python模块,增加InfoPi的健壮性

这些第三方Python模块是可选的,不安装的话InfoPi也可以运行. 但是如果安装了,会增加InfoPi的健壮性. 1.chardet chardet可以自动检测文本的编码.如果安装了,可以用于自动检测网页.xml的编码. 安装命令: sudo pip3.4 install chardet 如果系统自带python 3.4或以上版本,可能提示没有pip3.4,换成pip-3.x(x为python的具体版本号)试试. chardet的项目页面: https://pypi.python.org/p

代码健壮性是真的好吗?

我在看一个视频,这个视频里写的代码有这个特点,那就是它把代码写的一个方法可以多次被调用或者说叫利用也可以;同时视频也在一致强调这一点;那我就疑惑了,代码健壮性就那么好吗? 首先,你要写的一个方法能实现不同的功能,在开始设计它的时候就要考虑到各个问题的方方面面,这个对精力应该也是一个很大的消耗吧:这些代码也许写的人能轻松的能读懂,但是如果是别人来读的话,那耗费的时间和精力应该是更大的:如果是更大型的软件,恐怕程序员都要白头了吧:这难道是炫耀技术吗?这个代价也太大了! 其次,现在电脑运算速度是很快的

linux下,简单一行代码提高脚本的健壮性

前言 新来的美女同事,拿她写的脚本向我请教时,我证实了程序猿经常说的一句话:OMG,这么狗屎的代码居然是我写的!!! 问题描述: 在linux/unix写脚本时,我大多习惯在第一行加上(或许还有一大班跟我一样习惯的人): #!/usr/bin/bash 或者 #!/usr/bin/perl 或者 #!/usr/bin/python…………………… 用于操作系统执行这个脚本的时候,调用/usr/bin下的bash/perl/python解释器. 但是,这时存在两个小小问题: 1.本机的bash/p