[英]PrintStream object out is initialized by null, how we call method on it?
I have seen in the System
class that the out
object (of type PrintStream
) is initialized with a null
value. 我已经在
System
类中看到out
对象(类型为PrintStream
)用null
值初始化。 How can we call method like System.out.prinln("");
我们如何调用类似
System.out.prinln("");
? ? In System class out variable initialized like this way:
在System类中,以这种方式初始化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();
}
}
As per shown above code out
variable initialized by null and this variable is final, so it can not initialized further then how can we use "out" variable. 如上所示,代码
out
变量由null初始化,并且此变量是最终变量,因此无法进一步初始化,那么我们如何使用“ out”变量。
The explanation is in the comments: 注释中有解释:
/**
* 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().
*/
And initializeSystemClass()
uses native methods to initialize the standard streams to non-null values. initializeSystemClass()
使用本机方法将标准流初始化为非空值。 Native code can reinitialize variables that are declared final. 本机代码可以重新初始化声明为final的变量。
JVM calls the private static void initializeSystemClass()
method which initializes it. JVM调用
private static void initializeSystemClass()
方法对其进行初始化。
See these two lines of code : 参见这两行代码:
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
These are the two native methods : 这是两种本机方法:
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);
There is a nice article on it . 上面有一篇不错的文章 。
有一个getter
和setter
的out
对象。
When System class get initialized, it calls its initializeSystemClass()
method, here is the code: 初始化System类时,它将调用其
initializeSystemClass()
方法,下面是代码:
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
In this code setOut0() is a native function implemented in System.c: 在此代码中,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);
}
This is a standard JNI code that sets System.out
to the argument passed to it, this method calls the native method setOut0()
which sets the out variable to the appropriate value. 这是一个标准的JNI代码,将
System.out
设置为传递给它的参数,该方法调用本地方法setOut0()
,该方法将out变量设置为适当的值。
System.out is final, it means it cannot be set to something else in initializeSystemClass()
but using native code it is possible to modify a final variable. System.out是最终的,这意味着无法在
initializeSystemClass()
中将其设置为其他值,但是使用本机代码可以修改最终变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.