2014-10-20 5 views
3

В C#, это considered bad practice, чтобы выбросить исключения в Dispose метод IDisposable.Имеет ли смысл использовать метод закрытия AutoCloseable для исключения? Как это должно быть обработано?

Наоборот, в java метод closeAutoCloseable позволяет исключить любое Исключение и заставить вызывающего его обработать каким-либо образом. Но что разумно ожидать от вызывающего, если это произойдет? Это говорит о том, что попытка закрыть ресурс потерпела неудачу. Так пользователь должен попытаться закрыть ресурс еще раз, прежде чем продолжить, возможно, с каким-то экспоненциальным отступлением?

+0

Попробуйте http://stackoverflow.com/questions/4679409/how-to-properly-handle-an-ioexception-from-close –

ответ

0

Похоже, что каждая операция с ресурсами, включая неявный вызов close(), считается частью блока try {}. Даже мысли технически/синтаксически, ресурсы упоминаются вне скобок {}.

Это означает, что при вызове метода IOException во время закрытия() он будет пойман некоторым предложением catch(), связанным с вашей попыткой (или оно будет распространяться вверх).

О причине Причина: Зачем нужно исключать исключения: close() может вызвать flush(), flush() может вызвать write() s, а write() s может завершиться ошибкой.

+0

Если у меня есть попробовать (BufferedReader BR = новый BufferedReader (новый FileReader (путь))) { return br.readLine(); } и 'br.close()' генерирует исключение, то я не буду пытаться снова закрыть ресурс в точке, где мне нужно обработать исключение. Это, по-видимому, предполагает, что нет необходимости пытаться снова закрыть ресурс. –

1

Дизайн AutoCloseable является результатом проверенных исключений Java. Некоторые реализации просто должны иметь возможность выдавать проверенные исключения, и поэтому требуется throws Exception. Тем не менее, implementations should declare more specific types thrown (если таковые имеются):

Хотя этот метод интерфейса объявляется бросить Exception, исполнители являются сильно поощряемые объявить конкретные реализации метода close бросить более конкретные исключения, или не бросать никаких исключений в все, если операция закрытия не может потерпеть неудачу.

Вы не должны исключать исключения, если есть способ избежать этого, но вы не всегда можете избежать этого. Например, при закрытии BufferedOutputStream с незакрепленными данными буферизованный поток имеет два варианта; игнорируя неписанные данные и закрывая их, или записывая их в поток, что может вызвать исключения.

1

Поскольку разработчики Java смогли увидеть проблемы, возникшие с обработкой исключений-исключений в блоках .NET using, прежде чем реализовать свою собственную функцию try-with-resources, они смогли улучшить ее. В .NET автору блока Dispose часто приходится сталкиваться с неприятным выбором между проглатыванием любых исключений, которые возникают, что позволяет ошибочно разрешить вызывающей программе считать, что все в порядке или разрешить исключения, исходящие от Dispose, таким образом, чтобы стереть любые доказательства любого предыдущего исключения. К счастью, Java избегает этой проблемы.

Если блок try-with-resources преуспевает нормально, и close также успешно работает, тогда внешний код видит все как обычно. Если в разделе try возникает исключение, но close успешно выполняется нормально, внешний код будет видеть исключение try-block. Если try завершается нормально, но выбрасывает close, внешний код будет видеть исключение close.И если try выбрасывает, но close также выбрасывает, то внешний код будет видеть исключение try, но также сможет получить любое исключение, которое произошло в пределах close (и если несколько вложенных исключений try-with-resources в течение close, все заброшенные исключения будут доступный внешнему коду).

Следовательно, в отличие от конструкции .NET, который часто вынуждает авторов задушить некоторые потенциально серьезные исключения, брошенные Dispose, дизайн благосклонности Явы, имеющие close сгенерирует исключение в любое время что-то идет достаточно неправильно, что абонент не должно быть позволено верить что все в порядке.

Смежные вопросы