6

is this bad practice?

public String foo(File file) {
    StringBuilder sb = new StringBuilder();
    try(
            BufferedInputStream bis =
                    new BufferedInputStream(
                            new FileInputStream(file))
    ) {
        for(int c = bis.read(); c != -1; c = bis.read())
            sb.append((char) c);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    return sb.toString();
}

Assume that there is no way to gracefully recover from the checked exception.

Joseph Nields
  • 5,527
  • 2
  • 32
  • 48
  • possible duplicate of [The case against checked exceptions](http://stackoverflow.com/questions/613954/the-case-against-checked-exceptions). http://stackoverflow.com/questions/27578/when-to-choose-checked-and-unchecked-exceptions might also an interesting read –  Aug 06 '15 at 16:39
  • 1
    Throwing exceptions is NEVER good practice IMHO – cjds Aug 06 '15 at 16:40
  • 7
    @cjds then I'm curious how you handle exceptional cases! – Jorn Aug 06 '15 at 16:44
  • I prefer to use custom exceptions that extend from `RuntimeException` and wrap possible problems when interacting with external APIs. In the end, I catch the exception in a bigger place to display a nice message for end user, but still log the whole stacktrace to analyze the causes of the issues. – Luiggi Mendoza Aug 06 '15 at 16:45
  • See [`readAllBytes()`](http://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#readAllBytes-java.nio.file.Path-): `return new String(Files.readAllBytes(file), StandardCharsets.US_ASCII);` – erickson Aug 06 '15 at 16:49

3 Answers3

5

This is not ideal, but there are situations when there is no other workaround.

This approach becomes convenient when foo(File file) is an implementation of an interface method or an override of a superclass method which does not declare the checked exception. This situation forces you deal with the exception internally, or wrap it in a non-checked exception.

The problem, however, is that subclasses of RuntimeException are supposed to signal programming errors; IOException, on the other hand, does not signal a programming error, so wrapping it in RuntimeException in order to circumvent Java compiler's checks is wrong.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

The Java runtime uses UncheckedIOException for this kind of situation.

I would argue that it is a bad practice to define new types of unchecked exceptions and let them escape from a library, because it causes leaky abstractions. If you are going to rethrow a checked exception as an unchecked exception, find a suitable RuntimeException subclass in the core Java runtime.

erickson
  • 265,237
  • 58
  • 395
  • 493
1

Checked exceptions are problematic--I've heard them best described as a "Failed Experiment".

Unchecked runtime exceptions are a pretty good way to handle sticky situations. For instance, you often have a large high-level thread that is expected to run "Forever". There may be 30 places in that thread (inside different methods) that read from a database or interact with some other unstable source.

If that data source fails, you always want to handle it the same way--reconnect then restart your main loop.

This is very easily handled in the high-level thread but if each object handles it itself it spreads horrible error-check code all across your project.

So the answer is, feel free to wrap your checked in an unchecked runtime exception if there isn't anything useful you can do at that level--and I'd advise NEVER throwing a checked exception unless there is something that the caller MUST handle immediately (Which is almost never the case--most problems can be handled at a higher level).

By the way, I do this a lot and almost never use new exceptions--you can reuse existing ones unless you have some reason to differentiate between the exceptions at a higher level.

Bill K
  • 62,186
  • 18
  • 105
  • 157