There are a variety of things that could be done to PrintWriter to solve some common use cases.
The main issue that arises is the need to handle IOException when performing I/O operations. PrintWriter has a family of print methods that handle all primitives and objects, and these don't throw IOException. This makes them convenient to use.
However, PrintWriter's error handling is poor, and the current API leads toward exceptions being ignored or dropped. The problem is that nobody calls checkError(), so it's easy for any errors to go unnoticed. In addition, any IOException that actually occurs is simply thrown away. A better exception handling approach might be to have a persistent error state. This scheme would look something like the following:
1. Opening a PrintWriter on something that actually does output (e.g., a file of some sort) would still throw IOException. Opening a PrintWriter on an OutputStream or Writer won't throw IOException. (This is pretty much as things stand today.)
2. The usual print functions aren't declared to throw IOException. If an error occurs in a print function, the actual exception is saved in the object (in addition to the boolean "trouble" being set).
3. Behavior should be defined if an exception is recorded and then subsequent print functions are called. This will be the usual case. If I/O is subsequently attempted and succeeds, this will likely result in corrupted output (because the previous operation had failed). If I/O is attempted and fails, there is the question of what should be done with the exception. It could be added to the suppressed exception list of the initial exception. Alternatively, once the object is in an error state, it might be reasonable simply to ignore subsequent print operations.
4. The checkError() and clearError() methods could remain. Possibly, variations or overloads could be added that deal with the actual exception instead of the boolean. The clearError() method has rather dubious semantics, though it's protected, so conceivably a subclass might find a use for it.
5. The close() method should rethrow any saved IOException, after attempting to close and possibly storing any caught exception in the original exception's suppressed exception list.
Fitting all this into the existing API might be difficult. Adding static factory methods instead of new constructors might be an approach. This would also enable the change in exception behavior (instead of adding more booleans to the constructors). A static factory method might also create a PrintWriter on a Path. This could be on PrintWriter or possibly something like java.nio.file.Files.newPrintWriter(). If this is too difficult, it may be necessary to introduce a new class.
The main issue that arises is the need to handle IOException when performing I/O operations. PrintWriter has a family of print methods that handle all primitives and objects, and these don't throw IOException. This makes them convenient to use.
However, PrintWriter's error handling is poor, and the current API leads toward exceptions being ignored or dropped. The problem is that nobody calls checkError(), so it's easy for any errors to go unnoticed. In addition, any IOException that actually occurs is simply thrown away. A better exception handling approach might be to have a persistent error state. This scheme would look something like the following:
1. Opening a PrintWriter on something that actually does output (e.g., a file of some sort) would still throw IOException. Opening a PrintWriter on an OutputStream or Writer won't throw IOException. (This is pretty much as things stand today.)
2. The usual print functions aren't declared to throw IOException. If an error occurs in a print function, the actual exception is saved in the object (in addition to the boolean "trouble" being set).
3. Behavior should be defined if an exception is recorded and then subsequent print functions are called. This will be the usual case. If I/O is subsequently attempted and succeeds, this will likely result in corrupted output (because the previous operation had failed). If I/O is attempted and fails, there is the question of what should be done with the exception. It could be added to the suppressed exception list of the initial exception. Alternatively, once the object is in an error state, it might be reasonable simply to ignore subsequent print operations.
4. The checkError() and clearError() methods could remain. Possibly, variations or overloads could be added that deal with the actual exception instead of the boolean. The clearError() method has rather dubious semantics, though it's protected, so conceivably a subclass might find a use for it.
5. The close() method should rethrow any saved IOException, after attempting to close and possibly storing any caught exception in the original exception's suppressed exception list.
Fitting all this into the existing API might be difficult. Adding static factory methods instead of new constructors might be an approach. This would also enable the change in exception behavior (instead of adding more booleans to the constructors). A static factory method might also create a PrintWriter on a Path. This could be on PrintWriter or possibly something like java.nio.file.Files.newPrintWriter(). If this is too difficult, it may be necessary to introduce a new class.