In Java, System.out.println() is a statement that is used to print the arguments passed to it to the standard output, typically a console window.
Let us understand System.out.println in Java in detail:
System is a predefined final class present in the java.lang package. It is automatically imported in every Java program, we are not required to import it explicitly.
Can we create the object of the System class?
No, we cannot create the object of the System class. As we can see in the above picture (at line 113), it has a private constructor to restrict its initialization. This is the reason all the elements of the system class are static in nature.
out is an instance variable of PrintStream that is present as a static member variable of the System class.
As it is a static member variable, that’s why we call it using the class name and dot (.) operator as System.out, as shown in Fig-1.
println() is a method of the PrintStream class; that’s why we are able to call it using the out variable, which is of the PrintStream type.
println() is an overloaded method of the PrintStream class.
This is how System.out.println() works internally in Java.
How can we call the println() method on the PrintStream instance variable that is initialized as null, without giving the NullPointerException?
This is a very important interview question. As we see in above picture, the PrintStream instance variable out is initialized as null. How can we call the println() method on an object that is referenced to null without causing the NullPointerException?
The instance variable out is initialised internally by JVM. When the system class loads in memory, all of its static members are loaded, and it calls the setOut(PrintStream out) method, which takes an instance of PrintStream. i.e., out. This setOut(PrintStream out) method further calls the setOut0(PrintStream out) method and passes the out as an argument to it.
In the above picture, we can see that the setOut() method is calling the setOut0() method. If we look at the declaration of setOut0(), we can find that it is a native method.
As we can see above, the methods are written with native keywords. And these methods are written in the C language, which is present in the System.c file. These methods are called by the Java JNI (Java Native Interface) and initialize the out instance. We can see the implementation of these native methods in the Java Official Documentations.
This native method initializes the instance variable; that’s why we do not get a NullPointerException when calling the println() method.