В чём разница между final vs. finally vs. finalize

Модификатор final:

  • Класс не может иметь наследников;
  • Метод не может быть переопределен в классах наследниках;
  • Поле не может изменить свое значение после инициализации;
  • Локальные переменные не могут быть изменены после присвоения им значения;
  • Параметры методов не могут изменять своё значение внутри метода.

Оператор finally гарантирует, что определенный в нём участок кода будет выполнен независимо от того, какие исключения были возбуждены и перехвачены в блоке try-catch.

Метод finalize() вызывается перед тем как сборщик мусора будет проводить удаление объекта.

Пример:


public class MainClass {

	public static void main(String args[]) {
		TestClass a = new TestClass();
		System.out.println("result of a.a() is " + a.a());
		a = null;
		System.gc(); // Принудительно зовём сборщик мусора
		a = new TestClass();
		System.out.println("result of a.a() is " + a.a());
		System.out.println("!!! done");
	}

}
public class TestClass {

	public int a() {
		try {
			System.out.println("!!! a() called");
			throw new Exception("");
		} catch (Exception e) {
			System.out.println("!!! Exception in a()");
			return 2;
		} finally {
			System.out.println("!!! finally in a() ");
		}
	}

	@Override
	protected void finalize() throws Throwable {
		System.out.println("!!! finalize() called");
		super.finalize();
	}
}

Результат выполнения:

!!! a() called
!!! Exception in a()
!!! finally in a() 
result of a.a() is 2
!!! a() called
!!! Exception in a()
!!! finally in a() 
!!! finalize() called
result of a.a() is 2
!!! done

 

Oct. 21, 2023, Источник

Ключевые слова `final`, `finally`, и `finalize` имеют совершенно разные цели и контексты использования, хотя на первый взгляд могут показаться похожими из-за схожести их названий.

final

Это модификатор, который может быть использован с переменными, методами и классами.

  • Когда он применяется к переменной, это означает, что переменная может быть присвоена только один раз и её значение не может быть изменено после присваивания.
  • Когда он используется с методом, это предотвращает переопределение метода в подклассах.
  • Когда он применяется к классу, это означает, что класс не может быть наследован.
final int x = 100; // переменная, которую нельзя изменить
public final void myMethod() {} // метод, который нельзя переопределить
public final class MyFinalClass {} // класс, от которого нельзя наследоваться

finally

Это блок кода, который используется вместе с блоками `try` и `catch` для обработки исключений. Блок `finally` выполняется всегда после выполнения блока `try`/`catch`, независимо от того, было ли выброшено исключение или нет. Это идеальное место для кода очистки, например, для закрытия файловых потоков или освобождения других ресурсов.

try {
    // код, который может вызвать исключение
} catch (Exception e) {
    // обработка исключения
} finally {
    // код, который выполняется всегда
}

finalize

Это метод класса `Object`, который вызывается сборщиком мусора перед тем, как объект будет уничтожен. Этот метод можно переопределить в классе для реализации очистки ресурсов или других операций перед уничтожением объекта. Однако его использование не рекомендуется из-за его непредсказуемости и малой эффективности, а также потому, что он может вызвать задержку в сборке мусора.

@Override
protected void finalize() throws Throwable {
    try {
        // очистка ресурсов
    } finally {
        super.finalize();
    }
}
  • `final` используется для создания констант, предотвращения наследования классов и переопределения методов.
  • `finally` гарантирует выполнение кода после блока `try`/`catch`, обычно для очистки ресурсов.
  • `finalize` предназначен для очистки перед уничтожением объекта, но его использование не рекомендуется.

Каждое из этих ключевых слов имеет уникальное применение и важно в контексте разработки.

Feb. 27, 2024, easyoffer