Есть ли деструктор для Java? - PullRequest
       61

Есть ли деструктор для Java?

549 голосов
/ 05 октября 2008

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

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

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

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

Ответы [ 20 ]

4 голосов
/ 05 октября 2008

Функция finalize() является деструктором.

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

Более того, требуется более одного GC для освобождения объектов, которые имеют finalize().

Вы должны попытаться очистить логические места в вашем коде, используя операторы try{...} finally{...}!

4 голосов
/ 05 октября 2008

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

3 голосов
/ 05 октября 2008

Возможно, вы можете использовать блок try ... finally, чтобы завершить объект в потоке управления, в котором вы используете объект. Конечно, это не происходит автоматически, но и уничтожение в C ++ не происходит. Вы часто видите закрытие ресурсов в блоке finally.

1 голос
/ 05 октября 2008

Ближайшим эквивалентом деструктора в Java является метод finalize () . Большая разница с традиционным деструктором заключается в том, что вы не можете быть уверены, когда он будет вызван, поскольку это является обязанностью сборщика мусора. Я настоятельно рекомендую внимательно прочитать это перед использованием, поскольку ваши типичные шаблоны RAIA для файловых дескрипторов и т. Д. Не будут надежно работать с finalize ().

1 голос
/ 28 декабря 2016

В Ломбоке есть аннотация @ Cleanup , которая в основном напоминает деструкторы C ++:

@Cleanup
ResourceClass resource = new ResourceClass();

При обработке (во время компиляции) Lombok вставляет соответствующий блок try-finally, чтобы вызывать resource.close(), когда выполнение выходит из области видимости переменной. Вы также можете явно указать другой способ освобождения ресурса, например, resource.dispose():

@Cleanup("dispose")
ResourceClass resource = new ResourceClass();
1 голос
/ 25 августа 2009

Если вы пишете Java-апплет, вы можете переопределить метод Applet "destroy ()". Это ...

 * Called by the browser or applet viewer to inform
 * this applet that it is being reclaimed and that it should destroy
 * any resources that it has allocated. The stop() method
 * will always be called before destroy().

Очевидно, не то, что вы хотите, но, возможно, это то, что ищут другие люди.

0 голосов
/ 03 ноября 2016

Просто подумав об исходном вопросе ... который, я думаю, мы можем сделать из всех других заученных ответов, а также из важнейшего Эффективного Java Блоха , пункт 7, «Избегать финализаторов», ищет решение законного вопроса способом, не соответствующим языку Java ...:

... не было бы довольно очевидным решением сделать то, что на самом деле хочет ОП, - хранить все ваши объекты, которые должны быть сброшены, в виде «игрового автомата», на который все другие не сбрасываемые объекты имеют только ссылки через какой-то объект доступа ...

И затем, когда вам нужно «перезагрузить», вы отключаете существующий манеж и создаете новый: вся паутина объектов в манеже отбрасывается по течению, никогда не возвращается и однажды будет собрана GC.

Если какой-либо из этих объектов Closeable (или нет, но имеет метод close), вы можете поместить их в Bag в манеже по мере их создания (и, возможно, открытия) и последнем действии. принадлежность, прежде чем отрезать манеж, будет проходить через все Closeables закрывая их ...?

Код, вероятно, будет выглядеть примерно так:

accessor.getPlaypen().closeCloseables();
accessor.setPlaypen( new Playpen() );

closeCloseables, вероятно, будет методом блокировки, возможно, включающим защелку (например, CountdownLatch), для обработки (и ожидания в зависимости от ситуации) любого Runnables / Callables в любых потоках, специфичных для Playpen Завершается соответствующим образом, в частности в потоке JavaFX.

0 голосов
/ 17 мая 2013

Раньше я в основном имел дело с C ++, и именно это привело меня к поиску деструктора. Я сейчас использую JAVA. То, что я сделал, и это может быть не лучшим вариантом для всех, но я реализовал свой собственный деструктор, сбросив все значения либо в 0, либо там по умолчанию через функцию.

Пример:

public myDestructor() {

variableA = 0; //INT
variableB = 0.0; //DOUBLE & FLOAT
variableC = "NO NAME ENTERED"; //TEXT & STRING
variableD = false; //BOOL

}

В идеале это не будет работать во всех ситуациях, но там, где есть глобальные переменные, они будут работать, если у вас их нет.

Я знаю, что я не лучший Java-программист, но мне кажется, что он работает.

0 голосов
/ 05 июля 2018

В Java нет точно класса деструктора, класс уничтожается в Java автоматически сборщиком мусора. но вы можете сделать это, используя ниже один, но это не совсем то же самое:

завершить ()

Был вопрос, который породил всестороннее обсуждение финализации , так что вы должны получить больше глубины, если требуется ...

0 голосов
/ 05 октября 2008

Хотя в технологии Java GC и произошли значительные улучшения, вам все же нужно помнить о ваших ссылках. Вспоминаются многочисленные случаи, казалось бы, тривиальных эталонных образцов, которые на самом деле являются гнездами крыс под капотом.

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

...