我在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”变量。
答案 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);
答案 2 :(得分:1)
getter
对象有setter
和out
。
答案 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()
中的其他内容,但使用本机代码可以修改最终变量。