在Java中创建异常的一般经验法则是什么?

时间:2020-03-05 18:43:03  来源:igfitidea点击:

我曾经遇到过两种情况:

  • 创建过多的自定义异常
  • 使用太多的通用Exception类

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

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

解决方案

回答

基本上,每个工作都应该有自己的例外。捕获异常时,我们不会像对待对象那样区分不同的实例,因此需要不同的子类型。我看不到使用太多自定义异常的情况。

一种建议是根据需要创建异常,如果很明显一种异常类型是另一种的重复类型,则可以通过合并两者来重构代码。当然,如果从一开始就将一些想法用于构造异常,这将有所帮助。但通常,对于与现有的特定于情况的例外没有1:1对应的所有情况,请使用自定义例外。

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

回答

我的经验法则是,当客户端(调用方)合理地希望做一些不同的事情时,根据抛出的异常类型,可以保证其他异常类型。但是,通常不需要多余的异常类型。例如,如果调用方正在编写类似

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

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

回答

Java专家写了一篇有关Java异常的文章,其中列出了一些创建异常的"最佳实践",总结如下:

  • 不要编写自己的异常(Java API已经包含很多有用的异常)
  • 编写有用的异常(如果我们必须编写自己的异常,请确保它们提供有关所发生问题的有用信息)

回答

如果找不到名称描述引起错误的类型的异常,那么我将自己处理。

那是我的经验法则。

回答

我自己的经验法则:

我从来不会抛出Exception,除非在单元测试中抛出的异常是无关紧要的,并且没有理由花更多的时间在上面。

我为在自定义业务逻辑中发生的错误创建了自己的自定义异常类型。尽可能使用此异常类型来重播其他异常,除非在适当的情况下客户端可以看到实际发生的情况。

回答

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

Joshua Bloch在《有效的Java编程语言指南》(最佳实践的第一本圣经)第8章中对此进行了介绍。例外项42:赞成使用标准例外。这是他说的话

Reusing preexisting exceptions has several benefits. Chief among these, it makes your API easier to learn and use because it matches established conventions with which programmers are already familiar [my emphasis, not Bloch's]. A close second is that programs using your API are easier to read because they aren't cluttered with unfamiliar exceptions. Finally, fewer exception classes mean a smaller memory footprint and less time spent loading classes.
  
  The most commonly reused exception is IllegalArgumentException. This is generally the exception to throw when the caller passes in an argument whose value is inappropriate. For example, this would be the exception to throw if the caller passed a negative number in a parameter representing the number of times some action were to be repeated.

也就是说,我们永远不要抛出Exception本身。 Java具有一堆精心选择的,多样化且针对性强的内置异常,这些异常可以覆盖大多数情况,并描述发生得很好的异常,以便我们可以纠正原因。

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