← Назад к вопросам

Что такое finalize() в Java?

1.2 Junior🔥 181 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое finalize() в Java?

metodo finalize() — это метод, определённый в базовом классе Object, который вызывается сборщиком мусора (garbage collector) непосредственно перед удалением объекта из памяти. Это метод для очистки ресурсов, которые не могут быть автоматически освобождены сборщиком мусора.

Определение и синтаксис

protected void finalize() throws Throwable {
    // Код для очистки ресурсов
}

Метод имеет защищённый доступ (protected) и может выбросить любое исключение типа Throwable.

Когда вызывается finalize()

Сборщик мусора вызывает finalize() в следующих ситуациях:

  1. Перед сборкой мусора — когда объект помечен как подлежащий удалению (нет ссылок на него)
  2. Непредсказуемо — время вызова финализатора не гарантировано
  3. Один раз — для каждого объекта finalize() вызывается максимум один раз

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

public class FileHandler {
    private FileOutputStream fileStream;
    
    public FileHandler(String filename) throws IOException {
        fileStream = new FileOutputStream(filename);
    }
    
    public void writeData(byte[] data) throws IOException {
        fileStream.write(data);
    }
    
    @Override
    protected void finalize() throws Throwable {
        try {
            if (fileStream != null) {
                fileStream.close();
            }
        } finally {
            super.finalize();
        }
    }
}

Проблемы и недостатки finalize()

1. Непредсказуемость

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

2. Производительность

  • Объекты с переопределённым finalize() обрабатываются сборщиком мусора медленнее
  • Это создаёт специальную очередь финализируемых объектов

3. Потокобезопасность

  • finalize() может вызваться из любого потока
  • Требуется тщательная синхронизация

4. Исключения в finalize()

  • Если в finalize() выброшено исключение, оно игнорируется
  • Ресурс остаётся незакрытым без оповещения

Правильный подход: try-with-resources

public class BetterFileHandler implements AutoCloseable {
    private FileOutputStream fileStream;
    
    public BetterFileHandler(String filename) throws IOException {
        fileStream = new FileOutputStream(filename);
    }
    
    public void writeData(byte[] data) throws IOException {
        fileStream.write(data);
    }
    
    @Override
    public void close() throws IOException {
        if (fileStream != null) {
            fileStream.close();
        }
    }
}

// Использование
try (BetterFileHandler handler = new BetterFileHandler("data.txt")) {
    handler.writeData("Hello".getBytes());
} // close() вызовется автоматически

Заключение

finalize() считается устаревшей практикой в современной Java. Вместо него рекомендуется:

  • Использовать try-with-resources для ресурсов, реализующих AutoCloseable
  • Вызывать close() явно
  • Применять WeakReference с ReferenceQueue для отслеживания удаления объектов

Ответ deprecated в Java 9+ и полностью удалён в более новых версиях. Понимание finalize() важно для работы с legacy-кодом и для осознания истории развития Java.