我在某处读到(现在找不到)大型异常层次结构是浪费时间。这个陈述的理由在当时似乎很合理,这个想法一直困扰着我。
在我自己的代码中,当我有一个可以有一系列错误条件的代码库时,我使用一个枚举成员的异常来区分它们。
如果出现我需要抓住其中一个错误的情况,我会抓住它,检查枚举并重新抛出是否不符合我的预期。理想情况下,这应该是罕见的。
我再次处理异常,我有一个反思的时刻,我质疑我的异常习惯。我很好奇其他人做了什么以及为什么?
数据成员的层次结构或一个例外。
顺便说一句,我假设您同意异常与错误代码的概念。我不想打开那种虫子。答案 0 :(得分:12)
简单的经验法则:
答案 1 :(得分:11)
我认为只有一个嵌入枚举的异常类型不是最理想的:
要回答你的问题,我正在使用异常层次结构。它比它的深度要广泛得多。
答案 2 :(得分:7)
你不应该对此有教条。使用最适合手头问题的东西。我的经验法则如下:
答案 3 :(得分:4)
我认为你正处于两个世界中最糟糕的世界。大型异常层次结构是无用的,因为已知客户端是惰性的,并且最终仅检查顶层节点(可能仅针对层次结构根)。你的枚举系统没有解决这个问题,并且使得一个更加麻烦的异常捕获系统。
如果你真的知道需要很多不同的例外,并且捕手真的想要不同的例外(知道,而不是模糊地思考),继续大的层次结构并忘记枚举。否则,坚持使用小的异常层次结构,并且只提供对捕获者来说真正有用的异常类。
答案 4 :(得分:3)
根据我的经验,太多的异常类只会让人感到困惑,特别是它们只用于一种非常特殊的问题。我已经看到一个系统,其中每个错误条件都有它自己的异常,但只有在catch块中检查了超类。子类完全是浪费时间。
另一方面,必须检查枚举并重新抛出异常会使代码不那么直观,因为您无法识别catch之后直接抛出的异常。也许只是一个小缺点,但如果经常使用它会对可读性产生影响。当在需要非常快的代码中使用时,它也可能造成性能问题。
我不会使用枚举解决方案,而是使用一些具有足够广泛频谱的异常类型。就像DatabaseException而不是像TableNotFoundException,ColumnNotFoundexception等几个例外一样。根据我的经验,这对大多数开发人员来说效果最好。您始终可以添加一个字段,其中包含您向用户显示的一些错误代码,以便更轻松地在用户和支持之间进行通信。
答案 5 :(得分:2)
通过使用一个异常类型和枚举子类型替换它们,您无法解决太多异常类的问题。事实上,你只会让事情变得更糟!
示例:假设您有Exception类型Ex1..Ex99,例如E14..E18是E1等的孩子。您现在决定将它们替换为Ex和子类型ST1..ST99之外的一个例外。你有什么解决的?没什么 - 人们仍然需要处理所有可能性。你做得更糟糕了什么?您不能忽略ST14-ST18并将它们视为ST1的出现。你现在必须处理所有99种可能性,因为你的枚举子类型没有自然,灵活的层次结构。
答案 6 :(得分:1)
不要将错误与例外混为一谈 错误发生,尽可能地解决问题 例外是罕见的,如果没有更多的上下文信息,通常无法解决。
如果出现问题并且可以在本地纠正,那么您应该使用错误代码并在那里处理它。
应该使用异常将问题在调用堆栈中传播到具有足够信息来解决问题的上下文。
这样说:枚举不是可行的方法,因为它们绕过了编译器将自动生成的整个try catch机制。
答案 7 :(得分:0)
我喜欢为不同的错误分类设置少量例外,例如致命/非致命条件或应用程序的特定层或模块。然后,异常的thrower应提供代码作为异常的有效负载。应用程序的表示层可以查找与代码对应的本地化人类可读错误消息。
总之,异常类型对开发人员很有用,对应于错误代码的消息对用户很有用。