Don`t use finalize() and Cleaner!
Today we're going to dive a little deeper into item 8 of Creating and Destroying Objects, the first unit of Effective Java.
If we come to the details of our subject, we will examine the
finalize() method of our
Object class and the
Cleaner class. With Java 9, the
finalize() method is
deprecate and it has delegated its work to the
Cleaner class. Those who want to examine for detailed information: OpenJDK Doc.
The finalize() method is a method used to run when the object has not been used for a long time and before the garbage collector comes to clean up. It was created with the motto that the developer should use this method by overriding if there is an operation that he/she wants to have done before the object is deleted from the memory. The main reason why the
finalize() method should not be used is that when the user implements his/him own object, it is not clear when the garbage collector will come and clean it, or even whether it will clean it. It should never be used for a method that you want to be executed immediately if the object exits to the void. It may cause the project to throw an OutOfMemoryError error after a certain time.
Cleaner class has more advantages over the
finalize() method. This advantage is that the threads are under the control of the author of the class. But since the
Cleaner class is under the control of the garbage collector, there is no guarantee when it will be cleaned.
Another disadvantage of the
finalize() method is that exceptions are not caught. When there is an error in this structure, you cannot catch the error, the program does not stop and the stack trace is not printed.
Cleaner does not have this problem because the author can control it.
Another problem is a security vulnerability. This method, which is called Finalizer attack, if an exception is thrown in a constructor, this class can be inherited and a
finalize method can be written in the method it is inherited from. If this written
finalize() method defines a static value in the object, the reference of the object will remain in memory so it cannot be caught by the garbage collector. To solve this situation, an empty
final finalize() can be written, thus ensuring that it cannot be changed.
So, for example, what do we need to do for an event that we plan to do just before deleting it from memory? This process can be file closing or any connection termination. You can implement
AutoCloseable in your class. The
close() method should be called every time the instance is not used for a long time. Use
try-with-resources in case any exception can be thrown. For more detailed information on this subject, I invite you to read the 9th article.