JDK 14及更高版本中Java系统类中静态final字段的初始化

问题描述 投票:0回答:1

在检查 JDK 14 及更高版本中

System
类的初始化时,很明显,标准输入/输出流是通过调用
registerNatives()
方法来设置的,该方法是从静态初始化块调用的,并且本身是本机的。然而,引人注目的是变量
out
in
err
被定义为
static
final
。由于
final
,这些字段需要使用常量值进行显式初始化。最初,它们在班级内设置为
null

考虑到它们的初始化可能由本机方法处理,对

null
的显式赋值不会简单地从代码中消失,从逻辑上讲,这部分代码也应该执行。此外,如果我们假设整个过程发生在
<clinit>
方法的幕后,则本机方法将首先完成,然后是分配
null
的字段初始值设定项(例如,查看
out
字段) 。如何有效地覆盖
null
,以及实际的初始化发生在哪里?

此外,如果我们深入研究注释,就会发现该类的初始化在某种程度上与

<clinit>
的常规执行是分开的:

    /* Register the natives via the static initializer.
     *
     * The VM will invoke the initPhase1 method to complete the initialization
     * of this class separate from <clinit>.
     */
    private static native void registerNatives();
    static {
        registerNatives();
    }

什么是

initPhase1
?这个阶段会发生什么?它到底意味着什么?我实在是太好奇了!提前感谢大家!

java initialization native system
1个回答
0
投票

在检查 JDK 14 及更高版本中

System
类的初始化时,很明显,标准输入/输出流是通过调用
registerNatives()
方法来设置的,[...]

不,这些不是从

registerNatives()
初始化的。它们在
initPhase1()
方法中初始化,这是一个常规 Java 方法(在
System
类中),在初始化
System
类之后(即在这些字段被设置为
null
)。

initPhase1()
的调用是在名为
initialize_java_lang_classes
的 C++ 方法中完成的。

© www.soinside.com 2019 - 2024. All rights reserved.