(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 的输出跨越了三行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式学习——Linux基础——day1

1. linux基础命令 1.1 ls 查看当前目录下的所有文件 ls -l 查看文件的详细信息 ls -a 查看当前目录下的所有文件(包含隐藏文件) 1.2 touch 创建一个空的普通文件 1.3 rm 删除一个普通文件 rm -rf 删除非…

大模型用到的位置编码汇总(面试)

不同于RNN、CNN等模型,对于Transformer模型来说,位置编码的加入是必不可少的,因为纯粹的Attention模块是无法捕捉输入顺序的,即无法区分不同位置的Token。为此我们大体有两个选择:想办法将位置信息融入到输入中&#x…

用odin实现的资源复制编辑器

用odin实现了一个资源复制编辑器,使用要安装odin,功能是把要复制的资源路径一个个添加设置,点copy能把列表里的资源全部复制,支持目录复制到目录,文件复制到目录,文件复制替换。提升效率,让自己…

Office 365卡顿怎么办?SD-WAN可以解决

随着数字化浪潮的推进,Office 365等云办公应用已成为企业日常运营不可或缺的工具。然而,许多企业在使用Office 365时遭遇了网络卡顿的难题,给工作人员带来诸多不便。随着SD-WAN技术的成熟和普及,这一难题得到了有效的解决。 Offic…

使用JWT、Redis + token实现用户登录的两种方式。

使用JWT实现登录功能 功能实现流程: 1.用户发起登录请求。 2.使用JwtBuilder生成令牌并返回。 3.写一个拦截器,拦截初登录之外的请求。拦截到请求后解析令牌,若正常放行,并将当前用户id存在当前线程。若出异常则返回登陆失败。…

四足机器人应用篇之solidwork导出URDF

欢迎关注微信公众号 “四足机器人研习社”,本公众号的文章和资料和四足机器人相关,包括行业的经典教材、行业资料手册,同时会涉及到职业知识学习及思考、行业发展、学习方法等一些方面的文章。 |1.URDF介绍 一个URDF pakage示例 urdf是ROS用于…

ABAP MESSAGE 常用的类型

类型文本描述A终止处理终止,用户必须重启事务X退出与消息类型A 类似,但带有程序崩溃 MESSAGE_TYPE_XE错误处理受到干扰,用户必须修正输入条目,左下角提示!W警告处理受到干扰,用户可以修正输入条目,左下角提示!I信息处理受到干扰&a…

数据库讲解---(数据更新、视图、数据控制)【MySQL版本】

目录 前言 一.数据更新 1.1插入数据 1.1.1插入单个元组 1.1.2将一个新学生记录(学号:091530,姓名:夏雨,性别:男,籍:海南,出生年份:1999,学院:计算机)插入到学生表中 1.1.3插入子查询结果 1.1.4有一个表“DEPT”(SDEPT CHAR(20),AVG_AGE SMALLINT)表示每个学院的学生的平…

习题4-1 求奇数和

本题要求计算给定的一系列正整数中奇数的和。 输入格式: 输入在一行中给出一系列正整数,其间以空格分隔。当读到零或负整数时,表示输入结束,该数字不要处理。 输出格式: 在一行中输出正整数序列中奇数的和。 输入样例: 8 7 4 3 70 5 6 …

R 格式(蓝桥杯)

文章目录 R 格式【问题描述】高精度乘法高精度加法 R 格式 【问题描述】 小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R格式整数的做法是&#…

网络安全-自学笔记

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员(以编程为基础的学习)再开始学习 我在之前的回答中,我都一再强调不要以编程为基础再开始学习网络安全,一般来说,学习编程不但学习周期长,而…

【力扣TOP100热题图解】T1.两数之和

题目链接点这里—— 力扣(LeetCode)​​​​​​ 法一:暴力枚举 最容易想到的方法是枚举数组中的每一个数 x,寻找数组中是否存在 target - x。 当我们使用遍历整个数组的方式寻找 target - x 时,需要注意到每一个位…

【Linux】磁盘管理和文件系统

目录 一、硬盘 1.硬盘结构 2.结构类型 二、MBR与磁盘分区 1.MBR主引导记录 2.磁盘分区结构 三、文件系统类型 四、linux系统添加并使用新硬盘的步骤 1.添加新的硬盘 2.刷新识别 3.进行分区 4.格式化,创建文件系统 5.挂载使用 一、硬盘 1.硬盘结构…

SpringBoot整合消息中间件(ActiveMQ,RabbitMQ,RocketMQ,Kafka)

消息中间件 消息消息队列JMS AMQPMQTTKafka Spring整合消息队列模拟消息队列的工作流程Spring整合ActiveMQSpring整合RabbitMQ直连交换机模式主题交换机模式 Spring整合RocketMQSpring整合kafka 消息 消息的发送方:生产者 消息的接收方:消费者 同步消息…

基于SSM项目高校在线请假与审批系统

采用技术 基于SpringBoot框架实现的web的智慧社区系统的设计与实现~ 开发语言:Java 数据库:MySQL 技术:SpringMVCMyBatis 工具:IDEA/Ecilpse、Navicat、Maven 简介 本系统实现了管理员,教师,学生三个模…

OSPF动态路由实验(华为)

思科设备参考:OSPF动态路由实验(思科) 一,技术简介 OSPF(Open Shortest Path First)是一种内部网关协议,主要用于在单一自治系统内决策路由。它是一种基于链路状态的路由协议,通过…

探秘ChatGPT:写作论文的新奇技巧

ChatGPT无限次数:点击直达 探秘ChatGPT:写作论文的新奇技巧 近年来,随着人工智能技术的发展,ChatGPT作为一种强大的自然语言处理工具越来越受到关注。在学术界和工业界,人们开始探索如何利用ChatGPT这样的模型来辅助写作&#xf…

Linux下SPI设备驱动实验:实现SPI发送/接收数据的函数

一. 简介 前面文章介绍了SPI设备数据收发处理流程,后面几篇文章实现了SPI设备驱动框架,加入了字符设备驱动框架代码。文章如下: SPI 设备驱动编写流程:SPI 设备数据收发处理流程中涉及的结构体与函数-CSDN博客 SPI 设备驱动编写…

DevOps(二)Jenkins详细介绍和15天学习计划

Jenkins 是一个开源的自动化服务器,广泛用于持续集成和持续部署(CI/CD)的自动化过程中。它支持开发者在软件开发的各个阶段自动构建、测试并部署应用程序,从而提高开发效率并减少错误。下面详细介绍Jenkins: 一、核心功能 1、构…

【洛谷 P8802】[蓝桥杯 2022 国 B] 出差 题解(带权无向图+单源最短路+Dijkstra算法+链式前向星+最小堆)

[蓝桥杯 2022 国 B] 出差 题目描述 A \mathrm{A} A 国有 N N N 个城市,编号为 1 … N 1 \ldots N 1…N 小明是编号为 1 1 1 的城市中一家公司的员工,今天突然接到了上级通知需要去编号为 N N N 的城市出差。 由于疫情原因,很多直达的交…