В чем суть finally block В Java?
Я думаю о следующих примерах; но не мог понять, в чем важность блока finally. Можете ли вы сказать мне разницу в выполнении этих двух образцов кода? Также может быть полезен пример из реальной жизни.
Пример 1:
try{
// some code 1
}catch(Exception ex){
// print exception
}finally{
// some code 2
}
Пример 2:
try{
// some code 1
}catch(Exception ex){
// print exception
}
// some code 2
7 ответов
существует большая разница в двух фрагментах, которые вы представили, например, когда catch
блок сам выдает исключение,finally
блок по-прежнему будет выполняться его семантикой.
это следующий фрагмент печатает "Finally!"
, а не "What about me???"
:
try {
throw null; // throws NullPointerException!
} catch (Exception e) {
int oops = 1/0; // throws ArithmeticException!
} finally {
System.out.println("Finally!"); // still gets executed!
}
System.out.println("What about me???"); // doesn't get executed!
вообще говоря,finally
на try
блок практически всегда запускается на выполнение. Нет такой гарантии для любого кода, следующего за try
блок.
а что, если мой
catch
блок просто
есть еще никакой гарантии это не throw
что-то. Что-то все равно может пойти не так, например, в конструкции для подробного сообщения об исключении.
даже если вы приложите все усилия, гарантируйте, что catch
код "безопасный" и код после try
оператор всегда будет выполняться, тогда вопрос становится "почему?". Почему не finally
но тогда так старайтесь воспроизвести его семантику?
finally
семантика гарантирована, не требуя никакого бремени доказательства ни от автора, ни от читателя кода. Именно из-за этого, это идиоматическое использовать finally
блок для установки обязательного кода "очистки". Используя finally
гарантирует правильность и увеличивает и writability и считываемость.
на finally
блок выполняется, даже если, например,Error
бросается, который не пойман catch
блок в вашем примере. Таким образом, вы можете поместить код очистки в finally
блок, который должен быть запущен всегда, независимо от исхода операции в try
и catch
блоки.
обратите внимание, что обычно catch
блоки catch более конкретные типы исключений - часто только проверенные исключения, поэтому в большинстве случаев разница между двумя кода примеры выше очень определенные.
обновление: вы можете сказать, что ваш catch
блок никогда не может выдать исключение, поэтому finally
не требуется. Однако обратите внимание на две вещи:
- это только настоящее состояние кода, и оно может измениться в будущем-можете ли вы гарантировать, что будущий программист, который добавляет некоторый потенциально исключительный код в
catch
блок, не забудьте поместить код очистки после него вfinally
заблокировать? -
try-catch-finally
это Программирование фразеологизм что облегчает людям, читающим код, понимание того, что происходит. Если вы не используете общую идиому, вы рискуете недопониманием, поэтому ошибки в долгосрочной перспективе.
использовать finally
блок для очистки и запуска любого кода, который должен выполняться, было ли создано исключение (и поймано) или нет. Это включает код, который у вас есть в catch
блок.
Это полезно, когда мы хотим освободить ресурсы, которые мы использовали в блок try. Поэтому единственное место, где их можно выполнить, не пропуская ни в коем случае, - это, наконец, блок. Поскольку, если возникает исключение, java не выполняет код, который сразу после этого. он сразу в блок catch.
обратите внимание, что вы можете даже попробовать-ваще без улова:
try{
// some code
}finally{
// cleanup code
}
поэтому примером может быть метод, который хочет распространять исключения на вызывающего абонента, но все еще нуждается в очистке кода, например, освобождение взгляда.
в случае, если операторы в try block бросают непроверенные исключения, наконец, блок будет выполнен, позволяя программисту предпринимать соответствующие действия.
В РЕАЛЬНОЙ ЖИЗНИ, блок finally используется для закрытия ресурсов, даже если возникает исключение. Например, при чтении (или записи) файла, при доступе к базе данных и т. д.
public void readFile(String fileName) {
FileReader fr;
BufferedFileReader bfr;
try {
fr = new FileReader(fileName);
bfr = new BufferedFileReader(fr);
// ...
} catch (IOException ioe) {
// ...
} finally {
// TO ENSURE THAT THE READERS ARE CLOSED IN ALL CASES
if (bfr != null) {
try {
bfr.close();
} catch (IOException ignoredIOE) {}
}
if (fr != null) {
try {
fr.close();
} catch (IOException ignoredIOE) {}
}
}
}