首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇怪的'out‘变量,System.out.println()

奇怪的'out‘变量,System.out.println()
EN

Stack Overflow用户
提问于 2013-03-22 16:41:14
回答 3查看 736关注 0票数 6

下面是来自java.lang.System类的代码(JDK1.6版)

代码语言:javascript
复制
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呢?

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

代码语言:javascript
复制
public static void setOut(PrintStream out) {
     checkIO();
     setOut0(out);
 }

为什么JLS需要nullPrintStream方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-22 16:46:33

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

因此,即使字段看起来像public static final,但实际上不是,native代码会更改它。

编辑

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

这与java编译器有关-如果static final字段在编译时被赋值为某个常量,比如null,它将“内联”这些字段。编译器实际上会将字段的每个引用替换为常量。

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

有些人可能会称它为肮脏的黑客。错误的引用“JDK就像香肠,最好不要看到它被制造出来”。

票数 8
EN

Stack Overflow用户

发布于 2013-03-22 16:42:53

这就是System.out类的初始化方式。

还有一种方法:

代码语言:javascript
复制
 private static native void setOut0(PrintStream out);

在下面的方法中调用:

代码语言:javascript
复制
private static void initializeSystemClass() {
票数 2
EN

Stack Overflow用户

发布于 2013-03-22 16:47:47

System.in、out和err由JVM从本机代码管理。nullPrintStream()的整个魔力就是为了防止javac内联这些字段。从java 7开始,它看起来就像

代码语言:javascript
复制
public final static PrintStream out = null;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15565993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档