Что такое ресурс в конструкции try with resources

Инструкция try-with-resources в Java

Вступление

Синтаксис

То, как Java понимает этот код:

До внедрения этого подхода закрытие ресурсов выполнялось вручную, как показано в предыдущем коде. По сути, это был стандартный код, и базы кода были завалены ими, что снижало читаемость и затрудняло их обслуживание.

catch и наконец часть попробуйте с ресурсами работают, как ожидалось, с catch блоками, обрабатывающими соответствующие исключения, и наконец блок выполняется независимо от того, было ли исключение или нет. Единственное отличие-это подавленные исключения, которые объясняются в конце этой статьи.

Множество Ресурсов

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

Если бы мы хотели работать с несколькими файлами, мы бы открыли файлы в инструкции try() и разделили их точкой с запятой:

Поддерживаемые Классы

Это, конечно, включает в себя определенные пользователем объекты, реализующие Автоклавируемый интерфейс. Однако вы редко столкнетесь с ситуацией, когда захотите написать свои собственные ресурсы.

Обработка исключений

Представьте себе ситуацию:

Важно понимать, что порядок исполнения:

Например, вот ресурс, который ничего не делает, кроме как создает исключения:

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

Подсказка : Внезапно исключения, возникающие при закрытии ресурсов, становятся важными.

Помните, что внутри блока try может быть создано только одно исключение. Как только возникает исключение, код блока try завершается, и Java пытается закрыть ресурсы.

Вывод

Код более читабелен, его легче изменять и поддерживать, и обычно он короче.

Источник

Оператор try with resources

— Смирно, ученик Амиго!

— Рад изучать Java, капитан!

— Вольно, Амиго. Сегодня у нас супер-интересная тема. Мы поговорим о взаимодействии Java-программы с внешними ресурсами и изучим один очень интересный оператор. Ушами лучше не хлопать.

— Иногда в процессе работы Java-программа взаимодействует с объектами вне Java-машины. Например, с файлами на диске. Такие объекты принято называть внешними ресурсами.

— А что тогда считается внутренними ресурсами?

— Внутренние ресурсы — это объекты, созданные внутри Java-машины. Обычно взаимодействие происходит по такой схеме:

Что такое ресурс в конструкции try with resources. Смотреть фото Что такое ресурс в конструкции try with resources. Смотреть картинку Что такое ресурс в конструкции try with resources. Картинка про Что такое ресурс в конструкции try with resources. Фото Что такое ресурс в конструкции try with resources

— У операционной системы есть функции (API), которые позволяют программе захватить какой-либо ресурс и/или освободить его. Если ресурс занят, с ним может работать только та программа, которая его захватила. Если ресурс свободен, любая программа может захватить его.

— Представь, что в офисе есть общие кружки. Если кто-то взял кружку, другой уже не может взять её же. Но если ею воспользовались, помыли и поставили на место, её снова может брать кто угодно.

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

— Но после того, как ты закончил работать с файлом, этот ресурс (файл) нужно освободить: уведомить операционную систему, что он тебе больше не нужен. Если ты этого не сделаешь, ресурс будет продолжать числиться за твоей программой.

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

— Это как программы, которые могут съесть всю память…

— Как-то так. Хорошая новость в том, что если твоя программа завершилась, все ресурсы автоматически освобождаются (это делает сама операционная система).

— Раз есть хорошая новость, то и плохая поджидает?

— Так точно. Плохая новость состоит в том, что если ты пишешь серверное приложение…

— А я пишу такие приложения?

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

— То есть программа не завершается, соответственно, память, не освобождается автоматически.

— Именно. И если ты в день открываешь 100 файлов и не закрываешь их, то через пару недель твоё приложение исчерпает свой лимит и упадет.

— Не очень-то похоже на месяцы стабильной работы! Что же делать?

— Вот тебе пример программы, которая что-то пишет в файл и закрывает его за собой – освобождает ресурсы операционной системы. Выглядит это примерно так:

КодПримечание
Путь к файлу.
Получаем объект файла: захватываем ресурс.
Пишем в файл
Закрываем файл — освобождаем ресурс

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

— А это очень плохо. Что же делать?

— Хм… Здесь что-то не так?

— Ну а теперь-то всё работает?

— Ффух… Хорошо, что это всё закончилось. Относительно понятно, но как-то громоздко что ли?

— Так и есть. Поэтому создатели Java нам подсобили и подсыпали немного синтаксического сахарку. Переходим к гвоздю программы, а точнее — этой лекции:

— В общем случае выглядит он довольно просто:

— Ниже написано два эквивалентных примера:

Длинный кодКод с try-with-resources

Источник

Одним из основных нововведений, которые были включены в Java 7, стало введение нового оператора «try c ресурсами». «try c ресурсами» это оператор try, в котором объявляются один или несколько ресурсов. Ресурс — это объект, который должен быть закрыт после того, как программа закончит с ним работу. «try c ресурсами» берет всю работу по закрытию ресурсов на себя. Прежде, чем подробно его рассмотреть давайте разберемся в причинах, которые вызвали его появление.

Закрытие ресурсов до Java 7.

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

Слишком много кода для столь простой операции, не находите? Но и это еще не все, в коде выше есть существенный изъян, если при закрытии первого ресурса:

будет сгенерировано исключение, то второй ресурс закрыт не будет:

Самым очевидным выходом из данной ситуации – будет окружить закрытие ресурсов дополнительными блоками try:

Согласитесь, что выглядит ужасно, но до выхода Java 7 с этим приходилось мириться.

Использование try с ресурсами.

Появление оператора try с ресурсами значительно упростило жизнь программистам, больше не было необходимости громоздить конструкции try/catch в надежде, что ты закрыл все ресурсы и предусмотрел все возможные исключительные ситуации, большую часть этой работы try с ресурсами взял на себя. Рассмотрим его общий вид:

Главное отличие от привычного блока try в круглых скобках, в которых создаются ресурсы, которые впоследствии нужно закрыть, ресурсы будут закрываться снизу-вверх автоматически после завершения работы блока try, т.е. в примере, сначала закроется writer, а потом reader. Ресурсы созданные в блоке try(), в нашем случае reader и writer будут видны только в блоке try, в блоках catch и finally попытка их использования вызовет ошибку компиляции.

При использовании оператора try с ресурсами, совершенно не обязательно использовать блоки catch и finally, они являются опциональными, исходя из этого предыдущий пример можно переписать следующим образом:

Подобный код абсолютно легален и никаких ошибок компиляции не вызовет.

Настало время улучшить наш пример из начала статьи, который копирует первую строчку из одного файла в другой:

Получилось в два раза меньше кода, чем в первоначальном примере.

Интерфейс AutoCloseable.

Для того, чтобы класс можно было использовать в операторе try с ресурсами, он должен реализовывать интерфейс AutoCloseable. Хорошая новость, в том, что сделать это не так уж и сложно – необходимо реализовать всего лишь один метод – public void close() throws Exception.

Как и следовало ожидать сначала выполнился код из блока try, а потом произошло закрытие ресурса, с помощью переопределенного метода close(). Вы наверное заметили, что в примере, метод close() не генерирует и не объявляет никаких исключений, в отличии от метода объявленного в интерфейсе AutoCloseable – это вполне легально, переопределяемый метод может генерировать более конкретные исключения или не генерировать их вовсе. Еще на что хотелось бы обратить пристальное внимание, так это на саму реализацию метода close(). Метод close() не должен содержать никакой бизнес логики, только закрытие ресурсов:

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

Подавленные исключения.

Подавленные исключения (suppressed exception) образуются, когда в блоке try генерируется исключение и в методе close() при закрытии ресурса генерируется исключение, в этом случае первое исключение считается главным остальные подавленные, чтобы было понятнее рассмотрим пример:

Вывод:
Main exception
Suppressed Exception
Suppressed Exception

В нашем случае получился следующий ход выполнения программы: сначала создаются два объекта Example ex1 и ex2, после чего происходит вход в блок try, где генерируется исключение, программа прекращает выполнения кода в блоке и приступает к закрытию ресурсов снизу-вверх. При закрытии каждого из ресурсов в методе close() генерируется еще по одному исключению, которые последовательно добавляются к главному исключению, сгенерированному в блоке try. После того, как ресурсы были закрыты, программа приступает к обработке исключения в блоке catch, где первой строчкой мы выводим информацию о главном исключении, а последующим циклом получаем подавленные исключения и выводим информацию о них.

Последнее на что стоит обратить внимание, так это, что подавленные исключения работают только в блоке try, в следующем примере будет сгенерировано два самостоятельных и независимых друг от друга исключения:

Источник

Оператор try with resources

1. Внешние ресурсы

Иногда в процессе работы Java-программа взаимодействует с объектами вне Java-машины. Например, с файлами на диске. Такие объекты принято называть внешними ресурсами. Внутренние ресурсы — это объекты, созданные внутри Java-машины.

Обычно взаимодействие происходит по такой схеме:

Что такое ресурс в конструкции try with resources. Смотреть фото Что такое ресурс в конструкции try with resources. Смотреть картинку Что такое ресурс в конструкции try with resources. Картинка про Что такое ресурс в конструкции try with resources. Фото Что такое ресурс в конструкции try with resources

Учет ресурсов

Операционная система ведет строгий учет доступных ресурсов, а также контролирует совместный доступ разных программ к ним. Например, если одна программа меняет какой-то файл, другая программа не может изменить (или удалить) этот файл. Это касается не только файлов, но на их примере понятнее всего.

У операционной системы есть функции (API), которые позволяют программе захватить какой-либо ресурс и/или освободить его. Если ресурс занят, с ним может работать только та программа, которая его захватила. Если ресурс свободен, любая программа может захватить его.

Представьте, что у вас в офисе есть общие кружки. Если кто-то взял кружку, другой уже не может взять ее. Но если ей попользовались, помыли и поставили на место, ее снова может брать кто угодно. Ну или места в метро или в маршрутке. Если место свободно — любой может его занять. Если место занято — им распоряжается тот, кто занял.

Захват внешних ресурсов

Каждый раз, когда ваша Java-программа начинает работать с каким-то файлом на диске, Java-машина запрашивает у операционной системы монопольный доступ к нему. Если ресурс свободен, его захватывает Java-машина.

Но после того, как вы закончили работать с файлом, этот ресурс (файл) нужно освободить: уведомить операционную систему, что он вам больше не нужен. Если вы этого не сделаете, ресурс будет продолжать числиться за вашей программой.

Для каждой запущенной программы операционная система ведет список занятых ресурсов. Если ваша программа превысит разрешенный ей лимит ресурсов, новые ресурсы операционная система вам уже не даст.

Хорошая новость в том, что если ваша программа завершилась, все ресурсы автоматически освобождаются (это делает сама операционная система).

Плохая же новость в том, что если вы пишете серверное приложение (а очень много серверных приложений пишутся на Java), ваш сервер должен работать днями, неделями, месяцами без остановки. И если вы в день открываете 100 файлов и не закрываете их, через пару недель ваше приложение исчерпает свой лимит и упадет. Не очень-то похоже на месяцы стабильной работы.

2. Метод close()

Ниже приведем пример программы, которая что-то пишет в файл и закрывает его за собой – освобождает ресурсы операционной системы. Выглядит это примерно так:

КодПримечание
Путь к файлу.
Получаем объект файла: захватываем ресурс.
Пишем в файл
Закрываем файл — освобождаем ресурс

Исключения

Вроде все просто. Однако в процессе работы программы могут возникнуть исключения, и внешний ресурс так и не будет освобожден. А это очень плохо.

Ниже написано два эквивалентных примера:

Длинный кодКод с try-with-resources

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *