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()"
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