Зачем это делать
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
cs.close();
rs.close();
}
Вместо этого
} catch (SQLException sqle) {
sqle.printStackTrace();
}
rs.close();
cs.close();
Зачем это делать
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
cs.close();
rs.close();
}
Вместо этого
} catch (SQLException sqle) {
sqle.printStackTrace();
}
rs.close();
cs.close();
Потому что, если исключение получает бросок , код после try
блока выполняется, если исключение не поймано. Блок finally
всегда выполняется независимо от того, что происходит внутри вашего блока try
.
Посмотрите на свой блок catch - он собирается бросить DAOException
. Поэтому заявления после вашего блока catch не будут выполняться даже в выбранном вами образце. То, что вы показали (обертывание одного исключения в другом), является одним общим шаблоном, но другая возможность заключается в том, что блок catch "случайно" генерирует исключение, например. потому что один из вызовов, которые он вызывает, терпит неудачу.
Кроме того, могут быть другие исключения, которые вы не улавливаете - либо потому, что вы объявили, что метод их выбрасывает, либо потому, что они неконтролируемые исключения. Вы действительно хотите утечки ресурсов, потому что IllegalArgumentException
был брошен где-то?
Потому что, если выбрано исключение,
Код в предложении finally будет выполняться по мере того, как исключение распространяется наружу, даже если исключение отменяет оставшуюся часть выполнения метода;
Код после того, как блок try/catch не будет выполнен, если исключение не будет захвачено блоком catch и не будет повторно показано.
Потому что он гарантирует, что материал в блоке finally будет выполнен. Материал после того, как catch не может быть выполнен, скажем, например, есть еще одно исключение в блоке catch, что очень возможно. Или вы просто делаете то, что делаете, и бросаете исключение, обертывающее исходное исключение.
Ключевое слово finally гарантирует, что код будет выполнен. В нижнем примере инструкции close НЕ выполняются. В верхнем примере они выполняются (что вам нужно!)
В вашем втором подходе не будут выполняться операторы "close", поскольку он уже оставил метод.
Если вы поймаете все ошибки, не должно быть различий, иначе выполняется только код внутри блока finally, потому что последовательность выполнения кода: наконец код → ошибка бросить → код после catch следовательно, как только ваш код выкинет любую необработанную ошибку, только код кода, как правило, работает, как ожидалось.
Это способ избежать утечек ресурсов
Код в блоке finally будет вызван до того, как исключение будет сброшено из блока catch. Это гарантирует, что вызывается код очистки, который вы положили в блок finally. Код за пределами блока finally не будет запущен.
это может прояснить: http://www.java2s.com/Code/Java/Language-Basics/Finallyisalwaysexecuted.htm
считают, что catch может генерировать исключение для функций более высокого уровня в стеке вызовов. Это приведет к окончанию вызова, прежде чем выбросить исключение на верхний уровень.
В http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html это вводит в заблуждение (и, возможно, возник вопрос):
The try block of the writeList method that you've been working with here opens a PrintWriter. The program should close that stream before exiting the writeList method. This poses a somewhat complicated problem because writeList try block can exit in one of three ways.
1. The new FileWriter statement fails and throws an IOException.
2. The list.get(i) statement fails and throws an IndexOutOfBoundsException.
3. Everything succeeds and the try block exits normally.
Отсутствует 4th way (исключение, отличное от IOException
и IndexOutOfBoundsException
). Код, изображенный на предыдущей странице, только ловит (1) и (2), прежде чем прибегать к finally
.
Я также новичок в Java и задал тот же вопрос перед тем, как найти эту статью. Скрытая память, как правило, больше привязывается к примерам, чем к теории.
Блок finally может не всегда выполняться, рассмотрите следующий код.
public class Tester {
public static void main(String[] args) {
try {
System.out.println("The main method has run");
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("The finally block has run");
}
}
}
В вашем случае я бы предложил обернуть код внутри finally block в try/catch, так как этот код, по-видимому, может вызвать исключение.
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
try {
cs.close();
rs.close();
} catch (Exception e) {
//handle new exception here
}
Согласно HeadFirst Java, блок finally будет работать, даже если блок try или catch имеет оператор return. Поток переходит к окончанию, а затем назад, чтобы вернуться.