Наиболее распространенными проблемами close () являются нехватка дискового пространства или, как упомянул Брайан, удаленный поток, который потерял свою актуальность.
Примечание:
Вы действительно должны увидеть что-то вроде (примечание: я не проверял компиляцию)
SomeKindOfStream stream = null;
Throwable pending = null;
try {
stream = ...;
// do stuff with stream
} catch (ThreadDeath t) {
// always re-throw thread death immediately
throw t;
} catch (Throwable t) {
// keep track of any exception - we don't want an exception on
// close() to hide the exceptions we care about!
pending = t;
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e) {
if (pending == null)
pending = e;
}
}
if (pending != null) {
// possibly log - might log in a caller
throw new SomeWrapperException(pending);
// where SomeWrapperException is unchecked or declared thrown
}
}
Зачем все это?
Имейте в виду, что Java может отслеживать только одно «ожидающее» исключение за раз. Если тело основного блока try выдает исключение, и , то close () в finally генерирует исключение, единственное, о чем вы будете знать, это close ().
Приведенная выше структура выполняет следующие действия:
- Отслеживайте любые бросаемые броски в теле попытки
- Если это исключение - смерть нити, немедленно отбросьте его!
- При закрытии, если у нас нет ожидающего исключения, отследить исключение закрытия; в противном случае ранее созданное исключение должно отслеживаться. (В этом случае вам, вероятно, следует попытаться зарегистрировать ошибку close ())
- В конце, если есть ожидающее исключение, разберитесь с ним. Я обычно оборачиваю это и перебрасываю это. Лично я использую непроверенную оболочку, поэтому мне не нужно, чтобы все вызывающие в цепочке вызовов объявляли throws.
Чтобы выполнить вышеизложенное, я обычно использую шаблон метода шаблона для создания управления исключениями, а затем перезаписываю метод doWork (), являющийся телом try.