We all know, that according to JLS7 p.4.12.5 every instance variable is initialized with default value. E.g. (1):
public class Test {
private Integer a; // == null
private int b; // == 0
private boolean c; // == false
}
But I always thought, that such class implementation (2):
public class Test {
private Integer a = null;
private int b = 0;
private boolean c = false;
}
is absolutely equal to example (1). I expected, that sophisticated Java compiler see that all these initialization values in (2) are redundant and omits them.
But suddenly for this two classes we have two different byte-code.
For example (1):
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
For example (2):
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: aconst_null
6: putfield #2; //Field a:Ljava/lang/Integer;
9: aload_0
10: iconst_0
11: putfield #3; //Field b:I
14: aload_0
15: iconst_0
16: putfield #4; //Field c:Z
19: return
The question is: Why? But this is so obvious thing to be optimized. What's the reason?
UPD: I use Java 7 1.7.0.11 x64, no special javac options
The default value of static variable is zero. The static variables are alive till the execution of the program.
Generally, all variables should be explicitly initialized in their declaration.
then the local variables are destroyed. The local variables do not have any default values in Java. This means that they can be declared and assigned a value before the variables are used for the first time, otherwise, the compiler throws an error.
No, they're not equivalent. Default values are assigned immediately, on object instantiation. The assignment in field initializers happens when the superclass constructor has been called... which means you can see a difference in some cases. Sample code:
class Superclass {
public Superclass() {
someMethod();
}
void someMethod() {}
}
class Subclass extends Superclass {
private int explicit = 0;
private int implicit;
public Subclass() {
System.out.println("explicit: " + explicit);
System.out.println("implicit: " + implicit);
}
@Override void someMethod() {
explicit = 5;
implicit = 5;
}
}
public class Test {
public static void main(String[] args) {
new Subclass();
}
}
Output:
explicit: 0
implicit: 5
Here you can see that the explicit field initialization "reset" the value of explicit
back to 0 after the Superclass
constructor finished but before the subclass constructor body executed. The value of implicit
still has the value assigned within the polymorphic call to someMethod
from the Superclass
constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With