(delphi11最新学习资料) Object Pascal 学习笔记---第9章第6节(嵌套异常和 InnerException机制)

本文主要是介绍(delphi11最新学习资料) Object Pascal 学习笔记---第9章第6节(嵌套异常和 InnerException机制),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

9.6 异常的高级功能

​ 除非你对这门语言已经有了很好的了解,否则第一次阅读这部分内容时最好跳过。在此之前,你可以先阅读下一章,将来再回到这一部分。

​ 在本章的最后一部分,我将介绍一些与异常处理相关的高级主题。我将介绍嵌套异常(RaiseOuterException)和拦截类的异常(RaisingException)。

​ 这些功能在早期版本的 Object Pascal 语言中并不存在,但它们为系统增添了强大的功能。

9.6.1 嵌套异常和 InnerException 机制

​ 如果在异常处理器中引发异常,会发生什么情况?传统的答案是,新的异常将取代现有的异常,这就是为什么通常的做法是至少将错误信息合并在一起,写出这样的代码(缺少任何实际操作,只显示与异常相关的语句):

procedure TFormExceptions.ClassicReraise;
begintry// Do something...raise Exception.Create('Hello');excepton E: Exception do// Try some fix...raise Exception.Create('Another: ' + E.Message);end;
end;

​ 这段代码是 AdvancedExcept 示例的一部分。在调用该方法并处理异常时,你会看到一个包含两个异常信息的单一异常:

procedure TFormExceptions.BtnTraditionalClick(Sender: TObject);
begintryClassicReraise;excepton E: Exception doShow('Message: ' + E.Message);end;
end;

​ 输出结果(非常明显)是:

Message: Another: Hello

​ 现在在Object Pascal中,有了对嵌套异常的全系统支持。 在异常处理程序中,您可以创建并引发一个新的异常,同时仍然保持当前异常对象的活动状态,并将其连接到新的异常。 要做到这一点,Exception类有一个InnerException属性(引用前面的异常)和一个BaseException属性(允许访问系列中的第一个异常),因为异常嵌套可以递归。 这些是Exception类中与嵌套异常管理相关的要素:

typeException = class(TObject)privateFInnerException: Exception;FAcquireInnerException: Boolean;protectedprocedure SetInnerException;publicfunction GetBaseException: Exception; virtual;property BaseException: Exception read GetBaseException;property InnerException: Exception read FInnerException;class procedure RaiseOuterException(E: Exception); static;class procedure ThrowOuterException(E: Exception); static;end;

​ 静态类方法是类方法的一种特殊形式。我们将在第 12 章中解释这一语言特性。

​ 从用户的角度来看,要在保留现有异常的同时引发异常,应调用 RaiseOuterException 类方法(或相同的 ThrowOuterException 方法,后者使用面向 C++ 的命名)。处理类似异常时,可以使用新属性访问更多信息。请注意,您只能在异常处理器中调用 RaiseOuterException,这一点基于源代码文档:

Use this function to raise an exception instance from within an exception handler and you want to “acquire” the active exception and chain it to the new exception and preserve the context. This will cause the FInnerException field to get set with the exception currently in play.

使用此函数从异常处理程序中引发异常实例,并且您希望“获取”活动异常并将其链接到新异常并保留上下文。这将导致 FInnerException 字段设置为当前正在播放的异常。

You should only call this procedure from within an except block where this new exception is expected to be handled elsewhere.

您只应从 except 块中调用此过程,在该块中,此新异常应在其他地方处理。

有关实际示例,请参阅 AdvancedExcept 示例。在这个示例中,我添加了一个以新方式引发嵌套异常的方法(与前面列出的 ClassicReraise 方法相比):

procedure TFormExceptions.MethodWithNestedException;
begintryraise Exception.Create('Hello');exceptException.RaiseOuterException(Exception.Create('Another'));end;
end;

现在,在这个外部异常的处理器中,我们可以访问两个异常对象(也可以看到调用新的 ToString 方法的效果):

tryMethodWithNestedException;
excepton E: Exception dobeginShow('Message: ' + E.Message);Show('ToString: ' + E.ToString);if Assigned(E.BaseException) thenShow('BaseException Message: ' + E.BaseException.Message);if Assigned(E.InnerException) thenShow('InnerException Message: ' + E.InnerException.Message);end;
end;

该调用的输出结果如下:

Message: Another
ToString: Another
Hello
BaseException Message: Hello
InnerException Message: Hello

​ 有两个相关要素需要注意。首先,在单个嵌套异常的情况下,BaseException 属性和 InnerException 属性都指向同一个异常对象,即原始异常对象。其次,虽然新异常的消息只包含实际消息,但通过调用 ToString,可以访问所有嵌套异常的合并消息,并用 sLineBreak 分隔(如 Exception.ToString 方法的代码所示)。

​ 在这种情况下选择使用换行符会产生奇怪的输出结果,但一旦你知道了它,你就可以按照自己喜欢的方式来格式化它,用你选择的符号替换换行符,或者将它们赋值给字符串列表的 Text 属性。

​ 再举一个例子,让我向你展示引发两个嵌套异常时会发生什么。这个就是新方法:

procedure TFormExceptions.MethodWithTwoNestedExceptions;
begintryraise Exception.Create('Hello');excepttryException.RaiseOuterException(Exception.Create('Another'));exceptException.RaiseOuterException(Exception.Create('A third'));end;end;
end;

​ 这调用的方法与我们之前看到的方法完全相同,输出结果如下:

Message: A third
ToString: A third
Another
Hello
BaseException Message: Hello
InnerException Message: Another

​ 这一次,BaseException 属性和 InnerException 属性指向了不同的对象,ToString 的输出跨越了三行。

这篇关于(delphi11最新学习资料) Object Pascal 学习笔记---第9章第6节(嵌套异常和 InnerException机制)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/908056

相关文章

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

python 常见数学公式函数使用详解(最新推荐)

《python常见数学公式函数使用详解(最新推荐)》文章介绍了Python的数学计算工具,涵盖内置函数、math/cmath标准库及numpy/scipy/sympy第三方库,支持从基础算术到复杂数... 目录python 数学公式与函数大全1. 基本数学运算1.1 算术运算1.2 分数与小数2. 数学函数

Python Pillow 库详解文档(最新推荐)

《PythonPillow库详解文档(最新推荐)》Pillow是Python中最流行的图像处理库,它是PythonImagingLibrary(PIL)的现代分支和继承者,本文给大家介绍Pytho... 目录python Pillow 库详解文档简介安装核心模块架构Image 模块 - 核心图像处理基本导入

Redis的持久化之RDB和AOF机制详解

《Redis的持久化之RDB和AOF机制详解》:本文主要介绍Redis的持久化之RDB和AOF机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述RDB(Redis Database)核心原理触发方式手动触发自动触发AOF(Append-Only File)核

Python变量与数据类型全解析(最新整理)

《Python变量与数据类型全解析(最新整理)》文章介绍Python变量作为数据载体,命名需遵循字母数字下划线规则,不可数字开头,大小写敏感,避免关键字,本文给大家介绍Python变量与数据类型全解析... 目录1、变量变量命名规范python数据类型1、基本数据类型数值类型(Number):布尔类型(bo

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

CSS Anchor Positioning重新定义锚点定位的时代来临(最新推荐)

《CSSAnchorPositioning重新定义锚点定位的时代来临(最新推荐)》CSSAnchorPositioning是一项仍在草案中的新特性,由Chrome125开始提供原生支持需... 目录 css Anchor Positioning:重新定义「锚定定位」的时代来了! 什么是 Anchor Pos

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg