简体   繁体   中英

What issues may ensue by throwing a checked exception as a RuntimeException?

I have a piece of code that encodes some kind of business data in a JSON string:

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

The thing is:

  • JSONException is a checked exception, but
  • I don't really know how to handle it at compile time. If a JSONException really occurs, it's probably a bug in the the code and should be handled by the regular "global uncaught exception handler" which is already there (eg this ), and which already performs all the necessary logging and cleaning up.

Thus, I ended up doing this in the calling method:

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

It seemed like a lesser evil than adding a throws JSONException to every method up the call stack. However, it still feels dirty, hence my question:

If I want some specific checked exception to go the "regular unchecked exception route", is rethrowing it as a RuntimeException the correct idiom to use?

The situation is quite simple: if your exception has no business value, that is, it is just a failure, definitely use an unchecked exception. If you need to handle the exception in a way specific to that exception, which in most cases means that the handling code will involve business logic, then it is still OK to use an unchecked exception, but there are at least some benefits in using a checked exception. However, in either case the raw exception you get from the JSON API is useless and it is only a sign of bad public API design.

As a side note, there's the "sneaky throw" idiom which will allow you to throw your original checked exception without wrapping:

public static <R> R sneakyThrow(Throwable t) {
  return UncheckedThrower.<RuntimeException, R>sneakyThrow0(t);
}
@SuppressWarnings("unchecked")
private static <E extends Exception, R> R sneakyThrow0(Throwable t) throws E { throw (E)t; }

Needless to say, you should be very careful about using this approach in a project.

Short answer, yes.

You could probably create your own exception class (a child of runtime exception) and re throw that to make it easier to document, catch/ handle it where necessary. Something like hibernate does by using HibernateException, client/ calling code is not forced to catch it but can always catch it when something logical/ application specific can be done with it.

There is an argument for using only unchecked exception in your Java code. If you want to follow that approach, wrapping checked exception them as you have done is the only sensible thing to do. FWIW, I have used this approach many times and it has been useful.

Even if you don't want to buy in to that style it may be still be useful to convert some checked exceptions to runtime exceptions.

I do this all the time. Yes it is a good approach to do it. No, it is not a dirty approach. Personally, I cant stand checked exceptions. I wrap all checked exceptions as runtime exceptions regardless of what type of exception it is.

Well, if you don't intend to handled the exception in you application code then you can throw it as RuntimeException .

I prefer to use com.google.common.base.Throwables to propagate this.

Checked exception is a way to communicate between developers. Checked exceptions says "handle me". If you know what you do, you can rethrow exceptions (and log).

EDIT: as in other answer rewrap exception is also good advice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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