# Sunday, 09 November 2003
« More Name Dropping | Main | Generic Algorithms »
Finalize Considered Harmful

Last week at the PDC I talked to Anders Hejlsberg (btw, he's a really nice person). I asked him about having a way to prevent boxing and he told me they had already considered it and found too many problems with it (reflection, generics, more on that in another post). I also told him that I felt that C# had only one design flaw: The destructor syntax. I was reminded of this when I was working on some java.nio classes yesterday.

The Java Community Doesn't Understand Finalization

How's that for a section title? It's obviously a generalization, but I don't think it is too far from the truth. To prepare for writing this entry I looked at finalization in three books:

All three are excellent books. Highly recommended.

Addison-Wesley put online the relevant section of Peter's book here. First, let me say that Peter is a very smart guy (I know him from the Colorado Software Summit) and that this doesn't reflect on the quality of the rest of the book, but I'm picking on him because part of this particular "praxis" demonstrates the, IMO, typical misunderstanding of finalization in the Java community (and because his book is one of the few Java books I own).

So, what is wrong with his code? He uses the finalize method to cleanup managed objects that already have their own finalizer!
This practice is widely used in the Java libraries as well and it is a really bad idea. At best it doesn't help (the ServerSocket and FileInputStream will have already been finalized (see JLS 12.6.2 Finalizer Invocations are Not Ordered), or will be finalized soon anyway) and at worst you create APIs that are very difficult to use (or code) because multiple objects "own" the same resource.

The JLS doesn't say anything useful about finalization, but does mention that you should always call super.finalize() in your finalizer (like Peter does in his code).


Why? All finalizable classes should extend java.lang.Object and be final, because there is no reason for them not to be. Here is what a finalizable class should look like.

final class FileHandle {
  private int nativeHandle;

  FileHandle(String filename) {
    nativeHandle = nativeOpen(filename);
  private static int nativeOpen(String filename);

  synchronized void close() {
    if(nativeHandle != 0) {
      nativeHandle = 0;
  private static native void nativeClose(int handle);
  protected void finalize() {

  // example operation, the others are omitted
  synchronized int read(...) {
    return nativeRead(nativeHandle, ...);
  private static native int nativeRead(int handle, ...);

Other than exposing the primitive operations that can be performed on the unmanaged resource (thru the handle), the class should have no functionality. The class is package private and used only by the public classes that actually implement the exposed API. The class should never have any references to other objects.

This pattern of factoring out the finalizable resource into a separate class is discussed in the Jones/Lins book. It seems that not enough people read it.

The above discussion is specific to Java and .NET finalization, there are other implementations of finalization that do finalize in order. In such an implementation it can actually be useful to use references to other objects in your finalize method, because you know that the object you're using hasn't already been finalized.

Back To C#

So what's wrong with the C# destructor syntax? I think it encourages the mistake of thinking of Finalize as a destructor (and thus using it to cleanup other managed objects). Also, a "feature" of the C# destructor is that it always call the base class Finalize method. I hope I've shown that this isn't very useful.

Anders agreed with me. "In retrospect we probably shouldn't have done that." (paraphrased from memory).

Sunday, 09 November 2003 15:53:01 (W. Europe Standard Time, UTC+01:00)  #    Comments [1] Tracked by:
"free online nude teen poker" (free online nude teen poker) [Trackback]