異常響應為開發者提供了一個按自己的需要進行異常處理的機制。try …except …end形成了一個異常響應保護塊。與finally不同的是:正常情況下except 後面的語句並不被執行,而當異常發生時程序自動跳到except,進入異常響應處理模塊。當異常被響應後異常類自動清除。
下面的例子表示了文件打開、刪除過程中發生異常時的處理情況:
uses Dialogs;
var
F: Textfile;
begin
OpenDialog1.Title := 'Delete File';
if OpenDialog1.Execute then
begin
AssignFile(F, OpenDialog1.FileName);
try
Reset(F);
if MessageDlg('Erase ' +OpenDialog1.FileName + '?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
System.CloseFile(F);
Erase(F);
end;
except
on EInOutError do
MessageDlg('File I/O error.', mtError, [mbOk], 0);
on EAccessDenied do
MessageDlg('File access denied.', mtError, [mbOk], 0);
end;
end;
end.
保留字on…do用於判斷異常類型。必須注意的是:except後面的語句必須包含在某一個on…do模塊中,而不能單獨存在。這又是同finally不同的一個地方。
12.3.1 使用異常實例
上面所使用的異常響應方法可總結為如下的形式:
on ExceptionType do
{響應某一類的異常}
這種方法唯一使用的信息是異常的類型。一般情況下這已能滿足我們的需要。但我們卻無法獲取異常實例中包含的信息,比如異常消息、錯誤代碼等。假設我們需要對它們進行處理,那麼就必須使用異常實例。
為了使用異常實例,需要為特定響應模塊提供一個臨時變量來保存它:
on EInstance : ExceptionType do …
在當前響應模塊中我們可以象使用一個普通對象那樣來引用它的數據成員。但在當前響應模塊之外不被承認。
下面的代碼用於獲取異常消息並按自己的方式顯示它:
{窗口中包括一個ScrollBar部件,一個Button部件}
procedure TErrorForm.Button1Click(Sender: TObject);
begin
try
ScrollBar1.Max := ScrollBar1.Min-1;
except
on E: EInvalidOperation do
MessageDlg('Ignoring Exception:'+E.Message,
mtInformation,[mbOK],0);
end;
end;
12.3.2 提供缺省響應
在異常響應模塊中,一般我們只對希望響應的特定異常進行處理。如果一個異常發生而響應模塊並沒有包含對它的處理代碼,則退出當前響應模塊,異常類仍被保留。
為了保證任何異常發生後都能在當前響應模塊中被清除,可以定義缺省響應:
try
{程序正常功能}
except
on ESomething do
{響應特定異常}
else
{提供缺省響應}
end;
由於else可以響應任何異常,包括我們一無所知的異常,因此在缺省響應中最好只包括諸如顯示一個消息框之類的處理,而不要改變程序的運行狀態或數據。