在Java中创建Exception的一般规则是什么?

时间:2008-08-25 21:46:43

标签: java exception

我遇到过两种情况:

  • 创建过多的自定义例外
  • 使用太多的常规异常类

在这两种情况下,项目都开始运行,但很快就成了维护(和重构)的开销。

那么关于创建自己的异常类的最佳实践是什么?

8 个答案:

答案 0 :(得分:17)

The Java Specialists撰写了一篇关于Exceptions in Java的帖子,其中列出了一些创建例外情况的“最佳做法”,摘要如下:

  • 不要编写自己的异常(有很多有用的异常已经是Java API的一部分)

  • 编写有用的例外(如果您必须编写自己的例外,请确保它们提供有关所发生问题的有用信息)

答案 1 :(得分:13)

不要做我公司的开发人员所做的事情。有人创建了[sic] InvalidArguementException,它与java.lang.IllegalArgumentException相似,现在我们在(字面上)数百个类中使用它。两者都表明方法已被传递为非法或不恰当的参数。谈论浪费......

Joshua Bloch在有效的Java编程语言指南 [我的最佳实践的第一手段] 第8章例外 项目42:赞成使用标准例外情况。这是他说的一点,

  

重用先前存在的例外有几个好处。其中最重要的是,它使您的API更易于学习和使用,因为它符合程序员已经熟悉的既定惯例 [我的重点,而不是Bloch的]。紧接其后的是,使用您的API的程序更容易阅读,因为它们不会被不熟悉的异常所混淆。最后,更少的异常类意味着更小的内存占用和更少的加载类所花费的时间。

     

最常用的异常是IllegalArgumentException。当调用者传入一个值不合适的参数时,这通常是抛出的异常。例如,如果调用者在一个参数中传递一个负数来表示某个动作要重复的次数,那么这将是抛出的异常。

那就是说,你应该从不抛出异常本身。 Java有一个精心挑选,多样化且目标明确的一系列内置异常,涵盖大多数情况 AND 描述发生的异常,以便您可以纠正原因。

对于将来必须维护代码的程序员友好。

答案 2 :(得分:8)

我的经验法则是当客户端(调用者)可能合理地想要做一些不同的事情时,根据抛出的异常类型,保证附加的异常类型。但是,通常不需要额外的异常类型。例如,如果调用者正在编写类似

的代码
try {
     doIt();
} catch (ExceptionType1 ex1) {
     // do something useful
} catch (ExceptionType2 ex2) {
     // do the exact same useful thing that was done in the block above
}

然后显然不需要额外的异常类型。我经常看到(或者被迫编写)这样的代码,因为被调用的代码在创建新的异常类型时过于热心。

答案 3 :(得分:7)

如果我找不到一个具有描述错误类型的名称的异常,那么我自己创建。

这是我的大拇指。

答案 4 :(得分:4)

基本上,每项工作都应该有自己的例外。当您捕获异常时,您不区分不同的实例,就像您通常使用对象一样,因此您需要不同的子类型。使用太多自定义异常是我认为几乎没有发生的情况。

一个建议是根据需要创建异常,如果很明显一个异常类型与另一个异常类型重复,则通过合并两者来重构代码。当然,如果从一开始就考虑构建异常,它会有所帮助。但通常情况下,对于与现有的特定情况异常没有1:1对应关系的所有情况使用自定义例外。

另一方面,NullPointerExceptionIndexOutofBoundsException可能实际上是合适的。不要抓住这些(除了日志记录)因为它们是编程错误,这意味着在抛出它们之后,程序处于未定义状态。

答案 5 :(得分:3)

我自己的经验法则:

我从不抛出异常,除非在单元测试中,你抛出的东西是无关紧要的,并且没有理由花费任何额外的时间。

我为自定义业务逻辑中出现的错误创建了自己的自定义异常类型。此异常类型尽可能用于重新设计其他异常,除非客户能够了解实际发生的情况。

答案 6 :(得分:3)

创建自己的例外时:

  • 所有例外必须是Throwable Class

  • 的孩子
  • 如果要编写由句柄或声明规则自动强制执行的已检查异常,则需要扩展Exception Class

  • 如果要编写运行时execption,则需要扩展Runtime Exception Class。

答案 7 :(得分:0)

不要吃异常,将它们抛出https://stackoverflow.com/a/921583/1097600

避免创建自己的异常。使用下面已经存在的那些。

IllegalStateException
UnsupportedOperationException
IllegalArgumentException
NoSuchElementException
NullPointerException

抛出未经检查的异常。

示例

public void validate(MyObject myObjectInstance) {
    if (!myObjectList.contains(myObjectInstance))
        throw new NoSuchElementException("object not present in list");
}