Дебаты о попытке использования ресурсов Java

Хорошо, теперь на моей работе у нас дебаты о попытках использования ресурсов и подавлении исключений.

Краткий обзор: try-with-resources из java 7 устраняет необходимость в этом надоедливом блоке finally для закрытия ресурсов. Я лично считаю, что это более элегантно, но у меня есть коллега, который не убежден. Ему не нравится, что одно исключение подавляется, и он утверждает, что из-за этого мы теряем информацию.

Сначала я поверил ему на слово, потому что я младший разработчик, а он старший, я новичок и т. д. Но недавно я обнаружил, что вся информация попадает в трассировку стека, включая подавленное исключение. Так что никакая информация там не теряется.

Последняя часть этой дискуссии, которую я ищу (поскольку я выступаю за попытку с ресурсами), - это то, как auto-closeable обрабатывает это исключение. Допустим, при попытке закрыть ресурс возникает исключение, есть ли вероятность того, что ресурс может остаться открытым и протечь? В конечном счете, это может быть не такой уж большой проблемой, поскольку журналы все равно предупредят нас об этой проблеме.

Просто любопытно. Большое спасибо.


person user2223059    schedule 26.04.2016    source источник
comment
Так в чем твоя проблема? Как убедить коллегу?   -  person Sleiman Jneidi    schedule 26.04.2016
comment
Допустим, при попытке закрыть ресурс возникает исключение, есть ли вероятность того, что ресурс может остаться открытым и протечь? Он останется открытым точно в той же степени, в какой код try/finally до Java-7 позволял ему оставаться открытым. Я предполагаю, что у вас нет чего-то, например, чтобы попытаться закрыть несколько раз?   -  person Jon Skeet    schedule 26.04.2016
comment
Исключения, которые подавляются, вообще не теряются. См. слайд 8 этой презентации.   -  person fge    schedule 26.04.2016


Ответы (1)


Вы правы в том, что подавление исключения не приводит к потере информации. Беспокойство вашего коллеги по этому поводу беспочвенно. Точки попытки с ресурсами:

  • чтобы убедиться, что ресурсы закрываются независимо от того, что выбрасывается при их использовании, и в обратном порядке, в котором они объявлены,

  • чтобы убедиться, что исключения, созданные при закрытии, не приводят к потере исключений, созданных в блоке try, и

  • чтобы убедиться, что исключения, созданные при закрытии, по-прежнему сохраняются как подавленные исключения, поэтому никакая информация не будет потеряна.

Если закрытие ресурса вызывает исключение, вы ничего не можете с этим поделать в любом случае. В JDBC объекты базы данных связываются с сервером базы данных, чтобы указать ему отменить выделение ресурсов, и они останутся открытыми, если закрыть не удастся. (И в любом случае повторная попытка обычно бессмысленна, потому что проблема обычно заключается в том, что что-то изменилось в сети или соединении.) Но сервер в конечном итоге очистит их, и это не зависит от клиентского кода. И идиома try-with-resources, и более старая идиома try-finally одинаково хорошо справляются с закрытием ресурсов, просто с идиомой try-finally требуется больше работы и больше ввода.

Самая большая разница для меня в том, использовать ли операторы try-with-resources или вложенные операторы try-finally, заключается в том, что в первом случае, если в блоке try ничего не выбрасывается и что-то выбрасывается при закрытии, выдается исключение, выброшенное при закрытии ( поскольку в блоке try нет исключений, к которым можно было бы присоединить его как подавленное исключение). Если вы используете вложенные блоки try-finally, вы можете убедиться, что исключения, возникающие при закрытии, не распространяются из блока finally, чтобы периодический сбой сети при освобождении ресурсов не приводил к потере действительной бизнес-транзакции.

Но на практике очень немногие люди терпимы к такому типу вложенности, и они используют ярлыки, которые приводят к утечке ресурсов (обычно соединения, которые не закрываются, потому что более ранний вызов в блоке finally не удался). Люди также склонны писать код, который вызывает маскирование исключений (упомянутое во втором пункте списка), где исключение, вызванное при закрытии, приводит к потере исключения, созданного в блоке try; try-with-resources предотвращает подобные ошибки. Определенно есть место для попытки использования ресурсов.

Мой совет — узнать как можно больше об обработке исключений, написать примеры программ, демонстрирующих, как работают исключения, и понять сильные и слабые стороны обоих подходов, чтобы вы могли подробно говорить о них, сравнивать и сопоставлять. Таким образом, вы можете показать, что понимаете проблемы, которые поднимают ваши коллеги, и можете давать советы не в качестве защитника того или иного способа, а с целью помочь вашей группе найти решения, которые помогут ей писать более качественное программное обеспечение.

person Nathan Hughes    schedule 26.04.2016