Java: печать в файл, когда вы не можете использовать «выбросить исключение» - PullRequest
1 голос
/ 20 марта 2011

У меня есть класс для потоков (реализует runnable). Я хочу иметь возможность печатать текст в файл внутри метода «run», но я не могу добавить «throws IOException», потому что run () является реализацией метода в runnable.

Конечно, я не буду использовать gazillion "Try-Catch" в run () ...

Спасибо

Ответы [ 4 ]

3 голосов
/ 20 марта 2011

Работа с проверенными исключениями в вашем run() методе сложна по следующим причинам:

  1. Как говорит (и вы заметили) @kenson john, вы не можете просто позволить им распространятьсяпотому что run() не объявляется как выбрасывающий проверенные исключения.

  2. Если вы перехватите их и сбросите их, завернутые в непроверенные исключения, они, вероятно, останутся незамеченными потоком main.Зачем?Потому что исключения выбрасываются в стек дочернего потока.Если они не перехвачены в методе run(), они будут обрабатываться объектом UncaughtExceptionHandler потока ... который, вероятно, будет обработчиком по умолчанию ... который записывает трассировку стека в System.err и затем отбрасывает исключение.

  3. Теперь вы можете установить другой объект UncaughtExceptionHandler для дочернего потока или даже установить значение по умолчанию UncaughtExceptionHandler для JVM.Но что должен делать обработчик?В идеале, об исключении нужно сообщать обратно в поток main (или что-то еще) для принятия исполнительных действий.Но нет никакого способа, которым дочерний поток или обработчик для этого потока может вызвать исключение в стеке основного потока.(Лучшее, что вы можете сделать, чтобы привлечь внимание основного потока, это установить флаг или вызвать Thread.interrupt() в основном потоке ... и надеяться, что он периодически проверяет состояние флага / прерывания.)

  4. Любой IOException, который выдается при записи в выходной файл, указывает, что что-то серьезное пошло не так;например, файловая система заполнена, или сокет или канал, в который вы записывали, поврежден / закрыт.Поэтому простое игнорирование может быть большой ошибкой.(Например, предположим, что файл является ценным, и что последнее, что делает приложение, это удаляет старую версию файла и заменяет ее новой версией, которую мы только что создали. Ой! Мы не заметили, что FSзаполнено, новая версия файла повреждена, и мы просто удалили старую версию.)

В свете этого подход PrintStream является самым простым.PrintStream будет тихо перехватывать любые IOException, возникающие во время записи, но записывать факт возникновения исключения.Поэтому, когда поток main решает, что все должно закончиться, ему нужно вызвать PrintStream.checkError(), чтобы проверить, не возникли ли какие-либо ошибки.(К сожалению, API не позволяет вам выяснить, что именно являлось исключением.)

3 голосов
/ 20 марта 2011

Вы можете заключить вывод в PrintStream, он никогда не выдаст исключения.

1 голос
/ 20 марта 2011

Я понимаю, почему вы хотите это сделать, но я думаю, что это плохая практика - генерировать и перехватывать исключение из run () (что невозможно по причине, указанной ниже).

Исключение, сгенерированное из run (), будет рассматриваться как исключение "не проверено" в Java. Такое исключение не должно быть поймано программистом, и об этом должна позаботиться виртуальная машина.

Непроверенное исключение обычно происходит во время выполнения, например: NullPointerException, IllegalStateException.

IOException, являющийся подклассом java.lang. Исключение считается Проверенным Исключением, поэтому должно обрабатываться с использованием try catch в run () или в методе, вызываемом run ().

1 голос
/ 20 марта 2011

Если вы хотите выполнить определенную операцию ввода-вывода во многих местах, не помещая каждую из них в обработчик исключений, просто создайте функцию с обработчиком исключений (т. Е. Она не выбрасывает).Затем вызовите функцию non-throwing, чтобы выполнить все ваши операции ввода-вывода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...