103

I'm looking at the code below and found something a bit strange:

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

    public static void main(String[] args) {
        new Sequence().go();
    }

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

I would've expected this to give a compilation error as the System.out with "y " doesn't belong to a method declaration just a { }. Why is this valid? I don't see how this code would or should be called.

When running this it produces x y c g also, why does the static { } get called before the sequence constructor?

Boann
  • 48,794
  • 16
  • 117
  • 146
David
  • 19,577
  • 28
  • 108
  • 128

8 Answers8

150

This:

static {
    System.out.print("x ");
}   

is a static initialization block, and is called when the class is loaded. You can have as many of them in your class as you want, and they will be executed in order of their appearance (from top to bottom).

This:

{
   System.out.print("y ");
}

is an initialization block, and the code is copied into the beginning of each constructor of the class. So if you have many constructors of your class, and they all need to do something common at their beginning, you only need to write the code once and put it in an initialization block like this.

Hence your output makes perfect sense.

As Stanley commented below, see the section in the Oracle tutorial describing initializaiton blocks for more information.

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
jlordo
  • 37,490
  • 6
  • 58
  • 83
  • 12
    Great answer. Find out more about initialization block at [http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html](http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html) – Stanley Dec 04 '12 at 09:01
  • 6
    `the code is copied into the beginning of each constructor of the class` - this is incorrect. Let's say the constructor starts with `super("x ");`, the super constructor will execute before any initialization blocks. – RokL Dec 05 '12 at 11:47
  • 3
    yes, implicit and explicit calls to superconstructor will be executed first, initialization block next, and than the rest of the constructor code. – jlordo Dec 05 '12 at 13:30
26

Its not a method but a initialization block.

{
    System.out.print("y ");
}

It will be executed before the constructor call. While

static {
    System.out.print("x ");
}

is static initialization block which is executed when class is loaded by class loader.

So when you run your code

  1. Class is loaded by class loader so static initialization block is executed
    Output: x is printed
  2. Object is created so initialization block is executed and then constuctor is called
    Output: y is printed followed by c
  3. Main method is invoked which in turn invokes go method
    Output: g is printed

Final output: x y c g
This might help http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
16

That's an instance initialization block followed by a static initialization block.

{
    System.out.print("y ");
}

gets called when you create an instance of the class.

static {
    System.out.print("x ");
}

gets called when the class is loaded by the class loader. So when you do

new Sequence().go();

the class gets loaded, so it executes static {}, then it executes the instance initialization block {}, afterwards the body of the constructor is called, and then the method on the newly created instance. Ergo the output x y c g.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
15
static {
        System.out.print("x ");
    }

Is a static block and is called during Class Loading

{
    System.out.print("y ");
}

Is an initialization block

You can have multiple initialization blocks in a class in which case they execute in the sequence in which they appear in the class.

Note that any initialization block present in the class is executed before the constructor.

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
10
static {
      System.out.print("x ");
}

is an initialization block shared by the class(as indicated by static), which is executed first.

{
        System.out.print("y ");

}

is an initialization block shared by all objects(constructors) of the class, which comes next.

Sequence() {
        System.out.print("c ");
}

is a particular constructor for the class, which is executed third. The instance initialization block is invoked first every time the constructor is executed. That's why "y" comes just before "c".

void go() {
        System.out.print("g ");
}

is just an instance method associated with objects constructed using the constructor above, which comes last.

Terry Li
  • 16,870
  • 30
  • 89
  • 134
9
{
    System.out.print("y ");
}

These kinds of blocks are called initializer block. It is executed every time you create an instance of a class. At compile time, this code is moved into every constructor of your class.

Where as in case of static initializer block: -

static {
    System.out.println("x ");
}

it is executed once when the class is loaded. We generally use static initializer block when the initialization of a static field, require multiple steps.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
6

It is used as an initialisation block and runs after any static declaration. It could be used to ensure that no one else can create an instance of the class (In the same way you would use a private constructor) as with the Singleton design pattern.

maloney
  • 1,633
  • 3
  • 26
  • 49
3
static {
    System.out.print("x ");
}

Static blocks are only executed once when the class is loaded and initialized by the JRE.

And non-static block will be call every time your are creating a new instance and it will be call just before the Constructor.

As here you've created only 1 instance of Sequence so constructed has been called after non-static blocks and then the method which actually your goal.

Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103