(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中Object类的常用方法小结

《Java中Object类的常用方法小结》JavaObject类是所有类的父类,位于java.lang包中,本文为大家整理了一些Object类的常用方法,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. public boolean equals(Object obj)2. public int ha

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Java如何通过反射机制获取数据类对象的属性及方法

《Java如何通过反射机制获取数据类对象的属性及方法》文章介绍了如何使用Java反射机制获取类对象的所有属性及其对应的get、set方法,以及如何通过反射机制实现类对象的实例化,感兴趣的朋友跟随小编一... 目录一、通过反射机制获取类对象的所有属性以及相应的get、set方法1.遍历类对象的所有属性2.获取

MySQL中的锁和MVCC机制解读

《MySQL中的锁和MVCC机制解读》MySQL事务、锁和MVCC机制是确保数据库操作原子性、一致性和隔离性的关键,事务必须遵循ACID原则,锁的类型包括表级锁、行级锁和意向锁,MVCC通过非锁定读和... 目录mysql的锁和MVCC机制事务的概念与ACID特性锁的类型及其工作机制锁的粒度与性能影响多版本

Spring使用@Retryable实现自动重试机制

《Spring使用@Retryable实现自动重试机制》在微服务架构中,服务之间的调用可能会因为一些暂时性的错误而失败,例如网络波动、数据库连接超时或第三方服务不可用等,在本文中,我们将介绍如何在Sp... 目录引言1. 什么是 @Retryable?2. 如何在 Spring 中使用 @Retryable

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt