简体   繁体   English

在System.out.println()中

[英]out in System.out.println()

Firstly regrets if this is a very basic question and i promote that I'm still a code monkey. 首先感到遗憾的是,如果这是一个非常基本的问题,我建议我仍然是代码猴子。 I was asked in an interview to elucidate System.out.println(); 我在一次采访中被要求阐明System.out.println(); I explained the following way 我解释了以下方式

//this class belongs to java.lang package
class System{
  public static PrintStream out;
}
//this class belongs to java.io package
class PrintStream{
 public void println..
}

I've explained that System.out is valid since this is the way we access static variables in java, and out is an object of PrintStream and hence we can access its methods, In sum as 我已经解释说System.out是有效的,因为这是我们在java中访问静态变量的方式,而out是PrintStream的对象,因此我们可以访问其方法,总之为

System.out.pritnln(); 

he asked me to simulate a similar kind of program,i traced and it did not work,since System.out is returning null 他要求我模拟类似的程序,但我跟踪了它,但是它没有用,因为System.out返回null

my question is where is out object instantiated in java ? 我的问题是在Java中实例化的对象在哪里? Is it a predefined object if I'm not wrong. 如果我没看错,它是预定义的对象吗? what should be the meticulous explanation for this. 为此应该进行细致的解释。

Technically what should we call out? 从技术上讲,我们应该喊什么? Is out a variable of type PrintStream type or should one say it as an object of type PrintStream ? 是类型为PrintStream的变量还是应该说它为类型为PrintStream的对象?

System.out is initialized to null when the class is instantiated. 实例化类时,System.out初始化为null This is set by the nullPrintStream() method in System.java , which just returns null . 这是由设置nullPrintStream()在方法System.java ,这只是返回null

When the JVM has initialized, it calls the initializeSystemClass() method. JVM初始化后,将调用initializeSystemClass()方法。 This method calls the native method setOut0() which sets the out variable to the appropriate value. 此方法调用本native方法setOut0() ,该方法将out变量设置为适当的值。

This may seem weird but it is a necessary operation for the following reasons: 这看起来很奇怪,但是由于以下原因,它是必需的操作:

  • out cannot be set statically to the value because System needs to be one of the first loaded classes (before PrintStream ). out不能静态设置为该值,因为System需要是第一个加载的类之一(在PrintStream之前)。
  • out must be final so that its value cannot be directly overridden by a user. out必须是final以便用户不能直接覆盖其值。
  • Since out cannot be set statically, and is final, we must override the semantics of the language using a native method, setOut0() . 由于out不能静态设置,并且是最终的,因此我们必须使用native方法setOut0()覆盖语言的语义。

I hope that helps your understanding. 希望对您有所帮助。

System.out is a normal static attribute, it was set by the JVM through the initializeSystemClass() method during JVM initialization. System.out是正常的静态属性,它是JVM在JVM初始化期间通过initializeSystemClass()方法设置的。 You can even change it (although it's not recommended) by simply calling System.setOut(printOutStream); 您甚至可以通过简单地调用System.setOut(printOutStream);更改它(尽管不建议这样做System.setOut(printOutStream); , where printOutStream is the stream you want to use as standard output. ,其中printOutStream是要用作标准输出的流。

Here's a nice article detailing how does System.out.println() work. 这是一篇很好的文章,详细介绍了System.out.println()的工作方式。

Out in System.out.pritln is a static field (object) of PrintWriter in System class and println is a method of PrintWriter. System.out.pritln中的Out是System类中PrintWriter的静态字段(对象),而println是PrintWriter的方法。

Reference : System : http://docs.oracle.com/javase/6/docs/api/java/lang/System.html PrintWriter : http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html 参考:系统: http : //docs.oracle.com/javase/6/docs/api/java/lang/System.html PrintWriter: http : //docs.oracle.com/javase/6/docs/api/java /io/PrintWriter.html

There is no need to go for net and documentation even. 甚至不需要网络和文档。 We can simply say javap java.lang.System this gives you list of all static fields, method prototypes that belong to System class. 我们可以简单地说javap java.lang.System,它为您提供了所有静态字段的列表,这些列表属于System类。 We can get details of any java class using javap, provided you know its package and classname out is public static object of PrintStream defined in System class. 我们可以使用javap获取任何java类的详细信息,只要您知道它的包和类名是System类中定义的PrintStream的公共静态对象即可。

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()中将其设置为其他值,但是使用本机代码可以修改最终变量。

System.out is provided by the JVM. System.out由JVM提供。 By the time your main method is called, System.out is open and ready for use. 在您的主要方法被调用时,System.out已打开并可以使用。

See http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#out 参见http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#out

In the Oracle Java runtime libraries, it is instantiated natively using the registerNatives() native method which is called (via a static initializer) on loading the System class. 在Oracle Java运行时库中,它是使用registerNatives()本机方法本地化的,该方法在加载System类时被调用(通过static初始化程序)。 This is however an implementation detail. 但是,这是一个实现细节。

You can also set System.out directly using System.setOut() . 您也可以直接使用System.setOut()设置System.out

System.out.println(); 的System.out.println();

here println is an object of printstream class.We can't directly create object for printstream class. 这里的println是printstream类的对象。我们不能直接为printstream类创建对象。 Out is an object of system class. Out是系统类的对象。 out is called field in system class. out在系统类中称为字段。 while calling system.out it indirectly creates object for printstream class. 在调用system.out时,它间接为printstream类创建对象。 hence we can call println() method using System.out.prontln(). 因此我们可以使用System.out.prontln()调用println()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM