Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
176 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...