10

我在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 初始化的代码变量,并且该变量是最终变量,因此无法进一步初始化,那么我们如何使用“out”变量。

4

4 回答 4

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 的变量。

于 2013-08-01T08:55:22.327 回答
7

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);

有一篇不错的文章

于 2013-08-01T08:54:19.237 回答
1

有一个getterandsetter对象out

于 2013-08-01T08:57:54.753 回答
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()但使用本机代码可以修改最终变量。

于 2017-08-27T03:39:22.830 回答