24

Some days ago I realized that PrintWriter (as well as PrintStream) never throw an IOException when writing, flushing or closing.

Instead it sets an internal flag (trouble=true) when an error occurs.
It's not possible to get the exact exception, but only if there was some exception (checkError()).

My question is: why would one want to have such behavior? Isn't that bad API design?

Benedikt Waldvogel
  • 12,406
  • 8
  • 49
  • 61
  • 2
    I was just looking this up. I found it really strange too. It's one thing to hide the exception, but to drop it altogether? What if I really want to know the contents of the exception? I expected a getError() method but... it's a really strange design decision. – aberrant80 Jan 28 '10 at 12:26

6 Answers6

11

I think that since System.out and System.err are instances of PrintStream, some more relaxed error handling was provided. This was probably, as other posters have mentioned, to smooth the way for those transitioning from C/C++ circa 1995. When the Reader/Writer API was added, PrintWriter was created to parallel the existing PrintStream.

One application where this behavior is extremely desirable is logging. Logging is ancillary to a larger application. Typically, if logging fails, one doesn't want that the entire application to fail. Thus, it makes sense for System.err, at least, to ignore exceptions.

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

I wonder if its because IOExceptions are checked, this would require you placing a try catch block around every System.out. call.

update: Or a throws in your method signature.

That would get annoying very quickly.

Owen
  • 2,759
  • 1
  • 14
  • 9
  • A checked exception doesn't strictly require a try-catch block, of course. PrintStream is rarely used in production code, and its usage within the core libraries is limited to logging, where failures can be safely ignored. – erickson Nov 18 '08 at 03:12
  • They could still throw a runtime exception, instead of the IOException, rather than setting an internal flag. – Gonen I Sep 03 '16 at 22:16
1

I don't really know the story, but I think it was to make Java easier for newer programmers who the designers wanted to be able to use simple stdio printing methods without the need to know what exceptions are. So in that regard it is good design (I agree with you somewhat though).

Josh
  • 17,834
  • 7
  • 50
  • 68
1

Sun / Oracle should have added two write-like functions, one that throws an IOException and another that doesn't throw anything.

Bonita Montero
  • 2,817
  • 9
  • 22
0

It's possible that the design was done by someone coming from a C background where stdio errors are handled in a similar fashion. Since I'm used to that paradigm, I wouldn't call it bad, but I'd agree that it is inconsistent.

I also agree with the comment about trying to make PrintWriter easier to use. The IO classes in Java are confusing (at least for everyone I know) and perhaps someone was just trying to make life a little bit easier.

jdigital
  • 11,926
  • 4
  • 34
  • 51
0

It is not a design error. It is a proper design meant to be used in a situation when you write an output and you want errors to be ignored.

As a typical use case, the System.out and System.err were already mentioned, but the reason is not relaxed handling for convenience or smooth C/C++ transitions . It is a desired handling of a situation like this:

  • you start an application in a console
  • it produces output to the std out/err
  • you close the console, but you want the application to continue in the background

In this situation, depending on the system implementation, it could happen that System.out or System.err would fail after the console is closed, but you don't want that to crash your application. The application is wanted to continue to run in the background and the output is meant to be scraped. That's what PrintWriter does.

If you care about errors during the output, use FileWriter or OutputStreamWriter. If you need some of the methods available in PrintWriter and not available in FileWriter, create your own TextWriter extending FileWriter or OutputStreamWriter.

David L.
  • 3,149
  • 2
  • 26
  • 28