Why getX () method executes first and not constructor

In the following code snippet, the method getX()

executes first, not the constructor:

public class ConsructorQuestion {

    int x = getX();  // same this.getX();
    public int getX() {
        System.out.println(x + "  via method  ");
        return 10;
    }

    public ConsructorQuestion() {
        System.out.println(x+"  via constructor");
    }

    public static void main(String[] args) {
        ConsructorQuestion t = new ConsructorQuestion();
    }

}

      

+3


source to share


3 answers


Instance variables are initialized before the constructor body is executed (but after the superclass constructor body is executed).

So in your example



is executed before the body of the constructor.

This is equivalent to moving the initialization x

to the first line of the constructor:

int x;
public int getX(){
    System.out.println(x+"  via method  ");
    return 10;
}

public ConsructorQuestion() {
    x = getX();
    System.out.println(x+"  via constructor");
}

      

+6


source


Field initializers (and instance initialization blocks) are injected by the compiler at the beginning of each class constructor (immediately after the call super(...)

, implicit or explicit), unless a constructor is concatenated to another in the same class (by calling this(...)

). So if you look at the generated bytecode, you can see that your class looks like this:

public class ConsructorQuestion {

    int  x;                                             // ***
    public int getX(){
        System.out.println(x+"  via method  ");
        return 10;
    }

    public ConsructorQuestion() {
        this.x = getX();                                // ***
        System.out.println(x+"  via constructor");
    }

    public static void main(String[] args) {
        ConsructorQuestion t = new ConsructorQuestion();
    }

}

      

The order of things when constructing instances is covered by JLS§12.5 :



Before the result is a reference to the newly created object, the specified constructor is processed to initialize the new object using the following procedure:

  • Assign the constructor arguments to the newly created parameter variables for this constructor call.

  • If this constructor begins by explicitly calling a constructor (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process the constructor call recursively using these five steps. If the call to the constructor ends abruptly, then this procedure ends abruptly for the same reason; otherwise, go to step 5.

  • This constructor does not start by explicitly calling the constructor of another constructor in the same class (using this). If this constructor is of a class other than Object, then this constructor will start by explicitly or implicitly calling the superclass's constructor (using super). Evaluate the arguments and process the superclass constructor call recursively using these five steps. If the constructor call completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, go to step 4.

  • Execute instance initializers and instance variable initializers for this class by assigning the values ​​of the instance variable initializers to the corresponding instance variables in the order from left to right, in which they appear textually in source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed, and this procedure exits abruptly with the same exception. Otherwise, go to step 5.

  • Execute the rest of the body of this constructor. If this execution ends abruptly, then this procedure ends abruptly for the same reason. Otherwise, this procedure works fine.

Pay attention to the order # 4 and # 5.

+5


source


Javac starts at the beginning of the class and first initializes the members of the class and then goes to the main one.

0


source







All Articles