Вопрос-ответ

When is the finalize() method called in Java?

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

Мне нужно знать, когда finalize() метод вызывается в JVM. Я создал тестовый класс, который записывает в файл, когда finalize() метод вызывается, переопределяя его. Он не выполняется. Кто-нибудь может сказать мне причину, по которой он не выполняется?

Переведено автоматически
Ответ 1

Метод finalize вызывается, когда объект готовится к сборке мусора. Это может произойти в любое время после того, как он получит право на сборку мусора.

Обратите внимание, что вполне возможно, что объект никогда не получает сборку мусора (и, следовательно, finalize никогда не вызывается). Это может произойти, когда объект никогда не становится пригодным для gc (потому что он доступен в течение всего срока службы JVM) или когда фактически не выполняется сборка мусора между моментом, когда объект становится пригодным, и моментом, когда JVM прекращает работу (это часто происходит с простыми тестовыми программами).

Существуют способы сообщить JVM о запуске finalize для объектов, для которых он еще не вызывался, но использовать их тоже не очень хорошая идея (гарантии этого метода также не очень надежны).

Если вы полагаетесь на finalize для корректной работы вашего приложения, то вы делаете что-то неправильно. finalize следует использовать только для очистки ресурсов (обычно не Java). И это точно, потому что JVM не гарантирует, что finalize когда-либо вызывается для какого-либо объекта.

Ответ 2

В общем, лучше не полагаться на finalize() при выполнении какой-либо очистки и т.д.

Согласно Javadoc (который стоило бы прочитать), это:


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


Как указал Иоахим, этого может никогда не произойти в жизни программы, если объект всегда доступен.

Кроме того, сборщик мусора не гарантированно запустится в какое-либо определенное время. В общем, я пытаюсь сказать, что finalize() вероятно, это не лучший метод для использования в целом, если только он не нужен для чего-то конкретного.

Ответ 3

protected void finalize() throws Throwable {}


  • каждый класс наследует finalize() метод от
    java.lang.Object

  • метод вызывается сборщиком мусора, когда он определяет, что больше ссылок на объект не существует

  • метод Object finalize не выполняет никаких действий, но он может быть переопределен любым классом

  • обычно его следует переопределять для очистки ресурсов, отличных от Java, т.е. для закрытия файла

  • при переопределении finalize() хорошей практикой программирования является использование инструкции try-catch-finally и ее всегда вызывать super.finalize(). Это мера безопасности, гарантирующая, что вы случайно не пропустите закрытие ресурса, используемого классом objects , вызывающим класс


    protected void finalize() throws Throwable {
    try {
    close(); // close open files
    } finally {
    super.finalize();
    }
    }

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


  • finalize() никогда не запускается более одного раза для любого объекта


цитируется по: http://www.janeg.ca/scjp/gc/finalize.html

Вы также можете ознакомиться с этой статьей:

Ответ 4

Метод Java finalize() не является деструктором и не должен использоваться для обработки логики, от которой зависит ваше приложение. В спецификации Java указано, что нет гарантии, что finalize метод вообще вызывается во время работы приложения.

Что вам, вероятно, нужно, так это комбинация finally и метода очистки, как в:

MyClass myObj;

try {
myObj = new MyClass();

// ...
} finally {
if (null != myObj) {
myObj.cleanup();
}
}

Это позволит корректно обработать ситуацию, когда MyClass() конструктор выдает исключение.

java