简体   繁体   中英

Java: printing to file when you can't use “throw exception”

I have a class for threads (implements runnable). I want to be able to print text to a file inside the method "run", but I can't add "throws IOException" because run() is an implementation of a method in runnable.

Of course there's no way I'll use a gazillion "Try-Catch" in run()...

Thanks

您可以使用PrintStream包装输出,它永远不会引发异常。

Dealing with checked exceptions in your run() method is tricky for the following reasons:

  1. As @kenson john says (and you observed) you can't simply let them propagate, because run() is not declared as throwing checked exceptions.

  2. If you catch them and rethrow them wrapped in unchecked exceptions, they are likely to go unnoticed by the main thread. Why? Because the exceptions are thrown on the stack of the child thread. Unless they are caught in the run() method, they will be dealt with by the thread's UncaughtExceptionHandler object ... which is likely to be the default handler ... which writes a stacktrace to System.err and then discards the exception.

  3. Now you can set another UncaughtExceptionHandler object for the child thread, or even set a default UncaughtExceptionHandler for the JVM. But what should the handler do? Ideally, the exception needs to be reported back to the main thread (or whatever) to take executive action. But there's no way that the child thread, or a handler for that thread can throw an exception on the main thread's stack. (The best you could do to get the main thread's attention would be to set a flag or call Thread.interrupt() on the main thread ... and hope that it checks the flag / interrupt status periodically.)

  4. Any IOException that is thrown while writing to an output file indicates that something serious has gone wrong; eg the file system is full, or the socket or pipe you were writing to is broken / closed. So simply ignoring it could be a big mistake. (For instance, suppose that the file is precious, and that the last thing that the application does is to delete the old version of the file and replace it with the new version we just created. Ooops! We didn't notice that the FS filled up, the new version of the file is corrupt and we just deleted the old version.)

In the light of this, the PrintStream approach is simplest. A PrintStream will quietly catch any IOException that occurs while writing, but record the fact that an exception has occurred. So when the main thread decides that everything should have finished writing, it needs to call PrintStream.checkError() to test if any errors have occurred. (Unfortunately, the API does not allow you to find out what the actual exception was.)

If you want to do a particular I/O operation in many places without putting each one in an exception handler, just create a function with an exception handler (ie it doesn't throw). Then call the non-throwing function to do all your I/O.

I understand why you want to do this, but I think it is a bad practice to throw and catch an exception from run() (which is impossible for the reason mentioned below).

An exception generated from run() would be considered as an "Unchecked" exception in Java. This kind of exception should not be caught by the programmer, and should be taken care of by the VM.

Unchecked exception generally happen at runtime, example: NullPointerException, IllegalStateException.

IOException being a subclass of java.lang.Exception is considered a Checked Exception, therefore should be handled using a try catch within run() or in a method invoked by run().

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