Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this code valid? Assigning before declaring?

This is Java. I understand that the assignment of 1 to index is in an initialization block that is first run when the class is instantiated, but why is this valid?

public class arr {
    {
        index = 1;
    }

    int index;

    void go() {
        System.out.println(++index);
    }
    public static void main(String [] args){
          new arr().go(); 
        }
    }

Output is 2.

I should be getting a symbol not found compilation error. Is this behaviour native to initialization blocks? In a normal scenario int index; should come before index = 1;.

like image 709
Mob Avatar asked Dec 04 '22 00:12

Mob


2 Answers

+1, it looks really weird. But as a matter of fact non-static initialization blocks are simply inserted by javac into object constructors. If we decompile arr.class we will get the real code as

public class arr {
    int index;

    public arr() {
        index = 1;
    }

    void go() {
        System.out.println(++index);
    }

    public static void main(String args[]) {
        (new arr()).go();
    }

}

to make more fun of consider this puzzle

public class A {
    int index;

    A() {
        index = 2;
    }

    {
        index = 1;
    }
}

what is new A().index ?. Correct answer is 2. See decompiled A.class

class A {
    int index;

    A() {
        index = 1;
        index = 2;
    }
}

that is, non-static initialization blocks come first in object constructors

like image 180
Evgeniy Dorofeev Avatar answered Dec 17 '22 07:12

Evgeniy Dorofeev


Non-static initialization blocks run right after the constructor so the code is correct and the output as expected.

like image 35
Alessandro Santini Avatar answered Dec 17 '22 07:12

Alessandro Santini