2014-01-17 2 views
-2

действительно глупый вопрос, но, возможно, у кого-то есть умный ответ:Почему метод close() в java генерирует исключение?

Почему методы close() в исключениях Java исключают?

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

благодарит ВСЕХ

PS: в основном речь идет о предметном дизайне и концепции развития (не зависит от конкретной реализации)

теперь вы, вероятно, правы, что это имеет смысл, но как писать красиво такой код :

try { 
} catch (Exception e) { 
    logger.error("Error occured during copy", e); 
} finally { 
    // close all objects 
    try { 
     connection.close(); 
    } catch (...) { 
     ... 
    } finally { 
     ... 
    } 
} 

спасибо.

+3

'близко()' метод какого класса вы имеете в виду? –

+2

Было бы полезно увидеть код и конкретное исключение. – Dan

+1

Вы можете уточнить, что вы пытаетесь закрыть, и в каком классе он принадлежит? – Miller

ответ

3

Существует много классов, которые не требуют непосредственной работы, таких как объекты данных, карты, списки, поскольку для этих объектов управление ресурсами просто.

Те классы, которые предлагают тесную работу, обычно связаны с более сложным управлением ресурсами. Довольно часто они включают методы буферизации.

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

+0

+1 Очень подробно – zee

2

Вообще говоря, исключение IOException будет закрыто, если окончательный флеш не удастся. и это может иметь место по многим причинам. Допустим, у вас есть OutputStream, который по какой-то причине еще не был записан в файл. Вызов close() приведет к вымыванию данных, но если файл заблокирован - тогда будет вызвано исключение IOException.

+1

Если файл был заблокирован до того, как был выпущен запрос на открытую запись, этот запрос должен быть отклонен. Если файл открыт для записи, внешние попытки заблокировать файл должны завершиться ошибкой. Лучшим примером проблемного сценария будет захват USB-накопителя между последним запросом «написать» файл и запрос «закрыть» его. Раньше операция не имела бы никаких оснований для неудачи, но закрытие не могло быть успешным. Единственный выбор - это выбросить исключение или позволить пользователю ошибочно полагать, что файл был правильно написан. – supercat

0

close() Функция также выдаст исключение, если соединение, которое вы пытаетесь закрыть, не существует. Например. в SQL-соединении JDBC подключение может не открыться в первую очередь из-за неправильного URL-адреса JDBC или имени пользователя или пароля, функция close() генерирует исключение в этом случае.

1

Если вы хотите написать, что более приятно, вы можете использовать примерочный с-ресурсом включает в себя с Java7:

http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

try (BufferedReader br = new BufferedReader(new FileReader(path))) { 
    return br.readLine(); 
} 

Это позволяет вам определить ресурс, как в OutputStream, например, который будет автоматически закрыт в конце попытки.

Не меняется, как он работает под капотом, но он более изящный.

+1

Функция * major * try-with-resources, которая была бы большой болью, чтобы попытаться реализовать любой другой способ, заключается в том, что исключение, которое происходит во время 'закрытия', будет подавлено * только *, если другое исключение ожидает. Во многих случаях было бы целесообразно и полезно «закрывать» выдачу исключения в случае ошибки использования (например, предполагается, что любая транзакция, которая запускается с помощью обертки транзакций, должна быть зафиксирована или откатна до закрытия оболочки , при попытке закрыть без коммита или отката исключение может быть более полезным, чем молчащий откат, но ... – supercat

+0

... если исключение, которое происходит во время транзакции, вызывает «закрытие» без фиксации или откат был запрошен, если исключение «закрыть» исключение будет - за исключением случаев, когда оно используется в try-with-resources, - приведет к потере другого исключения. – supercat

3

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

Хорошо иметь мнения.К сожалению, мнения не всегда звучат :-)

Рассмотрим, что происходит, когда вы закрываете FileOutputStream завернутое в BufferedOutputStream:

  1. Любые выдающиеся данные в буфере очищено.
  2. Основной файловый дескриптор «закрыт».

Первая из этих операций может сбой, например, если файловая система заполнена.

Теперь представьте, что приложение записывало критический файл; например программа «adduser», которая обновляет «/ etc/passwd» в системе UNIX/Linux. Естественно, приложение будет делать это в два этапа. Сначала он выпишет новую версию файла. Затем, если это удастся, он переименует новый файл в путь к файлу старого файла. (Или что-то в этом роде)

Но если мы внедрили close(), как вы этого хотите, уровень приложения не знал бы, что close() не смог записать все данные ... и «adduser» перейдет к переименованию новый неполный «passwd» файл поверх старой версии. По электронной почте Ой !! Вы только что уничтожили «/ etc/passwd», и никто больше не может войти в систему. (Я надеюсь, что у вас есть резервная лента под рукой :-))

Урок:IOExceptions брошенной close() может быть важным.


Вы правы, конечно, но что-то не чувствует себя хорошо в письменной форме, что структура.

Ну, синтаксис «try-with-resources» делает это приятнее. Тем не менее, вы не можете избежать сделки с IOException на каком-то уровне, если у вас нет свободного объявления о том, что close() по статическому типу connection не генерирует исключение.

Попробовать-с-ресурсов версия будет выглядеть следующим образом:

try (Connection c1 = openConnection(); 
    Connection c2 = openConnection()) { 
    // so stuff 
} 

Оба c1 и c2 будут закрыты, даже если один из них close() методов бросает исключение. Но вам все равно придется иметь дело с этим исключением; например в прилагаемом обработчике. (Интересные вещи происходят, когда исключения выбрасываются внутри tryи в закрытии ресурса; смотрите раздел «Исключения» подавлено в http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html.)

+1

Вы правы, конечно, но что-то не кажется правильным в письменном виде, что структура – builtofire

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