自定义异常:通过许多子类或枚举支持的单个类来区分?
我希望为我当前正在从事的项目实现我自己的一组Exceptions
。该项目依赖于一个带有基本框架异常 MyFrameworkException
的核心框架(我也在编写这个框架)。
对于任何给定的项目,我想抛出几种不同类型的异常
,并且我无法决定是使用多个子类还是使用某种形式的Enum
的单个子类作为构造函数参数。
在这两种情况下,我都有:
public class MyFrameworkException extends Exception { /*...*/ }
选项 1:
public class MyProjectBaseException extends MyFrameworkException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
然后,在整个项目中,我会针对发生的任何问题抛出特定的异常。
选项 2:
public class MyProjectException extends MyFrameworkException {
public static enum Type {
SpecificType1, SpecificType2, SpecificType3
}
public MyProjectException( Type type ) { /*...*/ }
}
在这里,对于发生的任何问题,我总是会抛出带有特定枚举类型的 MyProjectException
。我将提供某种机制,以便可以根据类型枚举对任何 MyProjectException
执行 switch 语句。
处理项目中的异常的最佳方法是什么,尤其是那些共享公共基础设施的项目?以上两个选项是好的解决方案吗?为什么或为什么不呢?还有什么更好的解决方案?
I'm looking to implement my own set of Exceptions
for a projects I am currently working on. The project relies on a core framework with a base framework exception MyFrameworkException
(I am also writing this framework).
For any given project I would like to throw several different types of Exceptions
and I can't decide between using multiple subclasses or a single subclass with some form of an Enum
as a constructor parameter.
In both cases I have:
public class MyFrameworkException extends Exception { /*...*/ }
Option 1:
public class MyProjectBaseException extends MyFrameworkException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
Then, throughout the project I would throw the specific exception for any problem that occurs.
Option 2:
public class MyProjectException extends MyFrameworkException {
public static enum Type {
SpecificType1, SpecificType2, SpecificType3
}
public MyProjectException( Type type ) { /*...*/ }
}
Here I would always throw MyProjectException
with the specific enum type for any problem that occurs. I'd provide some mechanism so that a switch statement could be performed on any MyProjectException
based on the type enum.
What's the best way to handle exceptions in projects, especially those sharing a common infrastructure? Are the two options above good solutions? Why or why not? And what are any better solutions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
选项 2(常见异常 + 枚举)的主要缺点是您失去了受检查异常的一些实用性。一种方法几乎必须简单地说“与框架相关的东西可能会出错”:
...而不是“x或y可能会出错”:
这意味着可能需要处理一个框架异常的函数必须准备好处理其中任何一个,而如果您是特定的,函数只需要准备好处理它调用的框架方法引发的异常。
所以对我来说,像选项 1 这样的层次结构(如果结构本身表明它不需要那么平坦)是可行的方法。也就是说,有些人根本不喜欢检查异常,对于他们来说,我怀疑上述内容并不是一个令人信服的论点。 :-)
编辑 并采纳达菲莫的观点:我假设您正在谈论您确实必须创建的异常。绝对在任何有意义的地方抛出标准异常(几乎无处不在)。例如,不要创建自己的
MyFrameworkIllegalArgumentException
,只需使用IllegalArgumentException
(或其各种子类)。The chief disadvantage to Option 2 (a common exception + enum) is that you lose some of the utility of checked exceptions. A method pretty much has to say simply "something framework-related might go wrong":
...rather than "x or y might go wrong":
It means a function that may need to handle one framework exception has to be prepared to handle any of them, whereas if you're specific, a function need only be prepared to handle the exceptions that are thrown by the framework methods it calls.
So for me, a hierarchy such as Option 1 (it needn't be quite so flat, if a structure suggests itself) is the way to go. That said, there are people who don't like checked exceptions at all, and for them I suspect the above is not a compelling argument. :-)
Edit And picking up duffymo's point: I've assumed you were talking about exceptions you really did have to create. Absolutely throw standard exceptions wherever it makes sense (which is nearly everywhere). Don't create your own
MyFrameworkIllegalArgumentException
, for instance, just useIllegalArgumentException
(or its various subclasses).我会选择使用描述性类名扩展 java.lang.RuntimeException 的异常。
如果您有太多特定于业务的例外情况,以至于变得令人难以承受,则意味着您可能做错了。
请参阅 Joshua Bloch 关于支持标准异常的建议。
I would go with exceptions extending java.lang.RuntimeException with descriptive class names.
If you have so many business-specific exceptions that this becomes oppressive, it means you're probably doing it wrong.
See Joshua Bloch's advice about favoring standard exceptions.
我不会继承通用的
MyFrameworkException
,只要您不提供所有项目共有的任何功能。否则,总是扩展 Exception。通常,您应该在域/层边界抛出有意义的异常。因此,关于您的问题,您应该选择选项 1,并牢记上述要点。选项 2 会增加代码复杂性,因为您始终必须检查异常类型以确定出了什么问题。让异常类自己说话。
I wouldn't inherit from a generic
MyFrameworkException
, as long as you dont provide any functionality in there common to all projects. Else, always extend Exception.Normally you should throw meaningful exceptions at domain/layer boundaries. So regarding your question, you should go with option 1, having in mind the point above. Option 2 would increase code complexity, as you will always have to check for the exception type to determine what went wrong. Let the exception class speak for itself.