默认变量的值与初始化的默认值 [英] Default variables' values vs initialization with default
问题描述
我们都知道,根据 JLS7 p .4.12.5 每个实例变量都使用默认值进行初始化。例如。 (1):
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
}
但我一直认为,这样的类实现(2 ):
But I always thought, that such class implementation (2):
public class Test {
private Integer a = null;
private int b = 0;
private boolean c = false;
}
绝对等于示例(1)。我预计,复杂的Java编译器会发现(2)中的所有这些初始化值都是多余的并且省略了它们。
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.
例如(1):
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
例如(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:我使用Java 7 1.7.0.11 x64,没有特殊的javac选项
UPD: I use Java 7 1.7.0.11 x64, no special javac options
推荐答案
不,它们不等同。在对象实例化时,默认值立即。当调用超类构造函数时,字段初始值设定项中的赋值发生...这意味着可以在某些情况下看到差异。示例代码:
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();
}
}
输出:
explicit: 0
implicit: 5
在这里你可以看到显式字段初始化重置显式
的值在超类$ c $之后回到0 c>构造函数已完成但在子类构造函数 body 执行之前。
隐式
的值仍然具有在超类的
构造函数。 someMethod
的多态调用中指定的值
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.
这篇关于默认变量的值与初始化的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!