使检查的异常成为RuntimeException

时间:2014-08-29 14:40:45

标签: java runtimeexception

我正在开发一个遗留系统,该系统有一个自定义异常,它在任何地方都使用了gosh-frickity。它的灵感来自ServletException类,它说“好的,只要你的Servlet中有异常,你就会想要抛出这个ServletException”。

随着系统的发展(超过10年),已经发生了一个更强大的系统,可以在更高级别捕获异常,并且不再需要在此自定义异常中包装每个异常。 (有人可能会说它从来没有,但这是另一个故事。它是一个稳定的应用程序,所以我不会抱怨太多!!)但我们不会立刻重构它们,只是慢慢地重构。

但是,如果自定义异常是运行时异常而不是已检查的异常,那么使事情变得更简单的一件事就是。这样我们就不需要在任何地方明确地捕获它,并且尚未重构的遗留代码将继续抛出它,就像它们抛出空指针异常一样。

我的问题是...... 获取一次检查过的异常并使其成为运行时异常有什么副作用?

除了警告不必要的检查和抛出声明之外,我无法想到任何事情,但是从以前一直走在这条路上的人那里得到输入会很好。

3 个答案:

答案 0 :(得分:2)

将已检查的异常更改为未经检查的异常对现有的工作代码几乎没有实际影响,但您需要注意代码中某处catch (RuntimeException ...)的可能性。此类捕获现在不会拦截您的自定义异常,但如果您取消选中它们,它们就会执行。

如果你做了与抛出异常的方法有关的任何反映(显然是大多数异常),你也可能会遇到问题。

答案 1 :(得分:0)

类似的事情发生在我必须维护的应用程序的旧模块上。将异常转换为运行时的唯一问题是您可能会丢失粒度,但这完全取决于您处理。

例如,我们在更深层次中有大量这样的代码:

catch(IOException e){    
    Throwables.propagate(e);
}

我们在该层上不小心使用了该模式,当我们需要检查异常原因时,我们总是必须得到异常的原因并且在更高层中创建了大量样板。到目前为止,我认为最好创建一个非检查异常的良好类层次结构,以保持粒度。 e.g。

catch(IOException e){
    throw new FileNotCreatedException(e);
}

通过这种方式,您可以轻松地在其他层中捕获异常并轻松划分错误和后备:

catch(FileNotCreatedException e){
   notifyError(e);
} catch(NoMoreStorageException e){
   releaseSomeStorage();
   retryOperation();
}

答案 2 :(得分:0)

以下是我能想到的一些

  • 运行时异常可能会转到您不打算去的层。
    • ex:a Servlet --->服务---> DAO。 DAO抛出的与数据库交互相关的运行时异常可能会出现在Servlet上。明确隔离层,其中每个层在其入口点处理所有异常(检查/运行时)可以确保不会发生这种情况。
  • 运行时异常会使系统处于不一致状态。
    • 例如:如果序列图看起来像A类 - > B级---> C类,如果在B和C之间注入B1类,则A类---> B级---> B1级--->然后,类C,A类,B类,B1类都不知道它们可能必须在类C中发生此运行时异常时进行清理。事实上,这可能会影响任何依赖注入的语义。

在我看来,作为一般的拇指规则:

  • 当您将“异常”视为正常控制流的一部分时,请使用已检查的异常并知道如何处理它。例如:业务规则的验证表明帐户余额必须大于借方金额至少100。
  • 当你“不期望”将异常作为正常控制流程的一部分时使用未经检查的异常因此无法处理它但你知道“层”中的“某个类”将处理它以确保优雅降级例如:数据库连接丢失将由您的“服务”层条目类处理。
  • 绝不使用错误。只有JRE有理由抛出错误。