Saturday, December 31, 2011

Static Initializers

If you have a block of Java code that looks like this, within a class:

static {
    ...
}

then you've encountered a static initializer. Some facts about them include:
(1) They are executed once per class (more specifically, they are executed once per time the class is loaded).
(2) One can place multiple static initializers within a single class -- they are then aggregated and execute in the order in which they appear in the original code, top to bottom.
(3) They are thread-safe.

some appropriate times to use them:

(1) To load a native library which is known at compile time:

static {
      System.loadLibrary("NameOfLibrary");
}

(2) To initialize static data belonging to a class. For example, a static map:

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class Opposite{

        private static final Map<String, String> oppStrings;

        static {
                Map<String, String> oppStrings = new HashMap<String, String>();
                oppStrings.put("light", "dark");
                oppStrings.put("small", "large");
                myMap = Collections.unmodifiableMap(oppStrings);
        }

        ...
}

An alternative to a static initialization block, in certain cases, is a private static method: 

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class Opposite{

      public static final OPP_STRINGS = constructOppositeMap();

      private static Map<String, String> constructOppositeMap() {
            Map<String, String> oppositeStrings = new HashMap<String, String>();
            oppositeStrings.put("light", "dark");
            oppositeStrings.put("small", "large");
            return Collections.unmodifiableMap(oppositeStrings);
      }
      ...
}

I find this second method to be much more clearly indicative of the fact that OPP_MAP is being initialized. The static initializer could be buried toward the bottom of the file! In this case it wouldn't be immediately apparent where oppmap was being initialized (though you would know that if it compiles then it would have to be initialized somewhere, since the Map is declared "final"). An aptly-named static initializer-mimicker in the form of a private static method ensures easy and intuitive location of where the initialization code resides.

No comments:

Post a Comment