Java 构造函数与内联字段初始化
Java constructor vs inline field initialisation
如果我有以下代码:
public class Test {
private int x = 5;
private static int y = 5;
public Test() {
x = 10;
y = 10;
}
}
我想知道在这两种情况下它实际上是否会最初分配 5,然后用 10 更新它,换句话说,初始化一个内联变量和在构造函数中没有意义,因为它实际上具有初始化一个变量的效果变量两次?或者在 x(作为实例字段)的情况下,它只是将 x = 5 替换为 x = 10,因此甚至只有 运行 x = 10?
知道反编译版本就好了
当您使用这样的赋值语句声明变量时,该值将成为该变量的默认值。如果您不更改它,它将始终 return 该值。如果您覆盖默认值,它将 return 改为
I'm wondering in both cases will it actually initially assign 5, and then update this with 10
是的。构造函数将:
- 呼叫
super()
.
- 执行任何内联初始化和匿名初始化块。
- 执行构造函数的剩余主体。
这在 JLS #12.5-6 中有更详细的说明。
编译器不会进行此类优化 - 实际上进行此类微优化毫无意义(您可以确保使用 javap
)。
此外,语言规范规定这些值按某种顺序分配。而且这些步骤在逻辑上应该是不同的步骤,没有合并。
简单的流程是:
1.父class初始化
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
当JVM加载class时,它实际上加载Test.class并为静态变量如y分配内存。任何成员变量,例如 x 只会在构造对象时初始化,例如 new Test();
如果我有以下代码:
public class Test {
private int x = 5;
private static int y = 5;
public Test() {
x = 10;
y = 10;
}
}
我想知道在这两种情况下它实际上是否会最初分配 5,然后用 10 更新它,换句话说,初始化一个内联变量和在构造函数中没有意义,因为它实际上具有初始化一个变量的效果变量两次?或者在 x(作为实例字段)的情况下,它只是将 x = 5 替换为 x = 10,因此甚至只有 运行 x = 10?
知道反编译版本就好了
当您使用这样的赋值语句声明变量时,该值将成为该变量的默认值。如果您不更改它,它将始终 return 该值。如果您覆盖默认值,它将 return 改为
I'm wondering in both cases will it actually initially assign 5, and then update this with 10
是的。构造函数将:
- 呼叫
super()
. - 执行任何内联初始化和匿名初始化块。
- 执行构造函数的剩余主体。
这在 JLS #12.5-6 中有更详细的说明。
编译器不会进行此类优化 - 实际上进行此类微优化毫无意义(您可以确保使用 javap
)。
此外,语言规范规定这些值按某种顺序分配。而且这些步骤在逻辑上应该是不同的步骤,没有合并。
简单的流程是:
1.父class初始化
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
当JVM加载class时,它实际上加载Test.class并为静态变量如y分配内存。任何成员变量,例如 x 只会在构造对象时初始化,例如 new Test();