29

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

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

  • IllegalArgumentException
  • 不支持的操作异常
  • IO异常
  • 其他的?

还有其他我想念的吗?我在这里找到了“核心”例外的基本列表:http: //rymden.nu/exceptions.html,并附有幽默的解释。

谢谢!

编辑:

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

到目前为止的清单:

4

5 回答 5

25

是的,这样做非常好。事实上,它甚至在《Effective Java, 2nd ed》中也有过介绍。请参阅第 248 页的第 60 项:“支持使用标准例外”

重用预先存在的异常有几个好处。其中最主要的是,它使您的 API 更易于学习和使用,因为它符合程序员已经熟悉的既定约定。紧随其后的是使用您的 API 的程序更易于阅读,因为它们不会被不熟悉的异常所困扰。最后(也是最不重要的),更少的异常类意味着更小的内存占用和更少的加载类的时间。

于 2012-04-04T17:52:27.537 回答
19

您问题中提供的列表不能用作快速参考材料,并且开发文档中的大多数描述对我来说似乎很神秘。

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

github gist 链接(或查看下面的当前内容)

潜在可重用的内置异常列表

按估计效用组织

IllegalArgumentException

抛出以指示方法已传递了非法或不适当的参数。

IndexOutOfBoundsException

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

算术异常

当请求的数学运算没有意义或不可能时抛出。示例:int x = 1/0;

非法状态异常

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

数据格式异常

当您收到格式不正确的数据时抛出这个。例子:MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")

超时异常

如果某件事花费了太长时间并且您放弃了,请抛出这个。

键选择器异常

我认为如果您尝试使用密钥查找对象但未找到该对象或该密钥无效,则抛出此内容是有意义的,但我并不真正了解其上的开发文档

例如:myDataStructure.get("lookup_key");whenlookup_key不在数据结构中。

IO异常

读/写有问题?抛出这个异常。

脚本异常

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

一般安全异常

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

运行时异常

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

于 2015-10-04T00:33:46.387 回答
3

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

我发现通常可用的唯一例外是IOException, IllegalArgumentException,IllegalStateExceptionUnsupportedOperationException.

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

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

IllegalStateException- 当方法参数有效,但方法所需的某些内部数据或功能不可用,并且没有更合适的检查异常(如IOException)时,您可以使用它。通常最好设计一些东西,这样就没有必要了。

UnsupportedOperationException- 如果你创建了某个东西的子类,并且其中一个超类方法在概念上对其无效,请覆盖它并抛出其中一个。Guava 将其用于其不可变集合类,因为 Java 的集合接口并非旨在支持不可变性。这往往是超类中设计不良的标志。如果什么都不做或返回 null/empty 将是适当且不足为奇的结果,请不要使用它。

于 2017-06-09T20:28:39.960 回答
1

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

于 2012-04-04T17:51:59.377 回答
0

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

于 2012-04-04T17:52:45.820 回答