PrintStream对象out由null初始化,我们如何调用方法呢?

时间:2013-08-01 08:49:37

标签: java printstream

我在System类中看到out对象(类型PrintStream)初始化为null值。我们如何调用System.out.prinln("");之类的方法? 在System class out变量中,这样初始化:

package java.lang;

public final class System {
    public final static PrintStream out = nullPrintStream();

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

如上所示,代码out变量由null初始化,并且此变量是final,因此无法进一步初始化,我们如何使用“out”变量。

4 个答案:

答案 0 :(得分:8)

解释在评论中:

/**
 * The following two methods exist because in, out, and err must be
 * initialized to null.  The compiler, however, cannot be permitted to
 * inline access to them, since they are later set to more sensible values
 * by initializeSystemClass().
 */

initializeSystemClass()使用本机方法将标准流初始化为非空值。本机代码可以重新初始化声明为final的变量。

答案 1 :(得分:6)

JVM调用初始化它的private static void initializeSystemClass()方法。

请参阅以下两行代码:

setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));

这是两种原生方法:

private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);

nice article on it

答案 2 :(得分:1)

getter对象有setterout

答案 3 :(得分:0)

当System类初始化时,它会调用initializeSystemClass()方法,这里是代码:

FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));

在此代码中,setOut0()是在System.c中实现的本机函数:

JNIEXPORT void JNICALL
Java_java_lang_System_setOut0(JNIEnv *env, jclass cla, jobject stream)
{
    jfieldID fid =
        (*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");
    if (fid == 0)
        return;
    (*env)->SetStaticObjectField(env,cla,fid,stream);
}

这是一个标准的JNI代码,它将System.out设置为传递给它的参数,此方法调用本机方法setOut0(),将out变量设置为适当的值。

System.out是最终的,这意味着它不能设置为initializeSystemClass()中的其他内容,但使用本机代码可以修改最终变量。