В конструкции Try-With-Resources закроются ли остальные ресурсы, если при закрытии одного возникнет исключение?

Ответ

Да, все объявленные ресурсы будут закрыты.

Механизм Try-With-Resources гарантирует попытку закрытия каждого ресурса в порядке, обратном их инициализации.

Поведение при исключениях:

  1. Если исключение возникает в теле блока try, ресурсы закрываются, а это исключение становится основным.
  2. Если исключение возникает при закрытии ресурса, оно подавляется (added as a suppressed exception). Основным остаётся первое возникшее исключение.

Пример:

try (var in = new FileInputStream("source.txt");
     var out = new FileOutputStream("dest.txt")) {
    // ... операции чтения/записи
} catch (IOException e) {
    // e - основное исключение (например, из тела try)
    Throwable[] suppressed = e.getSuppressed(); // Массив подавленных исключений (например, от close())
}

Практический вывод: Используйте Try-With-Resources для автоматического и безопасного управления ресурсами, даже в случае ошибок.

Ответ 18+ 🔞

Да ты посмотри, какая хитрая жопа у этих ява-разработчиков придумана! Try-With-Resources, блядь. Ну типа, чтобы не быть полным распиздяем и не забывать закрывать файлы, сокеты и прочую хуйню, которая жрёт твои системные дескрипторы как не в себя.

Вот представь: ты открыл кучу всего — FileInputStream, FileOutputStream, ещё какую-нибудь Connection к базе. Раньше надо было в finally писать эту долбаную порнографию с проверками на null и try-catch внутри try-catch. А теперь? Просто объявляешь их в круглых скобочках после try, и они сами закроются. Автоматом, блядь! Как будто у тебя личный дворецкий для ресурсов.

И закрываются они, внимание, в обратном порядке. То есть, кто последний зашёл — тот первый вышел. Как в нормальной очереди в туалет на весёлой пьянке. Сначала закрылся out, потом in. Логично, ёпта.

А теперь про самое сокровенное — про исключения. Тут, блядь, целый детектив.

  1. Если пиздец случился прямо в теле try (например, файл source.txt оказался битым, и чтение пошло по пизде). Ресурсы всё равно закроются! А то исключение, которое всех обосрало, станет главным, основным. Его ты и ловишь в catch.

  2. А если пиздец случился при закрытии? Ну, допустим, в теле try всё прошло гладко, записалось, но когда закрывал out, система вдруг говорит: «А хуй тебе, диск переполнен, не могу буферы сбросить». Так вот, это исключение от close() не затрет основное. Его аккуратно пристегнут к главному исключению как «подавленное» (suppressed). Чтобы ты потом, если захочешь, мог его достать и посмотреть, что ещё за хуйня произошла.

Вот, смотри на код, тут всё наглядно:

try (var in = new FileInputStream("source.txt");
     var out = new FileOutputStream("dest.txt")) {
    // ... операции чтения/записи
    // Допустим, тут вылетает IOException — ОСНОВНОЙ ПИЗДЕЦ
} catch (IOException e) {
    // Ловим именно его, основной пиздец (e)
    // А если при закрытии out тоже был пиздец, он тихонько сидит тут:
    Throwable[] suppressed = e.getSuppressed(); // Массив подавленных исключений
}

Итог, блядь, простой как три копейки: не выёбывайся со своими ручными close() в finally. Используй Try-With-Resources, и пусть виртуальная машина сама разгребает этот бардак. Даже если всё полетит к чертям, ты будешь знать, откуда именно прилетело, и ничего не протечёт. Красота, ёперный театр!