Что такое try-with-resources в Java и как это работает?

Ответ

Try-with-resources — это конструкция языка Java (появилась в Java 7), предназначенная для автоматического управления ресурсами, которые необходимо закрывать после использования. Ресурсом считается любой объект, реализующий интерфейс java.lang.AutoCloseable (или его предшественник java.io.Closeable).

Как работает: Ресурсы, объявленные в скобках после try, автоматически закрываются при выходе из блока try (нормальном или исключительном). Компилятор гарантирует вызов метода .close() для каждого ресурса в порядке, обратном порядку их объявления.

Пример использования:

try (FileInputStream fis = new FileInputStream("file.txt");
     BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}
// Здесь fis и br будут закрыты автоматически, даже если возникнет исключение.

Ключевые преимущества и особенности:

  1. Автоматическое закрытие: Избавляет от необходимости писать блок finally для ручного закрытия, уменьшая шаблонный код и риск утечек ресурсов.
  2. Подавление исключений: Если в блоке try и при закрытии ресурса (close()) возникли исключения, исключение из блока try добавляется в подавленные (suppressed) исключения основного исключения, что позволяет не терять информацию об ошибках.
  3. Объявление ресурсов: Ресурсы можно объявлять непосредственно в скобках try (как в примере) или использовать уже существующие final/effectively final переменные (с Java 9).
  4. Совместимость: Блоки catch и finally остаются опциональными и работают как обычно.

Ответ 18+ 🔞

Да ты посмотри, какая красота придумана, блядь! Try-with-resources, ёпта! Это ж как глоток свежего воздуха после того, как всю жизнь вручную ресурсы закрывал, как последний мудак.

Раньше-то, сука, писал как? Открыл файлик — и сиди, блядь, молись, чтобы в блоке try всё гладко прошло, а потом в finally эту свою хрень закрывай. А если ещё два ресурса? А если исключение при закрытии первого, а второе уже и не закроется? Короче, пиздец и разводка, волнение ебать.

А тут, блядь, придумали штуку, которая сама всё за тебя сделает. Объявляешь ресурсы в скобках после try — и спи спокойно. Выйдешь из блока — они автоматом закроются. Даже если посреди чтения файла тебе кирпич на голову упадёт и IOException выскочит — всё равно закроются, ёбана в рот! Магия, блядь.

Смотри, как элегантно теперь выглядит код:

try (FileInputStream fis = new FileInputStream("file.txt");
     BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}
// Здесь fis и br будут закрыты автоматически, даже если возникнет исключение.

Красота-то какая! Никаких лишних телодвижений. Главное, блядь, чтобы твой ресурс реализовывал интерфейс AutoCloseable. Ну, или его старшего брата Closeable. А то возьмёшь какую-нибудь свою самописную хрень, а она, сука, не закрывается — и опять ты в пролёте.

И ещё фишка, охуенная: если и в основном блоке исключение, и при закрытии — информация не теряется! Исключение из close() прицепляется к основному как «подавленное». Не то что раньше — одно затирало другое, и потом гадай, что на самом деле сломалось.

Короче, вещь, блядь, обязательная к применению. С тех пор как в Java 7 появилась — жить стало проще. Только дурак или консервативный мудак будет до сих пор вручную в finally всё закрывать. Хуй с горы, в общем. Используй и не парься.