views:

1298

answers:

5

My question is about one particular usage of static keyword. It is possible to use static keyword to cover a code block within a class which does not belong to any function. For example following code compiles:

public class Test {
    private static final int a;    
    static {
        a = 5;
        doSomething(a);
    }
    private static int doSomething(int x) {
        return (x+5);
    }
}

If you remove the static keyword it complains because the variable a is final. However it is possible to remove both final and static keywords and make it compile.

It is confusing for me in both ways. How am I supposed to have a code section that does not belong to any method? How is it possible to invoke it? In general, what is the purpose of this usage? Or better, where can I find documentation about this?

+4  A: 

The static block is a "static initializer".

It's automatically invoked when the class is loaded, and there's no other way to invoke it (except maybe via Reflection?).

I've personally only ever used it when writing JNI code:

class JNIGlue {
    static {
        System.loadLibrary("foo");
    }
}
Alnitak
+1  A: 

The static code block can be used to instantiate or initialize class variables (as opposed to object variables). So declaring "a" static means that is only one shared by all Test objects, and the static code block initializes "a" only once, when the Test class is first loaded, no matter how many Test objects are created.

Paul Tomblin
As a follow up, if I do not create an instance of the object but instead I call a public static function. Does it imply that this block is guaranteed to execute before this public function call? Thanks.
Szere Dyeri
If you call a public static function of the class, then the class needs to be loaded first, so yes, the static initializer will execute first.
Paul Tomblin
Unless it was class initialisation which (indirectly) called the code which is trying to use it. IFYSWIM. Circular dependencies and all that.
Tom Hawtin - tackline
@Tom is right - it's possible to write something where one static initializer calls a static method before another static initializer is called, but my mind recoils at the thought so I never considered it.
Paul Tomblin
Thanks a lot to you both for the clarification.
Szere Dyeri
A: 

You will not write code into a static block that needs to be invoked anywhere in your program. If the purpose of the code is to be invoked then you must place it in a method.

You can write static initializer blocks to initialize static variables when the class is loaded but this code can be more complex..

A static initializer block looks like a method with no name, no arguments, and no return type. Since you never call it it doesn't need a name. The only time its called is when the virtual machine loads the class.

Vincent Ramdhanie
+25  A: 

The code block with the static modifier signifies a class initializer; without the static modifier the code block is an instance initializer.

Static initializers are executed in the order they are defined (top down, just like simple variable initializers) when the class is loaded (actually, when it's resolved, but that's a technicality).

Instance initializers are executed in the order defined when the class is instantiated, immediately before the constructor is called.

If you remove static from int a, it becomes an instance variable which is not initialized at construction. If you also remove static from the initializer block, it then becomes an instance initializer and so int a is initialized at construction.

Software Monkey
+1  A: 

"final" guarantees that a variable must be initialized before end of object initializer code. Likewise "static final" guarantees that a variable will be initialized by the end of class initialization code. Omitting the "static" from your initialization code turns it into object initialization code; thus your variable no longer satisfies its guarantees.

DJClayworth