Когда я очищал некоторый код, FindBugs указал мне на немного кода JDBC, который использует объекты Connection, CallableStatement и ResultSet.Вот фрагмент этого кода:
CallableStatement cStmt = getConnection().prepareCall("...");
...
ResultSet rs = cStmt.executeQuery();
while ( rs.next() )
{
...
}
cStmt.close();
rs.close();
con.close();
FindBugs указал, что они должны находиться в блоке finally.Я начал рефакторинг своего кода, чтобы сделать это, и я начал задаваться вопросом, как обрабатывать код в блоке finally.
Возможно, что создание объектов CallableStatement of Connection вызовет исключение, оставив мой объект ResultSet какноль.Когда я пытаюсь закрыть ResultSet, я получаю исключение NullPointerException, и мое Соединение, в свою очередь, никогда не закроется.Действительно, этот поток поднимает ту же концепцию и показывает, что обертывание ваших вызовов close () в нулевую проверку является хорошей идеей.
Но как насчет других возможных исключений?Согласно спецификации API Java, Statement.close () может генерировать исключение SQLException «в случае ошибки базы данных».Поэтому, даже если мой CallableStatement не равен NULL и я могу успешно вызвать для него функцию close (), я все равно могу получить исключение и не иметь возможности закрыть другие мои ресурсы.
Единственное «отказоустойчивое» решениеЯ могу подумать о том, чтобы обернуть каждый вызов close () в отдельный блок try / catch, например:
finally {
try {
cStmt.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
try {
rs.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
try {
con.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
}
Мальчик, если это не выглядит ужасно.Есть ли лучший способ сделать это?