gpt4 book ai didi

java - 当对象的所有字段都设置为默认值时,为什么实例常量有值?

转载 作者:行者123 更新时间:2023-12-01 14:13:02 26 4
gpt4 key购买 nike

代码如下:

public class Main {
public static void main(String[] args) {
new B();
}
}

class A {
A() {
System.out.println("A constructor before");
action();
System.out.println("A constructor after");
}

protected void action() {
System.out.println("Never called");
}
}

class B extends A {
private final int finalField = 42;
private int field = 99;

B() {
System.out.println("B constructor");
action();
}

public void action() {
System.out.println("B action, finalField=" + finalField + ", field=" + field);
}
}

结果是:

A constructor before
B action, finalField=42, field=0
A constructor after
B constructor
B action, finalField=42, field=99

我被这一行弄糊涂了:

B action, finalField=42, field=0

对象 B 未完全初始化,当我们从父类(super class)构造函数调用方法“action”时 - 变量“field”具有默认值,但最终变量“finalField”已经具有值 42。

“finalField”是什么时候初始化的?

最佳答案

当一个 final 字段被初始化为 constant expression (15.29) , 它被称为 constant variable (4.12.4) :

private final int finalField = 42;

这意味着字符串

"B action, finalField=" + finalField + ", field="

本身是一个常量表达式,它的值是在编译时确定的。如果您检查已编译的类文件,您实际上会在常量池部分找到字符串 B action, finalField=42, field=

一般来说,当一个字段是一个常量变量时​​,它必须在编译时被它的值替换。是not allowed (13.1)在运行时引用字段:

  1. A reference to a field that is a constant variable (§4.12.4) must be resolved at compile time to the value V denoted by the constant variable's initializer.

    If such a field is non-static, then no reference to the field should be present in the code in a binary file, except in the class containing the field. (It will be a class rather than an interface, since an interface has only static fields.) The class should have code to set the field's value to V during instance creation (§12.5).

字段初始值设定项仍按您预期的方式运行:在 A 构造函数返回之后和 B 构造函数启动之前。观察未初始化的值很棘手,因为编译器内联变量的使用,但您可以通过反射访问字段的值:

public void action() {
try {
System.out.println("B action, finalField="
+ getClass().getDeclaredField("finalField").get(this)
+ ", field=" + field);
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}

输出:

A constructor before
B action, finalField=0, field=0
A constructor after
B constructor
B action, finalField=42, field=99

关于java - 当对象的所有字段都设置为默认值时,为什么实例常量有值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63436203/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com