将检查的exception作为RuntimeException抛出会导致什么问题?

我有一段代码在JSON字符串中编码某种业务数据:

public String encodeDataAsJsonString(Data data) throws JSONException { JSONObject o = new JSONObject(); o.put("SomeField1", data.getSomeProperty1()); o.put("SomeField2", data.getSomeProperty2()); ... return o; } 

事情是:

  • JSONException是一个经过检查的exception,但是
  • 我真的不知道如何在编译时处理它。 如果真的发生了JSONException,它可能是代码中的一个错误,应该由已经存在的常规“全局未捕获exception处理程序”(例如这个 )处理,并且已经执行了所有必要的日志记录和清理。

因此,我最终在调用方法中执行此操作:

 ... try { encoded = encodeDataAsJsonString(data); } catch (JSONException e) { throw new RuntimeException(e); } ... 

throws JSONException向调用堆栈中的每个方法添加throws JSONException似乎是一个小恶魔。 但是,它仍然感觉很脏,因此我的问题是:

如果我想要一些特定的检查exception去“常规未经检查的exception路由”,是否将它重新抛出为RuntimeException使用的正确习惯用法?

简短的回答,是的。

您可能可以创建自己的exception类(运行时exception的子代)并重新抛出它以便更容易记录,在必要时捕获/处理它。 像hibernate这样的东西通过使用HibernateException来实现,客户端/调用代码不会被强制捕获它,但是当可以使用它完成逻辑/应用程序特定的事情时它总能捕获它。

情况非常简单:如果您的exception没有业务价值,也就是说,它只是一个失败,肯定会使用未经检查的exception。 如果您需要以特定于该exception的方式处理exception,这在大多数情况下意味着处理代码将涉及业务逻辑,那么使用未经检查的exception仍然可以,但使用a时至少有一些好处检查exception。 但是,在任何一种情况下,从JSON API获得的原始exception都是无用的,这只是公共API设计错误的标志。

作为旁注,有“偷偷摸摸”的习惯用法,它可以让你在没有包装的情况下抛出原始的检查exception:

 public static  R sneakyThrow(Throwable t) { return UncheckedThrower.sneakyThrow0(t); } @SuppressWarnings("unchecked") private static  R sneakyThrow0(Throwable t) throws E { throw (E)t; } 

不用说,在项目中使用这种方法时应该非常小心。

在Java代码中使用未经检查的exception存在争议。 如果你想要遵循这种方法,那么像你所做的那样包装已检查的exception是唯一明智的做法。 FWIW,我已多次使用这种方法并且它很有用。

即使您不想购买该样式,将一些已检查的exception转换为运行时exception仍然很有用。

我一直这样做。 是的,这是一个很好的方法。 不,这不是一个肮脏的方法。 就个人而言,我无法检查例外情况。 我将所有已检查的exception包装为运行时exception,而不管它是什么类型的exception。

好吧,如果您不打算在应用程序代码中处理exception,那么您可以将其作为RuntimeException抛出。

我更喜欢使用com.google.common.base.Throwables传播此内容。

检查exception是开发人员之间进行通信的一种方式。 检查过的例外说“处理我”。 如果你知道你做了什么,你可以重新抛出exception(和日志)。

编辑:如在其他答案重写exception也是很好的建议。