101

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;

    ....
Jean-François Corbett
  • 34,562
  • 26
  • 126
  • 176
Adam Matan
  • 107,447
  • 124
  • 346
  • 512
  • 1
    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 Feb 21 '12 at 14:40
  • It is a good place to load classes or load native library. – qrtt1 Feb 21 '12 at 14:43
  • 1
    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 Oct 06 '17 at 23:39

13 Answers13

118

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
}
Rich O'Kelly
  • 38,811
  • 8
  • 78
  • 108
  • 3
    Doing "b = a * 4;" inline would only be a problem if b were declared before a, which is not the case in your example. – George Hawkins Feb 24 '12 at 08:44
  • 1
    @GeorgeHawkins I was only trying illustrate that a static initialiser runs after inline initialisers, not that an equivalent couldn't be done inline. However, I take your point and have updated the example to (hopefully) be clearer. – Rich O'Kelly Feb 24 '12 at 09:26
  • 1
    Just for fun I might point out that your first example could just as easily be "static double a=someCondition?0:1;" Not that your examples aren't great, I'm just sayin... :) – Bill K Oct 06 '17 at 23:42
  • So initializing variables as static and then working with them inside the static block worked but why am I getting an error if I initialize the variables as static int B, etc inside the static block? – Amit Amola May 24 '21 at 12:21
18

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?

gawi
  • 13,050
  • 7
  • 38
  • 74
  • 2
    Answer: [Guava](http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableMap.Builder.html) :) +1 – Paul Bellora Feb 21 '12 at 14:55
  • 2
    Another answer without additional libraries: create a static method that encapsulates the initialization of `SET` and use the variable initializer (`private final static Set SET = createValueSet()`). What if you have 5 sets and 2 maps would you just dump all of them into a single `static` block? – TWiStErRob Oct 19 '16 at 22:08
16

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!

Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
karan patel
  • 407
  • 5
  • 9
12

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.

Paul Bellora
  • 51,514
  • 17
  • 127
  • 176
5

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.

Jesper
  • 186,095
  • 42
  • 296
  • 332
4

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.

ruakh
  • 156,364
  • 23
  • 244
  • 282
4

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

Danubian Sailor
  • 21,505
  • 37
  • 137
  • 211
3

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("=================");
    }
}
imbond
  • 1,830
  • 1
  • 17
  • 20
3

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.

Tom Hawtin - tackline
  • 139,906
  • 30
  • 206
  • 293
1

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);
    }
}
Michael
  • 467
  • 1
  • 8
  • 20
  • Reading stdin in a static initializer is a pretty awful idea. And `System.out.println("B * H");` is pretty useless. And the answer itself is pretty vague. OP didn't mention constructors or instance variables. – shmosel Apr 03 '18 at 22:48
  • This is just an example that shows what a static initializer is and how it is used. OP didnt ask for constructors or instance variables but in order to teach him the difference of static initializer from constructor he needs to know that. Otherwise he would say "Why dont i just use a constructor to initialize my static variables?" – Michael Apr 03 '18 at 22:51
1

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;
}
algolicious
  • 1,122
  • 2
  • 8
  • 14
  • 3
    While what you are saying is true, it does not demonstrate the necessity of static initializer block. You can just move you `ab` declaration below the declaration of `b`. – gawi Feb 21 '12 at 14:50
0

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.

Pang
  • 8,605
  • 144
  • 77
  • 113
Remario
  • 3,455
  • 2
  • 14
  • 22
0

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.

Armel
  • 2,328
  • 6
  • 16
  • 28
I'm_Pratik
  • 400
  • 2
  • 16