而不是抛出new Exception("Some message", maybeSomeCause)
,这意味着我的方法的所有调用者都需要捕获Exception(可以包含RuntimeExceptions),我想在出现问题时抛出更具体的异常类型。 / p>
我可以创建自己的异常类型来扩展Exception或其他异常类型,但我很好奇是否重新使用核心Java语言带来的一些异常,例如:
还有其他人我错过了吗?我在这里找到了一个基本的“核心”例外列表:http://rymden.nu/exceptions.html,并附有谦逊的解释。
谢谢!
修改
是否有一个很好的“核心”例外列表?
到目前为止列表:
答案 0 :(得分:22)
是的,这样做非常好。事实上,它甚至在 Effective Java,2nd ed。中有所描述。请参阅第248页的第60项:“赞成使用标准例外”
重用先前存在的例外有几个好处。主要的 这些,它使您的API更容易学习和使用,因为它匹配 程序员已经熟悉的既定惯例。一个 紧随其后的是使用API的程序更容易阅读 因为他们不会被不熟悉的例外所混淆。最后(和 至少),更少的异常类意味着更小的内存占用 加载课程的时间减少了。
答案 1 :(得分:16)
您的问题中提供的列表不是很有用的快速参考资料,并且开发文档中的大多数描述对我来说都显得神秘莫测。
我没有碰到任何最可重复使用的内置异常的简短列表。我已尽力在下面创建一个,但我确信它远非完美。
github gist link(或参见下面的当前内容)
按估计实用程序组织
抛出以表明方法已被传递为非法或不恰当的参数。
抛出以指示某种索引(例如数组,字符串或向量)超出范围。
当请求的数学运算是非敏感或不可能时抛出。
例如:int x = 1/0
;
应用程序未处于所请求操作的适当状态。 示例:在加载或创建文件之前尝试保存。
当您收到格式不正确的数据时,请将其丢弃。
例如:MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")
如果事情花了太长时间并且你放弃了,就扔掉它。
我认为如果您尝试使用密钥查找对象并且未找到该密钥或密钥无效,则抛出此信息是有意义的,但我并不真正了解其中的dev docs
示例:当myDataStructure.get("lookup_key");
不在数据结构中时,lookup_key
。
阅读/写作有问题吗?抛出这个例外。
运行某种形式的脚本并发现它有问题(不是I / O或解析)?抛出这个例外。
如果您遇到与安全相关的问题,请抛弃此信息。
将此用于某些不适合任何其他类别的运行时错误。
答案 2 :(得分:1)
当它们合理地描述导致引发异常的场景时,重用Exception
类是绝对有意义的。
答案 3 :(得分:1)
除非您复制核心库中的现有功能,否则大多数核心异常都太专业化而无法直接使用。例如,您可能永远不需要创建UnknownHostException
的实例;如果主机解析失败,则您调用的InetAddress
或SocketFactory
方法已经创建并抛出异常。
我发现通常可用的唯一例外是IOException
,IllegalArgumentException
,IllegalStateException
和UnsupportedOperationException
。
IOException
- 接口,网络和硬盘访问的所有问题都属于这个问题。如果您正在编写代码来访问外部数据或硬件,那么您应该使用它。例如,如果您正在实现API以访问某种类型的网络设备,则可以在设备返回错误状态或执行某些特殊操作时生成MyDeviceException
子类。在某些情况下,您希望从一个或多个低级库调用中捕获IOException
并将其包含在具有更高级别消息的另一个IOException
中,例如连接检查抛出“设备不可用“由”请求超时“例外引起的异常。
IllegalArgumentException
- 任何参数检查都应该抛出这个。例如,size参数的负整数或意外的null
。这是一个未经检查的异常,但我建议记录它,以使方法的前提条件更加清晰。你可以在核心库中找到很多例子。
IllegalStateException
- 您可以在方法参数有效时使用此方法,但方法所需的某些内部数据或功能不可用,并且没有更合适的已检查异常(如IOException
)。设计事物通常更好,这是不必要的。
UnsupportedOperationException
- 如果你创建了某个东西的子类,并且其中一个超类方法在概念上对它无效,则覆盖它并抛出其中一个。 Guava将其用于immutable collection classes,因为Java的集合接口并非旨在支持不变性。这往往是超类中糟糕设计的标志。如果不做任何事情或者返回null / empty将是一个合适且不令人惊讶的结果,请不要使用它。
答案 4 :(得分:0)
如果您的代码的用户可能需要对两个不同的异常执行不同的操作,那么这些异常应该是不同的异常类型。也就是说,JDK异常涵盖了大多数“程序员错误”异常 - 如果IllegalArgumentException
被抛出,例如,表示编程错误,而不是应该在运行时处理的东西。