Как работает конструкция try-catch-finally в Java
Что проверяют
Знаете ли вы порядок выполнения и подводные камни с return и подавленными исключениями.
Как отвечать
try содержит код, который может бросить исключение. catch перехватывает: блоков может быть несколько, проверяются сверху вниз, срабатывает первый подходящий, поэтому конкретные типы идут раньше общих (иначе не скомпилируется). finally выполняется всегда: и при успехе, и при исключении, и при return внутри try.
Тонкости, которые проверяют:
returnвfinallyперекрывает всё: он подавит и возвращаемое значение изtry, и летящее исключение. Так писать нельзя, и статические анализаторы на это ругаются;finallyвыполняется после вычисления возвращаемого значения: изменение примитивной переменной там на результат уже не влияет;- мультикэтч:
catch (IOException | SQLException e)для одинаковой обработки, переменная там неявноfinal; - try-with-resources: ресурсы, объявленные в скобках, закрываются автоматически в обратном порядке, и это заменяет
finallyдля закрытия. Важная деталь: если исключение бросили и тело, иclose, то второе становится подавленным и доступно черезgetSuppressed, а не теряется.
try (var conn = ds.getConnection(); var st = conn.createStatement()) { ... }Практика: finally для освобождения того, что не является AutoCloseable, всё остальное через try-with-resources. Пустой catch недопустим: минимум логирование, иначе ошибка исчезает бесследно.
Где спотыкаются
Пишут return в finally.
Ловят Exception вместо конкретного типа и прячут настоящие ошибки.
Закрывают ресурсы вручную в finally, забывая про исключение внутри самого close.
Глушат исключение пустым блоком.