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

Is there a destructor for Java?

Существует ли деструктор для Java?

Есть ли деструктор для Java? Кажется, я не могу найти никакой документации по этому вопросу. Если нет, то как я могу добиться того же эффекта?

Чтобы сделать мой вопрос более конкретным, я пишу приложение, которое работает с данными, и в спецификации сказано, что должна быть кнопка "сброс", которая возвращает приложение в исходное, только что запущенное состояние. Однако все данные должны быть "активными", если только приложение не закрыто или не нажата кнопка сброса.

Будучи обычно программистом на C / C ++, я подумал, что это будет тривиально реализовать. (И, следовательно, я планировал реализовать это в последнюю очередь.) Я структурировал свою программу таким образом, чтобы все объекты, способные к сбросу, находились в одном классе, так что я могу просто уничтожить все "живые" объекты при нажатии кнопки сброса.

Я подумал, что если бы все, что я делал, это просто разыменовывал данные и ждал, пока сборщик мусора соберет их, не произошла бы утечка памяти, если бы мой пользователь повторно вводил данные и нажимал кнопку сброса? Я также подумал, поскольку Java достаточно зрелый язык, должен быть способ предотвратить это или изящно решить эту проблему.

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

Поскольку Java - это язык сбора мусора, вы не можете предсказать, когда (или даже если) объект будет уничтожен. Следовательно, прямого эквивалента деструктора не существует.

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

Недавно был вопрос, который вызвал подробное обсуждение finalize , так что это должно обеспечить большую глубину, если требуется...

Ответ 2

Взгляните на инструкцию try-with-resources . Например:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
System.out.println(br.readLine());
} catch (Exception e) {
...
} finally {
...
}

Здесь ресурс, который больше не нужен, освобождается в BufferedReader.close() методе. Вы можете создать свой собственный класс, который реализует AutoCloseable и использовать его аналогичным образом.

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

Ответ 3

Нет, здесь нет деструкторов. Причина в том, что все объекты Java распределяются в куче и собирают мусор. Без явного освобождения (т. Е. оператора delete в C ++) нет разумного способа реализовать реальные деструкторы.

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

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

Ответ 4

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

Если вам требуется вызов освобождения в вашем объекте, скажем, для освобождения ресурсов, используйте явный вызов метода. Это соглашение можно увидеть в существующих API (например, Closeable, Graphics.dispose(), Widget.dispose()) и обычно вызывается через try/finally.

Resource r = new Resource();
try {
//work
} finally {
r.dispose();
}

Попытки использовать удаленный объект должны вызывать исключение во время выполнения (см. IllegalStateException).


Редактировать:


Я подумал, если бы все, что я делал, это просто разыменовывал данные и ждал, пока сборщик мусора их соберет, не произошла бы утечка памяти, если бы мой пользователь повторно вводил данные и нажимал кнопку сброса?


Как правило, все, что вам нужно сделать, это разыменовать объекты - по крайней мере, предполагается, что это работает именно так. Если вы беспокоитесь о сборке мусора, ознакомьтесь с Настройкой сборки мусора виртуальной машины Java SE 6 HotSpot[tm] (или эквивалентным документом для вашей версии JVM).

2024-03-01 02:56 java