Что такое final и finally, и чем они отличаются?
В Java final и finally — это два совершенно разных элемента языка, несмотря на схожесть названия. Они относятся к разным частям языка: final — это ключевое слово, а finally — это блок управления потоком исполнения.
Разберём их по отдельности, затем сравним.
🔑 final — модификатор
final используется для объявления "неизменяемости". Он может применяться к:
-
переменным,
-
методам,
-
классам.
1. final переменная
-
Значение можно присвоить только один раз.
-
После этого изменить нельзя.
final int x = 10;
x = 20; // ошибка компиляции
- Для объектов:
- final MyClass obj = new MyClass(); — нельзя переназначить obj,
но можно менять содержимое объекта (если он не immutable).
- final MyClass obj = new MyClass(); — нельзя переназначить obj,
2. final метод
- Метод нельзя переопределить в подклассе.
class Parent {
final void sayHello() {
System.out.println("Hello");
}
}
class Child extends Parent {
void sayHello() {} // ошибка компиляции
}
3. final класс
- Класс нельзя наследовать.
final class Utils {
// ...
}
class MyUtils extends Utils {} // ошибка компиляции
⚙️ finally — блок в конструкции try-catch-finally
finally — это блок, который всегда выполняется, вне зависимости от того, произошло исключение или нет. Он используется для освобождения ресурсов (закрытие файлов, потоков, соединений).
Пример:
try {
int x = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Ошибка: деление на ноль");
} finally {
System.out.println("Этот блок выполнится всегда");
}
-
Даже если в try будет return или throw, блок finally всё равно выполнится.
-
Исключение: если процесс был завершён принудительно (System.exit(0)), finally не выполнится.
📌 Отличия final и finally
Критерий | final | finally |
---|---|---|
Что это | Ключевое слово (модификатор) | Блок кода (часть конструкции try) |
--- | --- | --- |
Где используется | Переменные, методы, классы | В конструкции try-catch-finally |
--- | --- | --- |
Назначение | Запрет изменений/наследования | Гарантированное выполнение кода |
--- | --- | --- |
Когда выполняется | Во время компиляции | Во время выполнения |
--- | --- | --- |
Может ли влиять на поток исполнения | Нет | Да, выполняется всегда при выходе из try |
--- | --- | --- |
🧠 Дополнительно
-
Не путай final с finally, и тем более с finalize() — последний был методом, вызываемым перед уничтожением объекта, но он устарел и удалён с Java 9+.
-
Хорошая практика — всегда использовать finally для освобождения ресурсов или вместо него использовать try-with-resources.
Таким образом:
-
final → ограничивает возможность изменения (переменных, методов, классов).
-
finally → гарантирует выполнение блока кода после try/catch.
Они выглядят похоже, но относятся к разным аспектам Java — синтаксису, семантике и этапу исполнения.