How to ensure finalize() is always called (Thinking in Java exercise)

Viewed 14426

I'm slowly working through Bruce Eckel's Thinking in Java 4th edition, and the following problem has me stumped:

Create a class with a finalize( ) method that prints a message. In main( ), create an object of your class. Modify the previous exercise so that your finalize( ) will always be called.

This is what I have coded:

public class Horse {
    boolean inStable;
    Horse(boolean in){
        inStable = in;
    }   
    public void finalize(){
        if (!inStable) System.out.print("Error: A horse is out of its stable!");
    }
}
public class MainWindow {
    public static void main(String[] args) {
        Horse h = new Horse(false);
        h = new Horse(true);
        System.gc();
    }
}

It creates a new Horse object with the boolean inStable set to false. Now, in the finalize() method, it checks to see if inStable is false. If it is, it prints a message.

Unfortunately, no message is printed. Since the condition evaluates to true, my guess is that finalize() is not being called in the first place. I have run the program numerous times, and have seen the error message print only a couple of times. I was under the impression that when System.gc() is called, the garbage collector will collect any objects that aren't referenced.

Googling a correct answer gave me this link, which gives much more detailed, complicated code. It uses methods I haven't seen before, such as System.runFinalization(), Runtime.getRuntime(), and System.runFinalizersOnExit().

Is anybody able to give me a better understanding of how finalize() works and how to force it to run, or walk me through what is being done in the solution code?

5 Answers
Related