繁体   English   中英

使检查异常成为RuntimeException

[英]Making a checked exception a RuntimeException

我正在使用一个具有自定义异常的遗留系统,该异常使用了gosh-frickity-everywhere。 它受到ServletException类的启发,它表示“好吧,只要Servlet中有异常,就要抛出该ServletException ”。

随着系统的发展(超过10年),已经出现了一个更强大的系统来捕获更高级别的异常,不再需要将所有异常包装在此自定义异常中。 (可以说从来没有,但是那是另一回事了。它是一个稳定的应用程序,所以我不会抱怨太多!!)但是我们不会立即重构它们,只是随着时间的推移会慢慢地重构它们。

但是,使自定义异常是运行时异常而不是检查异常是使事情变得更简单的一件事。 这样,我们就不需要在任何地方显式捕获它,而尚未重构的旧代码将继续以与抛出空指针异常(如果发生的话)相同的方式抛出此异常。

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

除了不必要的警告和引发声明的警告外,我想不出任何办法,但是最好还是从以前走过这条路的人那里得到意见。

将一个已检查的异常更改为一个未检查的异常对现有的工作代码几乎没有实际影响,但是您确实需要注意在代码中某个地方被catch (RuntimeException ...)的可能性catch (RuntimeException ...) 这样的捕获现在不会拦截您的自定义异常,但是如果您不对其进行检查,它们就会这样做。

如果您做任何与引发该异常的方法相关的事情(这显然是其中的大多数),也可能会遇到问题。

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

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

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

我们在整个层上都粗心地使用了该模式,并且当我们需要检查异常原因时,我们总是必须找出异常原因,这在高层中产生了很多样板。 到目前为止,我相信最好创建一个良好的非检查异常类层次结构,以保持粒度。 例如

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

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

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

我可以想到的一些

  • 运行时异常可能会到达您不希望执行的层。
    • 例如:一个Servlet --->服务---> DAO。 DAO引发的与数据库交互相关的运行时异常可能会落在Servlet上。 清晰地隔离各个层,其中每个层在其入口点都处理所有异常(已检查/运行时),可以确保不会发生这种情况。
  • 运行时异常可能会使系统处于不一致状态。
    • 例如:如果序列图看起来像A级-> B级---> C级,并且如果B1级被注入到B和C之间,那么A级---> B级-> B1级->然后,类C,类A,B,B1都不知道在类C中发生此运行时异常时可能必须清除它们。实际上,这可能会影响任何依赖项注入的语义。

我认为一般的经验法则是:

  • 当您“期望”异常作为常规控制流的一部分并知道如何处理时,请使用检查的异常。 例如:验证业务规则后,帐户余额必须至少大于借方金额100。
  • 当您“不希望”将异常作为正常控制流的一部分使用时,请使用未经检查的异常,因此无法对其进行处理,但您知道“层”中的“某些类”将对其进行处理以确保正常降级,例如:DB连接丢失将由“服务”层条目类处理。
  • 永远不要使用错误。 仅JRE有引发错误的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM