Class initialization order

Many people know that the order of class initialization is as follows:
(1) Call the base class constructor and repeat this process until the bottom layer
(2) Then call the initialization methods of the members in the order of declaration
(3) Call the body of the class constructor

The actual process of class initialization

However, consider this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Animal{

public void walk(){
System.out.println("Animal.walk()");
}
Animal(){
System.out.println("Animal() before walk()");
walk();
System.out.println("Animal() after walk()");
}
}

class Cat extends Animal{
private int step = 100;

@Override
public void walk() {
System.out.println("Cat.walk(), step = " + step);
}

Cat(int step){
this.step = step;
System.out.println("Cat.Cat(), step = " + step);
}
}
public static void main(String[] args) {

new Cat(500);

}

The walk method of the Animal class is designed to be overridden in the Cat class, but Animal’s constructor calls the walk method, which results in a call to Cat.walk().
The generated result of the above code is:

Animal() before walk()
Cat.walk(), step = 0
Animal() after walk()
Cat.Cat(), step = 500

We will find that when the Animal constructor calls the walk() method, the step is not the default initial value of 100, but 0.
Therefore, the order of class initialization mentioned earlier is not complete. In fact, the order of class initialization should be like this:
(1) Allocate space before everything happens, and initialize the storage space allocated to the object to binary zero (or a value equivalent to zero in some special data types)
(2) Call the base class constructor as mentioned above. At this time, the walk method must be called before calling the cat constructor, so the step value at this time is 0
(3) Call the initialization methods of the members in the order of declaration
(4) Call the body of the class constructor
Of course, this kind of error is not easy to find, so it is recommended that you try to avoid calling other methods in the constructor if possible. The only methods that can be safely called in the constructor are the final methods of the base class (because they will not be overrided, there will be no above-mentioned problems)。