18

I've been working with Java for a long time but never have come across something like this. I would like to know what it does and why it is not an error.

public class Foo{

 private int someVariable;

 {
    doSomething();
 }

 public Foo(){
 }

 private void doSomething(){
    // Something is done here
 }

}

I would like to know what the purpose of the individual block is which contains a call to "doSomething()". Its just a skeleton code. The actual code that I came across is at http://www.peterfranza.com/2010/07/15/gwt-scrollpanel-for-touch-screens/

GreenMatt
  • 18,244
  • 7
  • 53
  • 79
Kasturi
  • 3,335
  • 3
  • 28
  • 42

2 Answers2

27

It's a (non-static) initializer block. It is documented in the official tutorial here:

Initializing Instance Members

Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods. Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:

{
    // whatever code is needed for initialization goes here
}

The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.


Here is a simple demo:

public class Test {

    {
        System.out.println("Initializer block");
    }

    Test() {
        System.out.println("Constructor 1");
    }

    Test(int i) {
        System.out.println("Constructor 2");
    }

    public static void main(String[] args) {
        new Test();
        System.out.println("---");
        new Test(1);
    }
}

Output:

Initializer block
Constructor 1
---
Initializer block
Constructor 2

You may find this useful when for instance adding a JLabel to panel:

panel.add(new JLabel() {{ setBackground(Color.GREEN); setText("Hello"); }});

Under the hood:

The bytecode of the initializer block is literally copied into each constructor. (At least by Suns javac and the eclipse compiler:

Test();
  Code:
    0:  aload_0
    1:  invokespecial
    4:  getstatic #2;
    7:  ldc #3;           //String "Initializer block"
    9:  invokevirtual #4; //Method PrintStream.println:(String;)V
   12:  getstatic #2;
   15:  ldc #5;
   17:  invokevirtual #4;
   20:  return

Test(int);
  Code:
    0:  aload_0
    1:  invokespecial #1;
    4:  getstatic #2;
    7:  ldc #3;           //String "Initializer block"
    9:  invokevirtual #4; //Method PrintStream.println:(String;)V
   12:  getstatic #2;
   15:  ldc #6;
   17:  invokevirtual #4;
   20:  return
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 3
    Note that it runs *before* the constructor code, so don't depend on things done in the constructor(s). – Stephen P Nov 22 '10 at 20:26
7

That's an initializer block, which is copied into all constructors for the class.

lhballoti
  • 806
  • 7
  • 17