1

I was going through this topics:

  1. In what order do static initializer blocks in Java run?
  2. Java Static Initialization Order

And I don't understand if we have a constructors, where we can put some logic, such as dealing with exceptional situations, why we need initialization blocks, which code we can also move to constructor ?

If the answer is that in some cases we need to initialize some resources before constructor runs would you help me with some examples, so I could fully see the picture.

Community
  • 1
  • 1
marknorkin
  • 3,904
  • 10
  • 46
  • 82
  • 2
    I don't have examples off the top of my head, so this is a comment. Initialization blocks are nice if you don't want to duplicate work across constructors. Static initialization blocks are nice if you want to do more complex work when initializing static variables. – awksp May 27 '14 at 21:17
  • 1
    @user3580294 you may call another constructor to avoid putting logic in initialization block. – Luiggi Mendoza May 27 '14 at 21:19
  • @LuiggiMendoza But there may be situation where we have `constructor(String)` `constructor(int)` and this constructors could be setting up instance in different ways, so they shouldn't be mixed. – Pshemo May 27 '14 at 21:25
  • @Pshemo use builder pattern for such cases. – Luiggi Mendoza May 27 '14 at 21:25
  • @LuiggiMendoza You are right, that would be better. I was just giving general idea of where initialization blocks could be used, not saying that they must be used :). – Pshemo May 27 '14 at 21:28
  • @Pshemo well, I find your example as a good example to not use initialization blocks but instead builder pattern :P – Luiggi Mendoza May 27 '14 at 21:29
  • 1
    @LuiggiMendoza I am starting to wander why do we actually need initialization blocks (not static ones, they can be useful for instance in [enums](http://stackoverflow.com/questions/18883646/java-enum-methods/18883717#18883717)) – Pshemo May 27 '14 at 21:32
  • @Pshemo: double brace initialization. – Luiggi Mendoza May 27 '14 at 21:32

2 Answers2

4

One example of a time when you'd use (and I have used) static initialization blocks is to initialize a collection of elements. For example, if I have some set of parsers that are stored in a static map:

 private static Map<String, Parser> parsers = new HashMap<String, Parser>();

I may use a static initialization block to populate the members of this map:

static {
  parsers.put("node", new NodeParser());
  parsers.put("tree", new TreeParser());
  parsers.put("leaf", new LeafParser());
  //etc.
}

I would do this because I want the map to be static rather than part of a particular object, or if I only want there to be one of these maps (maybe I only need one).

The difference between this and a constructor is the constructor is called at object instantiation whereas the static initialization block will be called when the class is loaded.

That is, if you call

MyClass.parsers.get("node");

The MyClass constructor is never called so if you waited to initialize the parsers map until the constructor, the above call would return null.

Chris Thompson
  • 35,167
  • 12
  • 80
  • 109
1

why we need initialization blocks

For instance initialization blocks, I can only think on two cases:

  1. When creating an anonymous class:

    Runnable runnable = new Runnable() {
        int x;
        //initialization block here
        {
            //IMO this is such odd design, it would be better to not
            //create this as an anonymous class
            x = outerClassInstance.someMethod();
        }
        @Override
        public void run() {
            //write the logic here...
        }
    };
    
  2. When using double brace initialization (if the class is not marked final):

    List<String> stringList = new ArrayList<>() {
        {
            add("Hello");
            add("world");
        }
    };
    System.out.println(stringlist);
    //prints [Hello, world]
    

For static initialization blocks, there are two cases:

  1. When defining the data for a static field. This is covered in @ChrisThompson's answer.

  2. When initializing a constant (static final) field from an external source, like the result of some computation.

    class Foo {
        public static final boolean DEBUG;
        static {
            DEBUG = getDebugMode();
        }
        private static boolean getDebugMode() {
            //code to open a properties file, read the DEBUG property
            //and return the value
        }
    }
    
Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332