Skip to content

Finally

Лекция: Блок finally в Java

Тема: Блок finally в Java и его использование для обработки исключений и освобождения ресурсов.

Цель: Понять назначение и механизм работы блока finally, научиться применять его в программах для обеспечения корректного завершения работы и предотвращения утечек ресурсов.

  1. Введение

Блок finally в Java – это блок кода, который гарантированно выполняется после блока try, независимо от того, произошло исключение или нет. Он предназначен для выполнения действий, которые необходимо произвести в любом случае, например, закрытие файлов, освобождение сетевых соединений или очистка других ресурсов.

  1. Синтаксис
try {
    // Блок кода, который может вызвать исключение
} catch (ExceptionType1 e1) {
    // Обработка исключения типа ExceptionType1
} catch (ExceptionType2 e2) {
    // Обработка исключения типа ExceptionType2
} finally {
    // Блок кода, который выполняется всегда
}
  1. Гарантированное выполнение

Блок finally выполняется всегда:

Если исключение не произошло: После успешного выполнения блока try. Если исключение произошло: После обработки исключения в блоке catch (или после того, как исключение не было обработано и передано дальше по стеку вызовов). Даже если произошел System.exit(): finally выполнится до завершения программы, вызванного System.exit(). Однако, если виртуальная машина аварийно завершается (например, из-за ошибки в самой JVM), finally может не выполниться.

  1. Примеры использования

Закрытие файлов:

try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    // Чтение из файла
} finally {
    // Закрытие файла - гарантированно, даже если возникло исключение
    //reader.close(); //В данном случае close() вызовется автоматически благодаря try-with-resources
}

Освобождение сетевых ресурсов:

Socket socket = null;
try {
    socket = new Socket("example.com", 80);
    // Работа с сокетом
} catch (IOException e) {
    // Обработка исключения
} finally {
    if (socket != null) {
        try {
            socket.close();
        } catch (IOException e) {
            // Обработка исключения при закрытии сокета
        }
    }
}

Очистка других ресурсов:

Connection connection = null;
try {
    connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
    // Работа с базой данных
} catch (SQLException e) {
    // Обработка исключения
} finally {
    if (connection != null) {
        try {
            connection.close();
        } catch (SQLException e) {
            //Обработка исключения при закрытии соединения
        }
    }
}

  1. finally и return

Значение, возвращаемое из блока try или catch, не влияет на выполнение блока finally. finally выполнится перед возвратом значения из метода.

  1. Исключения в блоке finally

Если в блоке finally возникает исключение, оно может замаскировать исключение, произошедшее в блоке try или catch. Поэтому код в блоке finally должен быть максимально простым и надежным.

  1. try-with-resources

Java 7 ввела конструкцию try-with-resources, которая упрощает работу с ресурсами, автоматически закрывая их в блоке finally. Это избавляет от необходимости писать дополнительный код для закрытия ресурсов. (Пример показан выше в разделе "Закрытие файлов")

Задания для самостоятельной работы:

Напишите программу, которая читает данные из файла, обрабатывает их и записывает результат в другой файл. Используйте блок finally для закрытия файлов. Напишите программу, которая устанавливает соединение с базой данных, выполняет запрос и закрывает соединение. Используйте try-with-resources или блок finally для освобождения ресурсов.

Исследуйте поведение блока finally при разных сценариях, включая возникновение исключений в блоках try и finally.

Сценарий: return внутри try или catch

public int myMethod() {
    try {
        // ... some code ...
        return 10;
    } catch (Exception e) {
        return -1;
    } finally {
        System.out.println("Выполняется finally");
    }
}

Даже если внутри try или catch встречается return, finally блок выполнится перед возвратом значения из метода. Это важно для освобождения ресурсов (например, закрытия файлов, соединения с базой данных).

В чём преимущество перед кодом после try-catch?

Код после try-catch не гарантирует выполнения, если произойдет System.exit() или RuntimeException, который не перехвачен. finally же обеспечивает гарантированное выполнение, что критически важно для освобождения ресурсов и обеспечения чистоты работы программы. Это делает код более надежным и предсказуемым.

В итоге, блок finally не просто дублирует код, а предоставляет механизм для гарантированного выполнения определённых операций, независимо от того, как завершился блок try. Это делает его незаменимым инструментом для управления ресурсами и обработки ошибок в Java.