And*_*niy 18 java bytecode compiler-optimization
我们都知道,根据JLS7第4.12.5节,每个实例变量都使用默认值进行初始化.例如(1):
public class Test {
private Integer a; // == null
private int b; // == 0
private boolean c; // == false
}
Run Code Online (Sandbox Code Playgroud)
但我一直认为,这样的类实现(2):
public class Test {
private Integer a = null;
private int b = 0;
private boolean c = false;
}
Run Code Online (Sandbox Code Playgroud)
绝对等于例子(1).我预计,复杂的Java编译器会发现(2)中的所有这些初始化值都是冗余的并且省略了它们.
但突然之间,这两个类我们有两个不同的字节码.
例如(1):
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
Run Code Online (Sandbox Code Playgroud)
例如(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
Run Code Online (Sandbox Code Playgroud)
问题是:为什么?但这是显而易见的优化事项.什么原因?
UPD:我使用Java 7 1.7.0.11 x64,没有特殊的javac选项
Jon*_*eet 25
不,他们不相同.在对象实例化时立即分配默认值.字段初始值设定项中的赋值发生在调用超类构造函数时...这意味着在某些情况下可以看到差异.示例代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
explicit: 0
implicit: 5
Run Code Online (Sandbox Code Playgroud)
在这里你可以看到显式字段初始化"重置" explicit了Superclass构造函数完成后但在子类构造函数体执行之前返回0 的值.值的值implicit仍然具有someMethod在Superclass构造函数的多态调用中指定的值.
| 归档时间: |
|
| 查看次数: |
907 次 |
| 最近记录: |