[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-java-core-chto-takoe-finalize-zachem-on-nuzhen":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":18,"progress":19,"seo":20},58,"chto-takoe-finalize-zachem-on-nuzhen",2,"java-core","Java Core","☕","Что такое `finalize()`? Зачем он нужен?","> **Важно:** Метод `finalize()` объявлен устаревшим начиная с Java 9 (`@Deprecated(since=\"9\")`) и помечен для удаления начиная с Java 18 (`@Deprecated(since=\"9\", forRemoval=true)`). Вместо `finalize()` рекомендуется использовать конструкцию _try-with-resources_ (для объектов, реализующих `AutoCloseable`) или `java.lang.ref.Cleaner` API (появился в Java 9) для выполнения действий по освобождению ресурсов.\n\nЧерез вызов метода `finalize()` (который наследуется от Java.lang.Object) JVM реализуется функциональность аналогичная функциональности деструкторов в С++, используемых для очистки памяти перед возвращением управления операционной системе. Данный метод вызывается при уничтожении объекта сборщиком мусора (garbage collector) и переопределяя `finalize()` можно запрограммировать действия необходимые для корректного удаления экземпляра класса - например, закрытие сетевых соединений, соединений с базой данных, снятие блокировок на файлы и т.д.\n\nПосле выполнения этого метода объект должен быть повторно собран сборщиком мусора (и это считается серьезной проблемой метода `finalize()` т.к. он мешает сборщику мусора освобождать память). Вызов этого метода не гарантируется, т.к. приложение может быть завершено до того, как будет запущена сборка мусора.\n\nОбъект не обязательно будет доступен для сборки сразу же - метод `finalize()` может сохранить куда-нибудь ссылку на объект. Подобная ситуация называется «возрождением» объекта и считается антипаттерном. Главная проблема такого трюка - в том, что «возродить» объект можно только 1 раз.\n\nПример:\n```java\npublic class MainClass {\n\n\tpublic static void main(String args[]) {\n\t\tTestClass a = new TestClass();\n\t\ta.a();\n\t\ta = null;\n\t\ta = new TestClass();\n\t\ta.a();\n\t\tSystem.out.println(\"!!! done\");\n\t}\n}\n```\n```java\n\npublic class TestClass {\n\n\tpublic void a() {\n\t\tSystem.out.println(\"!!! a() called\");\n\t}\n\n\t@Override\n\tprotected void finalize() throws Throwable {\n\t\tSystem.out.println(\"!!! finalize() called\");\n\t\tsuper.finalize();\n\t}\n}\n```\nТак как в данном случае сборщик мусора может и не быть вызван (в силу простоты приложения), то результат выполнения программы с большой вероятностью будет следующий:\n```\n!!! a() called\n!!! a() called\n!!! done\n```\nТеперь несколько усложним программу, добавив принудительный вызов Garbage Collector:\n```java\npublic class MainClass {\n\n\tpublic static void main(String args[]) {\n\t\tTestClass a = new TestClass();\n\t\ta.a();\n\t\ta = null;\n\t\tSystem.gc(); \u002F\u002F Принудительно зовём сборщик мусора\n\t\ta = new TestClass();\n\t\ta.a();\n\t\tSystem.out.println(\"!!! done\");\n\t}\n\n}\n```\nКак и было сказано ранее, Garbage Collector может в разное время отработать, поэтому результат выполнения может разниться от запуска к запуску:\nВариант а:\n```\n!!! a() called\n!!! a() called\n!!! done\n!!! finalize() called\n```\nВариант б:\n```\n!!! a() called\n!!! a() called\n!!! finalize() called\n!!! done\n```","","junior",[15,16,17],"jvm","core","garbage-collection",[],null,{"title":21,"description":22,"ogTitle":21,"ogDescription":23,"keywords":24,"schemaAnswer":32,"featuredSnippetReady":33},"Метод finalize() в Java: назначение и особенности — Gymterview","Что такое метод finalize() в Java, зачем он нужен, почему он устарел начиная с Java 9 и какие альтернативы существуют: try-with-resources и Cleaner API.","Разбор метода finalize(): вызов перед удалением объекта сборщиком мусора, проблемы и современные альтернативы.",[25,26,27,28,29,30,31],"finalize","Java","сборщик мусора","деструктор","garbage collector","Cleaner API","try-with-resources","Метод finalize() наследуется от Object и вызывается сборщиком мусора перед удалением объекта. Позволяет запрограммировать действия по очистке ресурсов (закрытие соединений, снятие блокировок). Устарел с Java 9 — вместо него рекомендуется использовать try-with-resources или java.lang.ref.Cleaner API. Вызов finalize() не гарантируется, объект после него должен быть повторно собран GC, а «возрождение» объекта через сохранение ссылки возможно только один раз.",true]