This is an extension of question: Order of the initialization in Java
so in the code block:
public class Point {
int y = getX();
int x = 42;
int getX() {
return x;
}
public static void main (String s[]) {
Point p = new Point();
System.out.println(p.x + "," + p.y);
}
}
It outputs 42,0
While the above question was answered by describing the behavior of the Java compiler and runtime, it is still bugging me why the compiler does not bake the initial value of x (42) into the bytecode?
I know the values of static variables get embedded into the bytecode since they are class level variables and they dont take up any space in the object memory, but doesn’t it make sense to also embed any initial values for class level non-static variables also into the bytecode? That way, the code above will be more in-line with expected behavior, and the instantiation of the object will be quicker I am guessing (since the memory assigned to x will immediately contain 42 hence saving time in parsing the initialization line in the class every time an object of class Point is created)
I suspect this might have something to do with the tradeoffs between class bytecode size, object initialization efficiency, and compile time efficiency.
I am hoping someone with deep knowledge on Java compiler/runtime can throw some light on this.
Knowing how a framework works internally always helps us write better code 🙂
It’s not a question of efficiency; it’s a question of having sensible semantics.
The Java designers wanted the behavior of initialization to be the same whether
xis defined to be42or to begetFortyTwo(), because if that behavior is different, then that leads to all kinds of ways to unintentionally shoot yourself in the foot. So they specified in the JLS which order field initialization occurs in, and that order is independent of whetherxis a constant or a method call or a potato. (For reference, it’s the order that you declare the fields in — so if you reversed the order ofxandyin your class,ywould be set to 42.)Frankly, I would bet that the compiler bakes the assignment
y = 0into the constructor, because the JLS’s semantics require thaty = 0based on this code.