The order of execution of initializer blocks, and variable initializer is specified in JLS § 12.5:
Just before a reference to the newly created object is returned as the
result, the indicated constructor is processed to initialize the new
object using the following procedure:
[...]
4 Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable
initializers to the corresponding instance variables, in the
left-to-right order in which they appear textually in the source code
for the class. [..]
So, the initializer blocks and variable initializers executed in order in which they appear in the source file. If you move the variable declaration, int x = 1;, before the initializer block, you'll get the result 2.
Technically, your Test class is compiled to the this:
class TestClass {
int x;
public TestClass() {
super();
x = 2;
x = 1;
}
}
For actual bytecode you can run javap -c command.