TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #269 5.07K
Ресурсы, идиома RAII и Java 9

Разработка - сложная штука c множеством идей и концептов. В этом посте я расскажу об идиоме RAII, разнице при работе с ресурсами в java и C++, блоке try-with-resources и изменениях java 9.

Начнём с основ. Ресурс - это сущность, для которой нужен эксклюзивный доступ. Их количество ограничено. Большинство ресурсов находятся за пределами JVM: файлы, соединения с БД, сокеты и т.д

Для корректной работы только один поток должен работать с ресурсом. Для этого нужно принять дополнительные меры. Обозначим их как "открыть" и "закрыть" ресурс:
🔸Открыть = получить эксклюзивный доступ.
🔸Закрыть = закончить работу. Теперь другой поток может работать с ресурсом.

Такой вот нехитрый жизненный цикл(ЖЦ).

RAII
или Resource Acquisition Is Initialization - одна из техник по работе с ресурсами. Другое название: SBRM - Scope-Bound Resource Management.

Суть: ассоциируем ресурс с объектом. Тогда ЖЦ ресурса совпадает с ЖЦ объекта. В идеале это выглядит так:

public void do() {
File f=new File("t.txt");
// Создаём объект File, ресурс "t.txt" теперь наш
// что-то делаем
}
// вышли из метода: объект f уже не нужен, ресурс "t.txt" освобождается

RAII легко реализовать в С++. В конструкторе пишем логику "открытия" ресурса, а в деструкторе - "закрытия". Конструктор и деструктор явно прописываются, поэтому ЖЦ объекта и ресурса под контролем.

В java так не получится. Деструктор выполнится неизвестно когда, а ресурс - штука ценная. Поэтому в java нужно явно вызвать метод закрытия. В стандартных библиотеках это close().

В java 7 появилась специальная конструкция для ресурсов:
try (PrintWriter writer = new PrintWriter(…)) {
// что-то делаем
}

Ресурс реализует интерфейс AutoCloseable, и после завершения блока для него вызовется close(). try-with-resources считается java реализацией RAII.

Но такой формат не идеален. Внутри try всегда определяется новый объект. Когда ресурсов два и больше, код становится громоздким:

try (DatagramChannel udpServer = …;
Selector selector = …) {
// …
}

В java 9 в блок try можно передать переменные:

DatagramChannel udpServer = …;
Selector selector = …;

try (udpServer;selector) {
// …
}

С одной стороны это удобно. Код выглядит приятно.

С другой - после try остаются переменные с закрытыми ресурсами. Теперь нельзя сказать, что java реализует RAII.

Ну и ладно, никто не расстроился🙂 Языки разные, и классно замечать, как по-разному в них реализуются идеи, и как они меняются с течением времени.
  • 👍 4
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →