Monday, 6 October 2014

Constructor and initialisation blocks

This article talks about the rules to follow when implementing Java constructors and in which order the initialisation blocks and constructors are initialised at runtime.

 Rules about constructors

  • Every classes, including abstract classes, must have a constructor! 
  • a constructor can not be overridden, but it can be overloaded, 
  • a constructor can use any access modifiers and can not have a return type, 
  • if you do not declare a constructor in your class, then the compiler will add a default "no-arg" constructor with 'super()' as first statement of the constructor; note that the default constructor has the same access modifier than the class, 
  • if you declare a constructor, be aware that the compiler will not add automatically a default "no-arg" constructor if there is not one, 
  • if you declare your constructor, the compiler will automatically add 'super()' as first statement of your constructor, 
  • keep in mind that if you do not explicitly call 'super', the compiler will add it on the top of your constructor; in this case make sure that the superclass has a 'no-arg' constructor, otherwise the code will not compile (remember that if a superclass has a constructor with argument(s), then the compiler will not add a default 'no-arg' constructor to this superclass), 
  • if you decide to use manually 'super()' or 'this()' (you can not use them together in same constructor) make sure that you write it as first statement of your constructor, 
  • a constructor can call an other constructor of the same class with "this()"; note that a method can not use neither "this()" nor "super()", 
  • even if it is not advised, note that it is possible to have a method with the same name than your class: this will not be seen as a constructor by the compiler as a method must have a return type and a constructor should not have one.

Initialization blocks 


There are 2 types of initialization blocks:
  • static initialization block: run when a class is first loaded 
  • instance initialization block: run each time an instance of a class is created; it runs just after the call of "super()" 
If, in a class, there are many initialization blocks then they are loaded following their declaration order.

class Car {

    // a static initialisation block
    static {
        System.out.println("Car - Static initialization block");
    }

    // a constructor
    Car() {
        System.out.println("Car - 0 arg constructor");
    }

    // an instance initialisation block
    {
        System.out.println("Car - Instance initialization block");
    }

}

public class Ferrari extends Car {

    Ferrari() {
        System.out.println("Ferrari- 0 arg constructor");
    }

    Ferrari (String model) {
        System.out.println("Ferrari - 1 arg constructor");
    }
   
    static {
        System.out.println("Ferrari - First static initialization block");
    }

    {
        System.out.println("Ferrari - First instance initialization block");
    }

    {
        System.out.println("Ferrari - Second instance initialization block");
    }

    static {
        System.out.println("Ferrari - Second static initialization block");
    }

    public static void main(String[] args){
        System.out.println("");
        new Ferrari();
        System.out.println("");
       new Ferrari("Renault 19");
    }

}

The execution of the class "Ferrari" will output:

Car - Static initialization block
Ferrari - First static initialization block
Ferrari - Second static initialization block

Car - Instance initialization block
Car - 0 arg constructor
Ferrari - First instance initialization block
Ferrari - Second instance initialization block
Ferrari- 0 arg constructor

Car - Instance initialization block
Car - 0 arg constructor
Ferrari - First instance initialization block
Ferrari - Second instance initialization block
Ferrari - 1 arg constructor