Delphi中的异常处理

转载:http://www.cnblogs.com/doit8791/archive/2012/05/08/2489471.html

  以前写Delphi程序一直不注意异常处理,对其异常处理的机制总是一知半解,昨天程序中的一个bug ,让我对异常有了更深入的认识,必须要对可能产生异常的地方进行异常处理,否则可能给程序造成灾难

  就像昨天,因为写的 filecopy 函数没有做异常捕获处理,导致复制文件出错时整个程序崩溃,用户只能通过杀进程的方式重启程序再进行其他操作。后来对程序进行了异常处理,遇到意外时只是提示一下用户,然后可以继续运行下去,表现的很完美,才意识到异常处理的重要性,故要总结下Delphi 异常处理相关的知识

Delphi的异常处理的机制介绍

  Delphi异常处理机制建立在保护块(protected blocks)的概念上。所谓保护块是用保留字try 和 end 封装的一段代码。保护块的作用是当应用程序发生错误的时候自动创建一个相应的异常类(Exception)。程序可以捕获并处理这个异常类,以确保程序的正常结束以及资源的释放和数据不受破坏。如果程序不进行处理,则系统会自动提供一个消息框。每一段程序都有可能产生错误!这是软件业的一个不容置疑的现象和规律。

传统的处理错误的方式和异常处理的联系和区别

  事实上,传统的 if...else...结构完全可以解决所有的错误,使用Exception 机制也没能够回避在最原始的层次,通过遍历可能的情况来产生异常的做法,但是异常提供了一种更加灵活和开放的方式,使得后来的编程者可以来根据实际的情况处理这种错误,而不是使用预先设定好的处理结果

一、异常的来源

  在Delphi的应用程序中,下列的情况比较有可能产生异常

1) 文件处理

2) 内存分配

3) Windows资源

4) 运行时创建对象和窗体

5) 硬件和操作系统冲突

二、异常处理

1. try... except... end;

  在 try体内的代码发生异常时,系统将转向 except部分进行异常的处理。这是Delphi 处理异常的最基本的方式之一。try语句块指出来需要进行异常保护的代码。如果在这部分有不正常的事情发生,则引发一个异常对象。 except 是异常处理部分,被保护部分引发的异常对象将执行 <异常处理语句> 或由这部分代码捕获并进行处理

  try ..except ..end 语句的一般格式如下

try  //try保护代码块
    被保护语句块
except  //异常处理块
    异常处理语句(如果异常不发生,就不执行)
end;

  或者

try  //try保护代码块
    被保护语句
except  //异常处理块
    on <异常处理对象类型1> do <语句1>  //捕获指定类型的异常对象,进行处理
    on <异常处理对象类型2> do <语句2>  //捕获指定类型的异常对象,进行处理
    else
        <语句 n+1>    //缺省的异常处理代码
end;

  

2. try... finally... end;

  这种异常处理结构一般用于保护 Windows的资源分配等方面,它确保了无论 try 体内的代码是否发生异常,都需要由系统进行最后的统一处理的一些 Windows对象的正确处理

  和 try... except... end不同,该结构的finally部分总被执行。在 try-finally语句中,当 try部分产生异常后,应用程序直接执行 finally部分的资源释放语句

  try finally语句的一般格式如下

try  //try保护代码块
    被保护语句
finally  //异常处理块
    异常处理语句    //无论异常是否发生,都必须处理
end;

  若用作创建一个资源保护块时,它的格式可以写成:

(分配系统资源)
try
    (使用系统资源的语句)
finally
    (释放系统资源)
end;

  

3. 不存在 try... except ... finally... end 结构来既处理异常,又保护资源分配的结构

  但是,try... except... end 结构允许嵌套到 try... finally... end结构中,从而实现既处理异常,又保护资源的分配

4. raise:知道一些情况不合理,直接手工弹异常对话框。

  比如

raise 异常类.Create(‘异常的缺省说明‘);

  

5. try... finally结构和 try... except 结构在用法上主要有以下区别

  1) 对于try...finally结构来说,不管try部分的代码是否触发异常,finally部分总是执行的。如果发生异常,就提前跳到finally部分。而对于try...except结构来说,只有当触发了异常后,才会执行except部分的代码。

  2) 在 try... except 结构中,当异常被处理后异常对象就被释放,除非重新触发异常。而在 try... finally 结构中,及时 finally部分对异常做了处理,异常对象依然存在

  3) finally 部分不能处理特定的异常,因为它没有 try... except 结构中的异常句柄,无法知道确切的异常类型。因此,在 finally 部分只能对异常作笼统的处理

  4) 在 try... finally 结构中,如果在 try 部分调用标准命令 exit、break或 continue,将导致程序的执行提前跳到 finally部分。finally部分不允许调用上述三个命令

三、Delphi中的异常类结构

  Delphi 提供的所有异常类都是 Exception的子类。用户也可以从 Exception派生一个自定义的异常类。即 Exception是所有异常类的基类,它并不是以 ‘T‘ 开头的,而是以 ‘E‘ 开头,它的派生类也是以 ‘E‘ 开头的。

  Delphi提供了一个很庞大的异常类体系,从大的方面可以把异常类分为运行库异常、对象异常、组件异常三类

1.运行库异常类(RTL Exception)

  运行库异常类可以分为七类,它们都定义在SysUtils 库单元中

1.1. I/O异常

  I/O异常类 EIOOutError 是在程序运行中试图对文件或外设进行操作失败之后产生的,它从 Exception 派生后增加了一个公有数据成员 ErrorCode,用于保存所发生错误的代码。这一成员可用于在发生 I/O 异常后针对不同的情况采取不同的策略

  当设置编译指令 {$I-} 时,不产生 I/O异常类而是把错误代码返回到预定义变量 IOResult中

1.2堆异常

  堆异常是在动态内存分配中产生的,包括两个雷 EOutOfMemory 和EInvalidPointer,如下表所示

堆异常类 引发条件、产生原因
EOutOfMemory 没有足够的控件用于满足所要求的内存分配
EInvalidPointer 非法指针。一般是由于程序试图去释放一个已经释放的指针而引起的

1.3整数异常

  整数异常都是从一个 EIntError 类派生的,但是程序运行中引发的总是它的子类:EFivByZero,ERangeError,EIntOverFlow,如下表

异常类 引发条件
EDivByZero 试图被零除
ERangeError 整数表达式越界
EIntOverFlow 整数操作溢出

  ERangeError 当一个整数表达式的值超过一个特定整数类型分配的范围时引发。比如下面一段代码将引发一个ERangeError异常

时间: 2024-12-14 03:03:17

Delphi中的异常处理的相关文章

Delphi中的异常处理(异常来源、处理、精确处理)

一.异常的来源 在Delphi应用程序中,下列的情况都比较有可能产生异常. 1.文件处理 2.内存分配 3.windows资源 4.运行时创建对象和窗体 5.硬件和操作系统冲突 6.网络问题 7.数据库 8.控件中的异常 9.DLL文件的异常 10.强制类型转换 ………… 二.异常的处理 1.try...except...end; 在try 体内的代码发生异常时,系统将转向except 部分进行异常的处理.这是Delphi处理异常的最基本的方式之一. 只有当try 体内的代码发生异常时,才会跳转

Delphi中的异常处理(10种异常来源、处理、精确处理)

一.异常的来源 在Delphi应用程序中,下列的情况都比较有可能产生异常. 1.文件处理 2.内存分配 3.windows资源 4.运行时创建对象和窗体 5.硬件和操作系统冲突 6.网络问题 7.数据库 8.控件中的异常 9.DLL文件的异常 10.强制类型转换 ………… 二.异常的处理 1.try...except...end; 在try 体内的代码发生异常时,系统将转向except 部分进行异常的处理.这是Delphi处理异常的最基本的方式之一. 只有当try 体内的代码发生异常时,才会跳转

Delphi 中自定义异常及异常处理的一般方法

delphi中异常定义如下: TCustomException   =   class(Exception)     private     public         constructor   Create(const   Msg:   string );     end; 在一般的编程中,因为涉及到函数的嵌套调用,如果在一个函数中发生异常,且此函数中有try except语句,如果想让上级函数捕捉到异常,则在except end中调用 raise语句即可. 一般编程语言的通用处理异常的结

Delphi中的关键字与保留字

Delphi中的关键字与保留字 分类整理 Delphi 中的“关键字”和“保留字”,方便查询 感谢原作者的收集整理! 关键字和保留字的区别在于,关键字不推荐作标示符(编译器已经内置相关函数或者留给保留实现),二保留字是根本不可能作标示符(编译时有警示!) [系统保留字] and            array          as             asm begin          case           class          const constructor   

[查异常网]-20160331-谈谈J2EE项目中的异常处理

为什么要在J2EE项目中谈异常处理呢?可能许多java初学者都想说:“异常处理不就是try….catch…finally吗?这谁都会啊!”.笔者在初学java时也是这样认为的.如何在一个多层的j2ee项目中定义相应的异常类?在项目中的每一层如何进行异常处理?异常何时被抛出?异常何时被记录?异常该怎么记录?何时需要把checked Exception转化成unchecked Exception ,何时需要把unChecked Exception转化成checked Exception?异常是否应该

Delphi中window消息截获的实现方式(2)

Delphi是Borland公司提供的一种全新的WINDOWS编程开发工具.由于它采用了具有弹性的和可重用的面向对象Pascal(object-orientedpascal)语言,并有强大的数据库引擎(BDE),快速的代码编译器,同时又提供了众多出色的构件.受到广大编程人员的青睐.在众多的编程语言(如VB,PowerBuilder,Powerpoint等)中脱颖而出.其中一个DELPHI强于其他编程语言(如VB4.0)的地方就是在DELPHI中可自定义消息,并可直接处理消息.这对于那些希望编写自

Delphi 中 函数参数中的 const 修饰符的本质以及注意事项

来自:http://blog.csdn.net/farrellcn/article/details/9096787 ------------------------------------------------------------------------------ 很多书籍中说函数参数如果是String类型的,如果在函数内部不改变参数的值,使用 const 修饰符会加快程序的执行速度,至于如何加快的?有的人说是因为 const 函数保证了参数字符串不会被复制.以前也没有对这个问题深入研究

DELPHI中的消息处理机制

DELPHI中的消息处理机制 Delphi是Borland公司提供的一种全新的WINDOWS编程开发工具.由于它采用了具有弹性的和可重用的面向对象Pascal(object-orientedpascal)语言,并有强大的数据库引擎(BDE),快速的代码编译器,同时又提供了众多出色的构件.受到广大编程人员的青睐.在众多的编程语言(如VB,PowerBuilder,Powerpoint等)中脱颖而出.其中一个DELPHI强于其他编程语言(如VB4.0)的地方就是在DELPHI中可自定义消息,并可直接

delphi中的Format函数详解

首先看它的声明:[[email protected]][@21ki!] function Format(const Format: string; const Args: array of const): string; overload;[[email protected]][@21ki!] 事实上Format方法有两种形式,另外一种是三个参数的,主要区别在于它是线程安全的,[[email protected]][@21ki!]但并不多用,所以这里只对第一个介绍:[[email protect