Что произойдёт при завершении try-with-resources, если выражение ресурса вернуло null?
Если выражение ресурса в try-with-resources вернуло null, блок try продолжит выполнение, а неявный вызов close() для этого ресурса пропустится. Исключение из-за попытки закрыть null не возникнет.
Конструкция try-with-resources появилась в Java 7, чтобы автоматически освобождать ресурсы при нормальном завершении блока и при исключениях. Она заменила повторяющийся шаблон с ручным вызовом close() в finally, где легко было забыть проверку на null или скрыть исходную ошибку исключением при закрытии.
Ресурс может быть необязательным: например, фабрика возвращает null, если внешний источник недоступен или конфигурация отключает его. При ручном закрытии прямой вызов close() у такой ссылки привёл бы к NullPointerException.
Неверное предположение о поведении try-with-resources может привести либо к лишней проверке и усложнению кода, либо к ошибочной диагностике: отсутствие вызова close() при null — это нормальное поведение конструкции, а не подавленная ошибка.
Перед закрытием каждого ресурса Java проверяет, не равна ли ссылка null. Если ссылка ненулевая, вызывается её close(); если равна null, закрытие пропускается. Поэтому null считается отсутствием созданного ресурса, который нужно освобождать.
В этом примере будет выведено body, а исключение при завершении блока не возникнет. Переменная r всё равно доступна внутри try, но содержит null.
Это правило относится именно к автоматическому закрытию ресурса. Если внутри тела явно вызвать метод через ссылку r, возникнет NullPointerException. Если само выражение resource() выбросит исключение, присваивание ресурса не завершится успешно; это уже ошибка инициализации, а не случай null.
Для нескольких ресурсов каждый успешно инициализированный ненулевой ресурс закрывается в обратном порядке объявления. Ресурсы, чьи ссылки равны null, при этом просто пропускаются. Исключения от реального close() обрабатываются по обычным правилам try-with-resources, включая механизм подавленных исключений.
Сервис получает необязательный аудит-логгер: при отключённом аудите фабрика возвращает null, а при включённом — объект, реализующий AutoCloseable. Вариант с ручным finally требует отдельной проверки ссылки и аккуратного сохранения исходного исключения; без этого ошибка закрытия может замаскировать ошибку бизнес-операции.
Можно заранее заменить null на объект-заглушку, что упрощает последующий код, но добавляет лишний объект и требует корректной реализации его методов. Можно отказаться от try-with-resources и закрывать ресурс вручную, но это увеличивает вероятность ошибки. Выбранный вариант — try-with-resources с возможным null: он использует стандартную семантику Java, не создаёт лишних объектов и безопасно пропускает закрытие отсутствующего ресурса.
null успешное создание ресурса?Нет. null означает, что ссылка не указывает на объект, поэтому закрывать нечего. Try-with-resources не создаёт ресурс автоматически и не превращает null в специальный объект-заглушку.
close(), если метод возвращает null, но тип результата — AutoCloseable?Нет. Проверяется фактическое значение ссылки, а не её объявленный тип. Тип должен позволять компилятору использовать ресурс, но при значении null вызов close() пропускается.
Нет. Конструкция защищает только этап автоматического закрытия null-ресурса. Обращение к тому же ресурсу внутри тела блока, например вызов его метода, по-прежнему приводит к NullPointerException, если ссылка равна null.