(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进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

Mysql中InnoDB与MyISAM索引差异详解(最新整理)

《Mysql中InnoDB与MyISAM索引差异详解(最新整理)》InnoDB和MyISAM在索引实现和特性上有差异,包括聚集索引、非聚集索引、事务支持、并发控制、覆盖索引、主键约束、外键支持和物理存... 目录1. 索引类型与数据存储方式InnoDBMyISAM2. 事务与并发控制InnoDBMyISAM

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

StarRocks索引详解(最新整理)

《StarRocks索引详解(最新整理)》StarRocks支持多种索引类型,包括主键索引、前缀索引、Bitmap索引和Bloomfilter索引,这些索引类型适用于不同场景,如唯一性约束、减少索引空... 目录1. 主键索引(Primary Key Index)2. 前缀索引(Prefix Index /

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

Nginx之upstream被动式重试机制的实现

《Nginx之upstream被动式重试机制的实现》本文主要介绍了Nginx之upstream被动式重试机制的实现,可以通过proxy_next_upstream来自定义配置,具有一定的参考价值,感兴... 目录默认错误选择定义错误指令配置proxy_next_upstreamproxy_next_upst

解决java.lang.NullPointerException问题(空指针异常)

《解决java.lang.NullPointerException问题(空指针异常)》本文详细介绍了Java中的NullPointerException异常及其常见原因,包括对象引用为null、数组元... 目录Java.lang.NullPointerException(空指针异常)NullPointer

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

Java中实现订单超时自动取消功能(最新推荐)

《Java中实现订单超时自动取消功能(最新推荐)》本文介绍了Java中实现订单超时自动取消功能的几种方法,包括定时任务、JDK延迟队列、Redis过期监听、Redisson分布式延迟队列、Rocket... 目录1、定时任务2、JDK延迟队列 DelayQueue(1)定义实现Delayed接口的实体类 (