如果我有以下代码:
public class Test {
private int x = 5;
private static int y = 5;
public Test() {
x = 10;
y = 10;
}
}
我想知道在两种情况下它实际上最初会分配5,然后用10更新它,换句话说,没有必要初始化变量内联和构造函数,因为它实际上有初始化变量两次的效果?或者在x(作为实例字段)的情况下,它只是用x = 10替换x = 5,因此只运行x = 10?
了解反编译版本会很高兴。
答案 0 :(得分:2)
我想知道在两种情况下它实际上最初会分配5,然后用10
更新它
是。构造函数将:
super()
。这在JLS #12.5-6。
中有更详细的说明答案 1 :(得分:0)
编译器不会进行这样的优化 - 实际上没有必要进行这样的微优化(你可以确保使用javap
)。
此外,语言规范规定这些值按某种顺序分配。这些步骤在逻辑上应该是不合并的不同步骤。
答案 2 :(得分:-1)
简单流程是:
1.父类初始化
2.静态字段和静态部分按源文件中出现的顺序初始化
3.字段初始化和实例部分按源文件中出现的顺序初始化
4.构造函数执行
示例:
public class TestClass {
private int a = 5;
{
a = 10;
}
private static int b = 10;
static {
b = 15;
}
public TestClass() {
System.out.println(a + ", " + b);
a = 20;
b = 30;
System.out.println(a + ", " + b);
}
public static void main(String args[]) {
TestClass t = new TestClass();
}
}
输出:
10, 15
20, 30
答案 3 :(得分:-1)
当JVM加载类时,它实际上加载Test.class并为静态变量(如y)分配内存。任何成员变量(如x)只会在构造对象时初始化,如new Test();
答案 4 :(得分:-2)
使用类似赋值语句声明变量时,该值将成为变量的默认值。如果您不更改它,它将始终返回该值。如果您确实覆盖了默认值,它将返回新的值