System.Out.Println

This is one the frequently asked question in Java interview, today I will try to explain the inside code of this statement.

System.out.println is simply defined as : calling println() method of PrintStream class whose object out is initialized in System class.

Lets first understand what System.out is and what exactly it do.

There is a class System.java in which System.out is declared, where out is the object of PrintStream class:


public final static PrintStream out = nullPrintStream();	


Below is the code for nullPrintStream():


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


So as shown is above code nullPrintStream() simply returning null or throws an exception, but actually it does not.

Here is the explanation:
When System class get initialized, it calls initializeSystemClass() method:


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:


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.

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.

Now lets discuss what is a FileDescriptor? As you already see below line of code:


FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);			


A FileOutputStream object is created using input value as FileDescriptor.out.

The FileDescriptor class not belongs to java.io directory because FileDescriptor is much lower level than most of the Java standard library. While most .java files are platform independent, there are actually different implementations of FileDescriptor for different platforms.

A FileDescriptor object holds is an integer. The constructor of FileDescriptor takes an integer and creates a FileDescriptor containing that integer. and which is used to initialize a FileOutputStream object.

Here is the code of FileDescriptor.out:


public static final FileDescriptor out = new FileDescriptor(1);			


Now let’s discuss how println() is defined in class PrintStream.java which is a higher level class, it used to write different kinds of data, flushing and handling errors.


public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}			


Following the call stack to print():


public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}			


Going deeper, and look at write() method:


private void write(String s) {
    try {
        synchronized (this) {
        ensureOpen();
        textOut.write(s);
        textOut.flushBuffer();
        charOut.flushBuffer();
        if (autoFlush && (s.indexOf('\n') >= 0))
            out.flush();
        }
    }
    catch (InterruptedIOException x) {
        Thread.currentThread().interrupt();
    }    
    catch (IOException x) {
        trouble = true;
    }
}			


Internally, the PrintStream object (System.out) contains three different objects:

  • charOut – The OutputStreamWriter object used to write character arrays into a stream.
  • textOut – The BufferedWriter object used to write character arrays as well as strings and text array.
  • out – A BufferedOutputStream object passed all the way down the call stack and used much lower than at the PrintStream level.

Here PrintStream.write() calls BufferedWriter.write() which is actually defined in the abstract class Writer.java:


public void write(String str) throws IOException {
    write(str, 0, str.length());
}
public void write(String s, int off, int len) throws IOException {
    synchronized (lock) {
        ensureOpen();
        int b = off, t = off + len;
        while (b < t) { 
            int d = min(nChars - nextChar, t - b); 
            s.getChars(b, b + d, cb, nextChar); 
            b += d; 
            nextChar += d; 
            if (nextChar >= nChars)
                flushBuffer();
        }
    }
}			


Data is stored in a data buffer until it’s written all at once, or flushed. Buffered IO is much faster than simply writing to the hardware one byte at a time.

Dynamic method dispatch in Java & Selenium

About Author

Myself KarthiQ, I am the author of this blog, I know ways to write a good article but some how I donot have the skills to make it to reach people, would you like help me to reach more people By sharing this Article in the social media.

Share this Article Facebook
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions

Recent Addition

new tutorial Selenium Online Training : Our next online training course for Selenium with Java starts from 17th December 2018.

You can attend first 3 classes for free, the total course fee is INR 10,000

The course time would be 8.00 PM(IST) for the first three classes

If you are interested to learn, then you can join the course by sending email to chercher.tech@gmail.com

or Register below


 
Join My Facebook Group
Join Group