奇怪的“输出"变量,System.out.println() [英] strange 'out' variable, System.out.println()

查看:12
本文介绍了奇怪的“输出"变量,System.out.println()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是java.lang.System类(JDK 1.6版)的代码

Following is the code from java.lang.System class (JDK version 1.6)

public final static PrintStream out = nullPrintStream(); //out is set to 'null'

private static PrintStream nullPrintStream() throws NullPointerException {
    if (currentTimeMillis() > 0) {
        return null;
    }
    throw new NullPointerException();
}

当我们在代码中编写 System.out.println("Something"); 那么为什么即使 'out' 设置为 'null' 我们也不会得到 NullPointerException

when we write System.out.println("Something"); in our code then why don't we get NullPointerException even when 'out' is set to 'null'

无论如何,out 将通过 System 类中的以下 setOut 方法设置

Anyhow out will be set via following setOut method in System class

public static void setOut(PrintStream out) {
     checkIO();
     setOut0(out);
 }

那为什么 JLS 需要 nullPrintStream 方法?

Theyn why JLS needs nullPrintStream method ?

推荐答案

看看private static void initializeSystemClass() - 这个方法被调用来启动,它调用setOut0() 这是一个 native 方法.这将 Stream 绑定到它应该在的位置.

Take a look at the private static void initializeSystemClass() - this method is called to start things up, it calls setOut0() which is a native method. This ties the Stream into where it's supposed to be.

因此,即使该字段看起来 public static final 实际上不是,native 代码会改变它.

So even though the field may look public static final it actually isn't, the native code changes it.

编辑

OP 问那为什么 JLS 需要 nullPrintStream 方法?

这与 java 编译器有关 - 如果在编译时将 static final 字段分配给某个常量,例如 null,它将内联"static final 字段.编译器实际上会用常量替换对该字段的每个引用.

This is to do with the java compiler - it will "inline" static final fields if they are assigned to something constant at compile time, like null. The compiler will actually replace each reference to the field with the constant.

这会破坏初始化,因为对象将不再持有对 Stream 的引用,而是对 null 的引用.将流分配给方法的返回可防止内联.

This would break the initialisation as objects would no longer hold a reference to the Stream but to null. Assigning the stream to the return of a method prevents the inlining.

有些人可能会称之为肮脏的黑客攻击.错误地引用俾斯麦的话JDK 就像香肠,最好不要看到它被制造出来".

Some might call it a dirty hack. To misquote Bismarck "The JDK is like sausages, it's best not to see it being made".

这篇关于奇怪的“输出"变量,System.out.println()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆