抛出异常时的Java最佳实践:抛出核心Java异常

时间:2012-04-04 17:48:03

标签: java exception exception-handling

而不是抛出new Exception("Some message", maybeSomeCause),这意味着我的方法的所有调用者都需要捕获Exception(可以包含RuntimeExceptions),我想在出现问题时抛出更具体的异常类型。 / p>

我可以创建自己的异常类型来扩展Exception或其他异常类型,但我很好奇是否重新使用核心Java语言带来的一些异常,例如:

  • 抛出:IllegalArgumentException
  • UnsupportedOperationException异常
  • IOException的
  • 其他?

还有其他人我错过了吗?我在这里找到了一个基本的“核心”例外列表:http://rymden.nu/exceptions.html,并附有谦逊的解释。

谢谢!

修改

是否有一个很好的“核心”例外列表?

到目前为止

列表:

5 个答案:

答案 0 :(得分:22)

是的,这样做非常好。事实上,它甚至在 Effective Java,2nd ed。中有所描述。请参阅第248页的第60项:“赞成使用标准例外”

  

重用先前存在的例外有几个好处。主要的   这些,它使您的API更容易学习和使用,因为它匹配   程序员已经熟悉的既定惯例。一个   紧随其后的是使用API​​的程序更容易阅读   因为他们不会被不熟悉的例外所混淆。最后(和   至少),更少的异常类意味着更小的内存占用   加载课程的时间减少了。

答案 1 :(得分:16)

您的问题中提供的列表不是很有用的快速参考资料,并且开发文档中的大多数描述对我来说都显得神秘莫测。

我没有碰到任何最可重复使用的内置异常的简短列表。我已尽力在下面创建一个,但我确信它远非完美。

github gist link(或参见下面的当前内容)

可能可重用的内置异常列表

按估计实用程序组织

抛出:IllegalArgumentException

抛出以表明方法已被传递为非法或不恰当的参数。

IndexOutOfBoundsException异常

抛出以指示某种索引(例如数组,字符串或向量)超出范围。

ArithmeticException

当请求的数学运算是非敏感或不可能时抛出。 例如:int x = 1/0;

IllegalStateException异常

应用程序未处于所请求操作的适当状态。 示例:在加载或创建文件之前尝试保存。

DataFormatException

当您收到格式不正确的数据时,请将其丢弃。 例如:MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")

TimeoutException异常

如果事情花了太长时间并且你放弃了,就扔掉它。

KeySelectorException

我认为如果您尝试使用密钥查找对象并且未找到该密钥或密钥无效,则抛出此信息是有意义的,但我并不真正了解其中的dev docs

示例:当myDataStructure.get("lookup_key");不在数据结构中时,lookup_key

IOException的

阅读/写作有问题吗?抛出这个例外。

ScriptException

运行某种形式的脚本并发现它有问题(不是I / O或解析)?抛出这个例外。

GeneralSecurityException

如果您遇到与安全相关的问题,请抛弃此信息。

的RuntimeException

将此用于某些不适合任何其他类别的运行时错误。

答案 2 :(得分:1)

当它们合理地描述导致引发异常的场景时,重用Exception类是绝对有意义的。

答案 3 :(得分:1)

除非您复制核心库中的现有功能,否则大多数核心异常都太专业化而无法直接使用。例如,您可能永远不需要创建UnknownHostException的实例;如果主机解析失败,则您调用的InetAddressSocketFactory方法已经创建并抛出异常。

我发现通常可用的唯一例外是IOExceptionIllegalArgumentExceptionIllegalStateExceptionUnsupportedOperationException

IOException - 接口,网络和硬盘访问的所有问题都属于这个问题。如果您正在编写代码来访问外部数据或硬件,那么您应该使用它。例如,如果您正在实现API以访问某种类型的网络设备,则可以在设备返回错误状态或执行某些特殊操作时生成MyDeviceException子类。在某些情况下,您希望从一个或多个低级库调用中捕获IOException并将其包含在具有更高级别消息的另一个IOException中,例如连接检查抛出“设备不可用“由”请求超时“例外引起的异常。

IllegalArgumentException - 任何参数检查都应该抛出这个。例如,size参数的负整数或意外的null。这是一个未经检查的异常,但我建议记录它,以使方法的前提条件更加清晰。你可以在核心库中找到很多例子。

IllegalStateException - 您可以在方法参数有效时使用此方法,但方法所需的某些内部数据或功能不可用,并且没有更合适的已检查异常(如IOException )。设计事物通常更好,这是不必要的。

UnsupportedOperationException - 如果你创建了某个东西的子类,并且其中一个超类方法在概念上对它无效,则覆盖它并抛出其中一个。 Guava将其用于immutable collection classes,因为Java的集合接口并非旨在支持不变性。这往往是超类中糟糕设计的标志。如果不做任何事情或者返回null / empty将是一个合适且不令人惊讶的结果,请不要使用它。

答案 4 :(得分:0)

如果您的代码的用户可能需要对两个不同的异常执行不同的操作,那么这些异常应该是不同的异常类型。也就是说,JDK异常涵盖了大多数“程序员错误”异常 - 如果IllegalArgumentException被抛出,例如,表示编程错误,而不是应该在运行时处理的东西。