【2.Delphi语法基础】7.程序异常处理

7.程序异常处理

Delphi对应用程序中产生的异常定义在SysUtils、DB、ComCtrl等多个库单元中。

7.1Object Pascal异常基类

Delphi中,所有异常的基类是Exception类。其主要属性和方法如下:

1.属性

  • HelpContext

    HelpContext是ThelpContext类的实例,提供了与异常对象联系在一起的上下文相关帮助信息的序列号。该序列号决定当发生异常时,用户按F1键显示的异常错误的帮助信息。

  • Message

    存储异常发生时的错误信息。可以通过该属性在提示错误对话框中显示错误信息字符串。

2.方法

  • Create(Const Msg: string)

    该方法用来产生一个具有简单提示信息的对话框,对话框中的提示信息由Msg提供。

  • CreateFmt(Const Msg: string, Const Args: Array of Const)

    该方法用来产生一个具有格式化字符串提示信息的对话框,格式化字符串由Msg和Args提供。如:CreateFmt('%dbu z %d..%d范围内', [100, 0, 99]),产生”100不在0..99范围内“。

  • CreateHelp(Const Msg: string, AhelpContext: Integer)

    该方法产生一个具有简单提示信息和上下文帮助序列号的提示对话框,其中:Msg参数时显示在异常对话框中的提示信息,AhelpContext参数是异常错误信息上下文帮助序列号。

7.2Delphi内建异常类

Delphi内建异常类很多,下面表格列出常见的Delphi内建异常类:

异常类引发条件
EAbort程序遇到错误但不弹出对话框
EAccessViolation无效内存访问错误
EAssertionFailed执行Assert过程返回值是False
EControlC在控制台中,按【Ctrl】+【C】组合键遇到错误
EConvertError在字符串或其他对象集转换时遇到错误
EDivByZero整数除数是0
EinOutError输入/输出错误
EIntOverflow整数运算时,结果超过变量定义范围
EMathError浮点运算出现错误
EOutOfMemory超出内存错误
EOverflow浮点运算返回结果超出变量定义范围
ErangeError整数数值超出变量定义范围,例如数组下标越界
EStackOverflow堆栈溢出错误
EWin32ErrorWindows错误
EzeroDivide浮点运算除数是0
EdatabaseError数据库错误,在数据库中定义
EupdateError数据集提供者错误,在数据库中定义
EADOErrorADO数据库错误,在adodb库中定义
EDBEngineError出现BDE错误,在dbtables库中定义
EnoResultSet没有成功打开一个数据集查询

7.3自定义异常类

虽然Delphi已经有很多内建的异常类,但有时满足不了应用需求,此时,可以自行定义异常类,自定义异常类必须继承内建异常类。以下举例说明校验年龄数据的正确性,年龄限制在0~99之间。

运行时界面如下图所示:

 

代码如下:

implementation
​
{$R *.dfm}
​
type
  VerifyAgeError = class(Exception)         // 自定义异常类
    function toAge(age: integer): integer;
  end;
​
function VerifyAgeError.toAge(age: integer): integer;
begin
  if (age >= 100) or (age < 0) then
    showmessage('年龄不符合实际!');
  result := abs(age) mod 99;
end;
​
// 校验按钮事件处理
procedure TForm1.Button1Click(Sender: TObject);
var
  a: integer;
begin
  try
    a := strtoint(Edit1.Text);
    if (a >= 100) or (a < 0) then raise VerifyAgeError.Create('年龄错误');
    messagedlg('OK', mtinformation, [mbok], 0);
  except
    on e: EConvertError do
      messagedlg(e.Message, mterror, [mbok], 0);
    on e: VerifyAgeError do
    begin
      messagedlg(e.Message, mterror, [mbok], 0);
      Edit1.Text := inttostr(e.toAge(strtoint(Edit1.Text)));
    end;
  end;
end;
​
// 退出按钮事件处理
procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;
​
end.

7.4触发异常

异常触发可以分为两种:一种是程序系统自动触发,另一种是执行raise指令触发。如上面的代码中,EConvertError异常就是由系统在执行字符串转换整型数值的时候自动触发的,而VerifyAgeError是当年龄不在指定范围内时通过raise指令手动触发的。

raise指令的语法格式:

raise 异常对象

再次举例说明,以下例子通过输入两次密码相同或不同的情况进行处理。

运行时界面如下图所示:

 

代码如下:

implementation
​
{$R *.dfm}
​
type
  EPasswordInvalid = class(Exception);
​
procedure TForm1.Button1Click(Sender: TObject);
begin
  if edit1.Text <> edit2.Text then
    raise EPasswordInvalid.Create('密码输入有误!')
  else
  begin
    showmessage('密码设置完成!');
  end;
  showmessage('欢迎光临!');
end;
​
end.

7.5异常捕获

在Object Pascal程序语言中,有两种用来处理异常的语句:

  • try...finally...end

  • try...except...end

1.try...finally...end

语法格式:

try
    <被保护语句>
finally 
    <异常处理语句> //无论异常发生否,都必须处理
end;

该语句处理异常,只要触发异常,系统自动捕捉被触发的异常,然后以信息对话框的方式显示异常信息,让程序避开发生异常的代码,然后继续向下执行。

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

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

示例:

运行时界面如下图所示:

 

示例代码:

implementation
​
{$R *.dfm}
​
procedure TForm1.Button1Click(Sender: TObject);
var
  i: ^integer;
  res, y: double;
begin
  try
    new(i);
    i^ := strtoint(edit1.Text);
    y := 3.1415926;
    res := y/i^;
    label1.Caption := '3.1415926 div ' + inttostr(i^) + ' = ' + floattostr(res);
  finally
    showmessage('现在释放i^的内存');
    dispose(i);
  end;
end;
​
end.

2.try...except...end

语法格式:

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

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

使用该语句处理异常时,会根据异常的类型不同,对异常做不同的处理。

在前面的自定义异常代码示例中已经使用过该语句,所以在此不再举例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Janeb1018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值