当我浏览 System.class
时,我发现了一些我觉得很奇怪的东西。当您查看 System.in、System.out、System.err
的声明时,它们被标记为 final static
但也用 null
public final static InputStream in = null;
public final static PrintStream out = null;
public final static PrintStream err = null;
既然 final
只能初始化一次,那么如何管理它们呢?
当我们使用 System.out.print("...");
时很明显 out
不是 null
而是一个 final static
它怎么不是 null
?
那么谁能解释一下已经声明为 final 的 out 是如何初始化的?
它在静态初始化器中使用 native 代码进行初始化。
在 System.java 的顶部,您有:
/* register the natives via the static initializer.
*
* VM will invoke the initializeSystemClass method to complete
* the initialization for this class separated from clinit.
* Note that to use properties set by the VM, see the constraints
* described in the initializeSystemClass method.
*/
private static native void registerNatives();
static {
registerNatives();
}
registerNatives()
方法将初始化 in/out/err - 它在 native 代码中这样做 - native 代码几乎可以做任何它想做的事情并且不限于所有 java 语言规则。 (尽管您也可以通过反射在 Java 中设置一个已经初始化的 final 字段)