109
votes

What's the difference between initialization within a static block:

public class staticTest {

    static String s;
    static int n;
    static double d;

    static {
        s = "I'm static";
        n = 500;
        d = 4000.0001;
    }
    ...

And individual static initialization:

public class staticTest {

    static String s = "I'm static";
    static int n    = 500;
    static double d = 4000.0001;

    ....
13
You're only using assignments in the static initialization block, so of course those could be done using static variable assignment. Have you tried seeing what happens if you need to execute non-assignment statements? - Platinum Azure
It is a good place to load classes or load native library. - qrtt1
Note that static variables should be avoided and therefore static initialization blocks are generally not a great idea. If you find yourself using them a lot, expect some trouble down the line. - Bill K

13 Answers

124
votes

A static initialization blocks allows more complex initialization, for example using conditionals:

static double a;
static {
    if (SomeCondition) {
      a = 0;
    } else {
      a = 1;
    }
}

Or when more than just construction is required: when using a builder to create your instance, exception handling or work other than creating static fields is necessary.

A static initialization block also runs after the inline static initializers, so the following is valid:

static double a;
static double b = 1;

static {
    a = b * 4; // Evaluates to 4
}
18
votes

A typical usage:

private final static Set<String> SET = new HashSet<String>();

static {
    SET.add("value1");
    SET.add("value2");
    SET.add("value3");
}

How would you do it without static initializer?

17
votes

You can use try/catch block inside static{} like below:

MyCode{

    static Scanner input = new Scanner(System.in);
    static boolean flag = true;
    static int B = input.nextInt();
    static int H = input.nextInt();

    static{
        try{
            if(B <= 0 || H <= 0){
                flag = false;
                throw new Exception("Breadth and height must be positive");
            }
        }catch(Exception e){
            System.out.println(e);
        }

    }
}

PS: Referred from this!

12
votes

Exception handling during initialization is another reason. For example:

static URL url;
static {
    try {
        url = new URL("https://blahblah.com");
    }
    catch (MalformedURLException mue) {
        //log exception or handle otherwise
    }
}

This is useful for constructors that annoyingly throw checked exceptions, like above, or else more complex initialization logic that might be exception-prone.

5
votes

Sometimes you want to do more than just assign values to static variables. Since you cannot put arbitrary statements in the class body, you could use a static initializer block.

4
votes

In your example, there is no difference; but often the initial value is more complex than is comfortably expressed in a single expression (e.g., it's a List<String> whose contents are best expressed by a for-loop; or it's a Method that might not exist, so exception-handlers are needed), and/or the static fields need to be set in a specific order.

4
votes

static block can be used to initialize singleton instance, to prevent using synchronized getInstance() method.

3
votes

Technically, you could get away without it. Some prefer multiline initialisation code to go into a static method. I'm quite happy using a static initialiser for relatively simple multistatement initialisation.

Of course, I'd almost always make my statics final and point to an unmodifiable object.

3
votes

Static keyword (whether it's a variable or block) is belong to the class. So when the class is called, these variables or blocks are executed. So most of the initialisation will be done with the help of static keyword. As it is belong to the class itself, the class can directly accessed it, without creating an instance of the class.

Let's take an example, There is a shoe class in which there are several variables like colour, size, brand etc... And here if the shoe manufacture company has only one brand than we should initialise it as a static variable. So, when the shoe class is called and different types of shoes are manufactured (by creating an instance of the class) at that time colour and size will occupy memory whenever new shoe is created but here the brand is a common property for all shoes, so that it will occupy memory for once no matter how many shoes are manufactured.

Example:

    class Shoe {
    int size;
    String colour;
    static String brand = "Nike";

    public Shoe(int size, String colour) {
        super();
        this.size = size;
        this.colour = colour;
    }

    void displayShoe() {
        System.out.printf("%-2d %-8s %s %n",size,colour, brand);
    }

    public static void main(String args[]) {
        Shoe s1 = new Shoe(7, "Blue");
        Shoe s2 = new Shoe(8, "White");

        System.out.println("=================");
        s1.displayShoe();
        s2.displayShoe();
        System.out.println("=================");
    }
}
3
votes

We use constructors to initialize our instance variables(non-static variables, variables that belong to objects, not the class).

If you want to initialize class variables(static variables) and want to do it without creating an object(constructors can only be called when creating an object), then you need static blocks.

static Scanner input = new Scanner(System.in);
static int widht;
static int height;

static
{
    widht = input.nextInt();
    input.nextLine();
    height = input.nextInt();
    input.close();

    if ((widht < 0) || (height < 0))
    {
        System.out.println("java.lang.Exception: Width and height must be positive");
    }
    else
    {
        System.out.println("widht * height = " + widht * height);
    }
}
1
votes

The static code block enables to initialize the fields with more than instuction, initialize fields in a different order of the declarations and also could be used for conditional intialization.

More specifically,

static final String ab = a+b;
static final String a = "Hello,";
static final String b = ", world";

will not work because a and b are declared after ab.

However I could use a static init. block to overcome this.

static final String ab;
static final String a;
static final String b;

static {
  b = ", world";
  a = "Hello";
  ab = a + b;
}

static final String ab;
static final String a;
static final String b;

static {
  b = (...) ? ", world" : ", universe";
  a = "Hello";
  ab = a + b;
}
0
votes

A static initialization block is useful if one, you wish to intialize specified class static types, prior to the class first use. Subsequent use will not invoke any static initialization blocks. It's the direct opposite of instance initializers, which initialize instance members.

0
votes

When you want to evaluate any certain expression while class loading time then you can make use of static block but remember:

You must handle an exception in static block meaning you cannot throw an exception from a static block.