or

Understanding Static Blocks

Before talking about Static Initializer, I wanna talk a little bit about what is this static thingy in Java.

Every developer who comes from non-OOP origin look for a global variables in Java. And they end up, there is no such a thing in Java. The only thing that close to global variables in Java is static variables. So what is static variables? Static variables are basically class variables. When you define a static variable for your class implementation, there will be only one copy of the variable for the class rather than one for each instance of the class. In other words, this basically gives you an option to have class-wide global variables. Anyway, since I’m not a technical writer, I’ll show it on the code again :)

class IHaveStaticVariable {
   public static final String iAmStaticVariable = "HELLO";

   // as a best practice, never define variables public if possible
   public final String iAmNotStaticVariable = "Oopps";

   public IHaveStaticVariable() {
   }
}

// somewhere in your code
IHaveStaticVariable weAreTrying = new IHaveStaticVariable();
IHaveStaticVariable iAmTryingToo = new IHaveStaticVariable();

// let's print static variable on both classes
System.out.println(weAreTrying.iAmStaticVariable);
System.out.println(iAmTryingToo.iAmStaticVariable);
// this will show same thing for both output: HELLO

// now let's print non-static variables
System.out.println(weAreTrying.iAmNotStaticVariable);
System.out.println(iAmTryingToo.iAmNotStaticVariable);
// this will print same too: Oopps

// so what is the difference? let's make a difference
weAreTrying.iAmStaticVariable = "NEW";
iAmTryingToo.iAmStaticVariable = "SECOND NEW";

// let's print static variable on both classes again
System.out.println(weAreTrying.iAmStaticVariable);
System.out.println(iAmTryingToo.iAmStaticVariable);
// woov, output is double "SECOND NEW"

// is it same for non-static variable? let's try..
weAreTrying.iAmNotStaticVariable = "ouch";
iAmTryingToo.iAmNotStaticVariable = "yeah";

// let's print static variable on both classes again
System.out.println(weAreTrying.iAmNotStaticVariable);
System.out.println(iAmTryingToo.iAmNotStaticVariable);
// two different output

These are just basics. Let’s go a little bit further in this topic.

Java has 2 important blocks in its class definition. Static variables/methods/blocks and constructor block. There is also double brace initialization block which I’ve already written an article about that. For more information about that topic, please refer to this article.

So what is special about these definitions. Well, I’m sure everybody knows what constructor is, so I’ll skip that. The hidden gem is lying under static blocks/methods/variables :) A static block resembles a method with no name/arguments/return type. There is no need to refer to it from outside the class definition, therefore it doesn’t need a name. If it doesn’t have any name, who is executing this block? Simple :) This block is executed by the Java VM when the class is loaded.

Why Do I Need a Static Block

Static blocks are very useful if you consider doing things like below:

  • If you’re loading drivers and other items into the namespace. (for instance Class.forName(”org.h2.Driver”))
  • Initialize your static members at once (most likely this would be singletons, etc)
  • Security related issues or logging related tasks
  • Some database operations like creating prepared SQL statements, etc

Execution Order

Java doesn’t limit you with one static block. So you may define more than one static block. JVM combines them together and then executes. Here you might think what about the order of all these statements? Since static code blocks could be separated by non-static code blocks, the execution might not be in the same order you see in the code. You must remember that JVM combines all these blocks into one single static block and then executes. Here are some notes from my understanding:

  • If you’re defining static variables/methods, JVM will execute these statements when they need.
  • If you have executable statements in the static block, JVM will automatically execute these statements when the class is loaded into JVM.
  • If you’re referring some static variables/methods from the static blocks, these statements will be executed after the class is loaded into JVM (same time as second).

Let’s see all of these in one great example:

public class StaticDemo {
    public static final String name = "NAME";

    {
        System.out.println("HELLO");
    }

    static {
        show();
    }

    public StaticDemo() {
        System.out.println("CONSTRUCTOR");
    }

    public static void show() {
        System.out.println("MESSAGE");
    }

    public static void main(String[] args) {
        System.out.println("MAIN");

        StaticDemo s = new StaticDemo();
        StaticDemo s2 = new StaticDemo();
    }

    static {
        System.out.println("STATIC BLOCK");
        System.out.println("StaticDemo.name = " + name);
    }
}

/*
You'll see following output:

MESSAGE
STATIC BLOCK
StaticDemo.name = NAME
MAIN
HELLO
CONSTRUCTOR
HELLO
CONSTRUCTOR
*/

So what happened in above code? Let me try to explain. First of all, Java didn’t do anything before the class is loaded into JVM. After loading, JVM combined all the static blocks into one regardless of their position in the code, and started to execute each line. If line is executable JVM executed that line, otherwise it just kept the method/variable blocks on a special area in the memory. And when they are needed, JVM executed those statements too. If you double check, we have 2 static methods, one is show and the other is main. Show is executed as the first item since it is called within the static block. However, main is executed after all static initializations. I’ll try to cover main method execution in a different article. So don’t think about that too much.

One thing you might notice is there is another block without static keyword. And it’s been executed twice. Yes, that block is not a static block. It is instance initialization block. For more information, please refer this article again. I hope this clarifies things a little bit :)

Limitations

Yes, we have couple limitations about static blocks:

  • You shouldn’t try to access super since there is no such a thing for static blocks
  • You cannot use this keyword since there is no instance :)
  • You cannot throw Checked Exceptions
  • And please don’t try to return anything from this block

Please share your knowledge on this topic by adding new comments. This is what I know so far :) Hope it helps somebody!



2 Responses

  1. Abhishek

    why this works (compiles) , even if the variable in static is yet not declared:

    public class StaticTest {

    
    
    static
    {
        System.out.println("Hello You1");
        refInitClass3= new InitClass3(1);
        System.out.println("Hello You2");      
    }      
    public InitClass2 refInitClass2= new InitClass2();  

    public static InitClass1 refInitClass1= new InitClass1();

    public static InitClass3 refInitClass3= new InitClass3(2);

    public static void main(String[] args) {

        StaticTest refStaticTest = new StaticTest();
    }

    }

    September 8, 2009, 10:33 AM
  2. Isa Goksu

    @abhishek, when you use multiple static keyword/block usages, JVM combines all of them into one big static block and then executes it. In your example static InitClass3 variable is already defined due to the fact that they’re in the same block. This usage is exactly same with:

    static { .. public static InitClass3 refInitClass3= new InitClass3(2); System.out.println(”Hello You1″); refInitClass3= new InitClass3(1); System.out.println(”Hello You2″); .. }

    Hope it helps.

    September 8, 2009, 11:27 AM

Leave a Reply

Name (required)
Mail (required)
Website