Risolto What is the purpose of the finalize() method in Java?

urooj

Utente Iron
20 Dicembre 2022
9
5
0
9
I was asked to explain the concept of my project during the interview.
Gone through some online resources but I couldn't get it.

The invocation of an Object's finalize() method is the last thing that happens before an
object is garbaged collected.

I had to answer the question by.
  • True
  • False
What was the reason that you chose True, and why do you think it was incorrect?
 
That method has no purpose or, to better say, it was a mistake. The official documentation says it's pending removal, so it won't be there in future version of Java and for any practical purpose your interview question is irrelevant and you should be allowed to reply "finalize() is never getting called". In JDK19 finalization is still enabled by default so, technically speaking, that's the wrong answer; nevertheless, you can manually disable it with the --finalization=disabled flag and it will be permanently disabled in the future. It's just wiser to pretend finalize() is not a thing anymore. The only reason for why your question could still be valid is if you are given an old codebase to refactor and they ask you to replace all the overridden finalize() with a saner alternative, like those discussed in the link above.

That said, if you search online you can see reasons for why False was supposed to be the correct answer even years ago. It's a tricky question tho and, since you already did your research, I'll give you my explanation. Let's see what happens in the following code:
Java:
public enum Singleton {
    INSTANCE;
    public List<Object> data = new ArrayList<Object>();
    synchronized public void hold(Object obj) { data.add(obj); }
}

public class Something {
    private int id;
    public Something(int id) { this.id = id; }
    public String toString() { return "Something " + id; }

    protected void finalize() {
        System.out.println("Finalizing " + id);
        Singleton.INSTANCE.hold(this);
    }

    // useless data to make the object big (lots of garbage to collect)
    private Object[] data = new Object[1 << 25];
}

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) { new Something(i); }
        for (Object obj: Singleton.INSTANCE.data) { System.out.println(obj); }
        Singleton.INSTANCE.data = null; // enables garbage collection
    }
}
In the first line of main we are creating a few instances of Something. These few instances we are creating are stored nowhere, so as soon as we create them they become candidates for garbage collection. These objects happens to be quite big, so when they go out of scope the garbage collector is likely to be willing to catch at least some of them. Before deallocating them the java virtual machine calls the finalize method (that's how it works). Our implementation of Something.finalize() acts as a life safer tho, because it store the object that is about to be deallocated into a global variable, making it not a good candidate for deallocation anymore. The virtual machine called a finalize method but the object is not going to be garbage collected because we saved its life. Now we are back to the main and the second line prints every object that was about to be garbage collected (which is not necessarily every object we created, because the garbage collection picks at its own discretion). Finally, we clear the global variable to make every Something object a good candidate for gargabe collection. The finalize method is called at most only once per object (see the docs) so every object that we have finalized and then printed is not going to be finalized ever again. For some Something objects, the java virtual machine chose to call finalize() then had to call toString() and it finally deallocated it: we wrote a program that such that finalize() is not the last thing that happens before an object is garbaged collected.
 
  • Geniale
Reazioni: urooj