在程序运行过程中
往往出现一些意外错误状态而导致程序无法运行下去的情况
因此 在实现程序功能的同时
必须考虑如何处理程序运行过程中可能出现的各种异常情况
所谓异常是指打断程序正常流程的
非常见或意外的状态
打开文件时按路径找不到文件
不能分配所需的内存等
现本人结合实际就Delphi中异常的产生
来源以及实现异常处理的方法进行探讨
异常的来源
异常可由一些不同的资源产生用户的程序可以因为不正常状态产生异常Delphi的组件可以因为不同的事件产生异常把越界值赋给属性或尝试为不存在的数组元素建立索引 运行的库过程和函数也能产生异常执行带有非法操作的数学表达式如被0除肯定是异常 其他产生异常操作的例子包括引用nil指针执行非法类型转换的表达式等总的来说软件在运行过程中遇到的情况千差万别因此产生异常的情况也各有不同
传统的异常处理方法
对于程序运行过程中产生的异常情况传统处理的方法主要是通过IF语句布尔型标志和特别函数返回值来控制如在加载文件时采用条件语句以处理可能产生的打开空文件的错误
If OpendialogFilename=nil then //判断是否选择文件
Begin
ShowMessage( 选择文件无效请重新选择一个文件)
End
以上例子是通过IF语句判断到异常事件后提示重新操作这种异常处理方法当然很容易理解但在软件编写的过程中如果每个地方都使用IF语句来检查错误并处理异常会使编程工作变得较为繁杂在Delphi中这个问题可以用更简便的方法来实现异常处理
Delphi 中的异常处理方法
Delphi支持多种异常处理机制Object Pascal提供了高级的异常处理机制在这里就两种异常处理方法进行探讨
创建被保护语句块
所谓被保护语句块简单说是一条或多条语句带有对这些语句产生异常的处理器运用try和except关键字来创建被保护语句块的结构具体结构如下
Try //可能引起异常的代码段
···
except //对异常进行处理的代码段
···
end
其中try和except为关键字try用于标志可能产生异常的代码段如果这段程序在运行时产生了异常系统会中止try代码段的执行并根据except所设的代码段进行
下面就如何利用这个结构来创建被保护语句块研究一个程序的例子具体的调用事件处理过程主要代码如下
var
IJKInteger
Begin
I=J=
Try
K=J DIV I //产生异常的语句
Except
ShowMessage ( Divede error! + I=+ IntToStr ( I ) + J + IntToStr ( J ) +k= + IntToStr ( K ))
End
在这个过程中表达式JdivI尝试用除以使Object Pascal运行库产生一个异常从而执行了except块中的ShowMessage语句这个保护语句控制程序的执行过程主要有以下三个要点
() 如果except块中的一条语句处理了一个异常过程或函数在保护块后面继续正常运行
() 如果没有语句处理异常当前的过程或函数立即退出异常查找调用链直到找到合适的处理器
() 未处理的异常最终找到应用程序的缺省异常处理器处理器显示对话框和消息 缺省异常处理器接收所有没有提供处理的异常
创建被保护资源块
以上的例子显示错误消息仅仅是异常处理的一个方面当产生异常情况时一个可靠的应用程序必须恢复稳定性如果发生磁盘错误应用程序必须释放可能不用的内存快直到用户重新启动一个可靠的程序很容易排除错误通过关闭文件释放Windows资源用任何可能的方法从混乱中恢复这种情况可用try 和finally关键字来创建被保护资源块所谓被保护资源块简单说是由一条或多条语句组成带有对资源使用可能产生异常的处理器 这个保护资源块的基本框架结构为
try//程序语句
···
finally // 释放的资源
···
end
在这个结构中不管try块中的语句是否产生异常finally块中的语句总是要执行的在典型的情况下finally块中的语句释放内存关闭文件执行其他必须完成的操作来恢复系统稳定性如果是try块外的语句产生异常就会立刻引起过程或过程跳出跳过finally块需要注意的一点是分配语句不要放在try块中即使它将产生一个异常也是如此{例如由于RAM 的缺陷而使内存分配失误}finally块的目的是释放资源因此必须在try块前放置分配语句在该块中插入任何可以产生异常的语句或可以让过程或函数退出以让分配的资源悬挂直到用户重新启动的语句下面结合实际例子来探讨这种技术并且显示如何使用被保护资源块来防止悬挂资源具体的过程主要代码如下
var
IJKInteger
PPointer
Begin
I=J=//给变量初值
GETmem ( P )//分配内存资源
Try
K= J div I
var
I J K Integer
P Pointer
Begin
I=J=//给变量初值
GETmem(P)//分配内存资源
Try
K=JdivI
Except
ShowMessage ( RRSULTS I+ IntToStr ( I ) + J + IntToStr ( J ) +KI + IntToStr ( K ))
Finally
FreeMem ( P ) ; //释放内存资源
ShowMessage( 已经释放内存)
End
上述过程与被保护语句块相似只是增加了一条分配内存的语句这条语句调用GetMem 来保存4098 个字节的内存当产生异常情况时程序由于设置了被保护资源块使得占用内存的资源得以释放另外程序中潜在的错误除法表达式存在于try块中如果除法不在try中这条语句的执行就将产生异常过程会立刻结束
结束语
在程序中加入异常处理结构以达到对异常的控制这种处理方法在编写程序的过程中非常有用有人可或许认为异常处理很复杂或者用处不大其实异常处理并不复杂无非是中断产生异常的程序代码捕捉可能产生的异常并进行相应处理掌握了这一基本方法后就理解运用异常处理机制的重要性以及如何使用异常处理机制了