2

I've recently noticed this construct in java that allows executing code before the constructor gets called:

public class Foo {

    {
        System.out.println("before constructor 1");
    }

    public Foo () {
        System.out.println("constructor");
    }


    {
        System.out.println("before constructor 2");
    }

}

With this class, when constructor is called:

new Foo();

this gets to the output:

before constructor 1
before constructor 2
constructor

I would like to know more about this construct: how is it called, when it was added, documentation page url ...

Chris Kitching
  • 2,559
  • 23
  • 37
Ben
  • 3,989
  • 9
  • 48
  • 84

1 Answers1

4

This is an instance initialiser block

The compiler concatenates all the instance initialiser blocks in your class in the order they are given, then copies the result into the start of all constructors, including the implicit no-args one (if applicable).

The only time the semantics of these are different from if you just copied this code into the constructors yourself is when you have a superclass constructor call. Instance initialisers allow you to have code that runs before the call to super(), but the language rules don't allow you to write constructors with this property.

A similar mechanism is used to handle field initialisers. When you define a field like this:

int something = 3;

It will generate something = 3 and copy it into the beginning of every constructor (before any instance initialisers).

Also interesting are static initialiser blocks

Community
  • 1
  • 1
Chris Kitching
  • 2,559
  • 23
  • 37
  • 1
    There is one mistake in your answer- in case you have a constructor matching super, parent constructor call must be the first line of the constructor. The only way to have code executed before your constructor is by using this instance initialiser block. – Ben Mar 09 '16 at 19:09
  • 1
    Instance initialiser blocks are just copied into the start of every constructor by the compiler. The need to call super at the start of each constructor you _write_ is a language rule that's irrelevant to this mechanism. I'll add an explicit mention of this, since it is the only situation in which the semantics of this are actually different from copy-pasting your code everywhere. – Chris Kitching Mar 09 '16 at 19:11
  • What these comments mean is that those blocks are NOT executed BEFORE your constructor - they are executed at the beginning of your constructor, before the rest of the statements in your constructor are executed, similar to how instance variables are initialized . This is easy to see - even without such blocks - when using a debugger, stepping into the constructor. – FredK Mar 09 '16 at 19:27
  • 1
    Yes. That's exactly what my answer says. The compiler literally _copies these blocks into all constructors_. – Chris Kitching Mar 09 '16 at 19:28
  • There's no magical "before the constructor" place for code to run, there's just this handy shorthand for causing code to end up in all constructors. The exact same mechanism is used for instance variable initialisers: but I said all that above. – Chris Kitching Mar 09 '16 at 19:29