0Pricing
Java Academy · Урок

Безопасное закрытие потоков

try-with-resources

«Безопасное закрытие потоков» — бесплатный урок Java Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Зачем закрывать потоки

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

Закрытие потока освобождает удерживаемые им ресурсы и записывает все ожидающие данные. В этом уроке показано, как делать это безопасно.

Метод close

У каждого средства чтения есть метод close(). Его вызов освобождает ресурс.

Если BufferedReader оборачивает System.in, закрытие также закрывает потоки, лежащие в его основе.

BufferedReader br =
    new BufferedReader(new InputStreamReader(System.in));
// ... use br ...
br.close();

Старый рискованный способ

Можно вызвать close() вручную, но если до выполнения этой строки произойдёт ошибка, close() будет пропущен и ресурс утечёт.

Размещение close() в блоке finally помогает, но делает код многословным, и в нём легко допустить ошибку.

BufferedReader br = null;
try {
    br = new BufferedReader(
        new InputStreamReader(System.in));
    // ... use br ...
} finally {
    if (br != null) br.close();
}

Автоматическое закрытие ресурсов

В Java есть более чистое решение: конструкция с ресурсами. Вы объявляете поток в скобках после try, и Java автоматически закрывает его после завершения блока — даже если происходит ошибка.

Не нужны ни finally, ни ручной вызов close(). Это современный рекомендуемый способ.

try (BufferedReader br =
        new BufferedReader(new InputStreamReader(System.in))) {
    String line = br.readLine();
    System.out.println(line);
}

Как это работает

Любой ресурс, объявленный в скобках try (...), должен реализовывать AutoCloseable. BufferedReader соответствует этому требованию, поэтому Java вызывает его close() за Вас.

Закрытие происходит после завершения блока независимо от того, завершился ли он обычным образом или из-за исключения.

Полный пример

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

Программа читает из System.in, поэтому ожидает ввода и не запускается здесь автоматически.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(System.in))) {
            String name = br.readLine();
            System.out.println("Hi " + name);
        }
    }
}

Запускаемый пример со StringReader

Чтобы убедиться, что конструкция с ресурсами работает без ввода с клавиатуры, здесь программа читает из StringReader. Её можно полностью запустить.

После блока средство чтения закрывается автоматически — Вам не нужно писать вызов close().

import java.io.BufferedReader;
import java.io.StringReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        try (BufferedReader br =
                new BufferedReader(new StringReader("done"))) {
            System.out.println(br.readLine());
        }
    }
}

Несколько ресурсов

Можно объявить несколько ресурсов в одном try, разделив их точками с запятой. Java закроет их все в обратном порядке объявления.

Это удобно, когда Вы объединяете несколько потоков.

try (InputStreamReader isr =
        new InputStreamReader(System.in);
     BufferedReader br = new BufferedReader(isr)) {
    System.out.println(br.readLine());
}

Обработка IOException

Чтение может вызвать IOException. Можно добавить catch к блоку с ресурсами, чтобы обработать исключение вместо объявления throws.

Ресурс всё равно автоматически закрывается до выполнения catch.

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in))) {
    System.out.println(br.readLine());
} catch (IOException e) {
    System.out.println("Read failed");
}

Нужно ли закрывать System.in?

Есть один нюанс: закрытие средства чтения для System.in также закрывает сам System.in, и повторно открыть его нельзя.

Для коротких программ это нормально. Но если позднее Вам ещё понадобится ввод с консоли, не закрывайте это конкретное средство чтения. Учитывайте, какой поток оно оборачивает.

Рекомендации

Чтобы безопасно работать с потоками:

  • Предпочитайте конструкцию с ресурсами ручному вызову close().
  • Она автоматически закрывает ресурсы даже при возникновении ошибок.
  • Помните: закрытие средства чтения System.in закрывает стандартный ввод.

Корректная работа с ресурсами предотвращает утечки и ошибки.

Быстрая проверка

Подумайте о главном преимуществе автоматического закрытия ресурсов.

Повторение

Вы узнали, почему потоки необходимо закрывать, чем опасен ручной подход с finally и как работает чистая конструкция автоматического закрытия ресурсов, которая закрывает ресурсы AutoCloseable.

Теперь Вы можете безопасно читать ввод с помощью BufferedReader от начала до конца.

Часто задаваемые вопросы

Урок «Безопасное закрытие потоков» бесплатный?

Да — полный текст урока «Безопасное закрытие потоков» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Безопасное закрытие потоков»?

try-with-resources Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Безопасное закрытие потоков»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужен BufferedReader
  2. Чтение строк
  3. Разбор чисел из ввода
  4. Безопасное закрытие потоков
← Назад к Java Academy