Try-With Resource, когда AutoCloseable имеет значение null

Как работает функция try-with для AutoCloseable переменных, объявленных null?

Я предположил, что это приведет к исключению нулевого указателя, когда он попытается вызвать close для переменной, но это не вызывает проблем:

try (BufferedReader br = null){
    System.out.println("Test");
}
catch (IOException e){
    e.printStackTrace();
}

person flakes    schedule 12.02.2016    source источник


Ответы (1)


Спецификация языка Java указывает, что он закрывается, только если он не равен нулю, в разделе 14.20.3. попытка с ресурсами:

Ресурс закрывается, только если он инициализирован ненулевым значением.

Это действительно может быть полезно, когда ресурс может иногда присутствовать, а другие отсутствуют.

Например, предположим, что у вас может быть или не быть закрываемый прокси-сервер для какой-либо удаленной системы ведения журнала.

try ( IRemoteLogger remoteLogger = getRemoteLoggerMaybe() ) {
    if ( null != remoteLogger ) {
       ...
    }
}

Если ссылка не нулевая, прокси-сервер удаленного регистратора закрывается, как мы и ожидали. Но если ссылка имеет значение null, для нее не предпринимается никаких попыток вызвать метод close(), исключение NullPointerException не генерируется, и код продолжает работать.

person Andy Thomas    schedule 12.02.2016
comment
Ха-ха, вариант использования, который вы только что добавили, в первую очередь заставил меня задать вопрос! Спасибо! - person flakes; 13.02.2016
comment
Ни за что! Это дико. Я только что выдумал. - person Andy Thomas; 13.02.2016
comment
Что ж,. разные типы переменных, но одинаковая структура: p - person flakes; 13.02.2016
comment
Все равно круто! Приятно видеть, что дизайнеры языка подумали об этом случае. - person Andy Thomas; 13.02.2016
comment
Обычно я выбрасываю пойманное исключение, если возникает проблема, при которой в противном случае я бы вернул null. Иметь блок catch для каждой попытки с ресурсами — это немного, но проверка на null — это примерно то же самое. На самом деле проверка на null немного медленнее (незначительно) в оптимальных условиях, поэтому я решил генерировать пойманные исключения. - person searchengine27; 19.06.2019
comment
@searchengine27. Насколько я понимаю, сгенерировать исключение может быть дороже, чем возврат null. Возвращаемое значение null может быть нормальным или исключительным случаем. Мой пример для первого. Исключения лучше всего использовать для последних. - person Andy Thomas; 19.06.2019
comment
Да, исключения дороже бросать. Но обычно в Java, в отличие от таких языков, как Python, исключения не используются для потока управления, а используются для решения проблем. Блоки Catch не влияют на производительность в номинальных случаях. Так что причина, по которой мне это нравится, заключается в том, что в номинальных случаях это дешевле. Опять же, мы говорим о незначительном выигрыше, потому что это дополнительная пара ассемблерных операторов под капотом для проверки нуля, но моя типичная позиция в отношении вычислений такова: «каждый бит имеет значение». - person searchengine27; 20.06.2019