What is System.out.printlnSystem.out.println prints the argument passed, into the System.out which is generally stdout.
- System – is a final class and cannot be instantiated. Therefore all its memebers (fields and methods) will be static and we understand that it is an utility class. As per javadoc, “…Among the facilities provided by the
Systemclass are standard input, standard output, and error output streams; access to externally defined properties and environment variables; a means of loading files and libraries; and a utility method for quickly copying a portion of an array…”
- out – is a static member field of System class and is of type PrintStream. Its access specifiers are public final. This gets instantiated during startup and gets mapped with standard output console of the host. This stream is open by itself immediately after its instantiation and ready to accept data. When running a program from windows command line, it is the standard console.
- println – println prints the argument passed to the standard console and a newline. There are multiple println methods with different arguments (overloading). Every println makes a call to
write()and the story goes on like that.
Change out of System.out.println‘out’ object can be customized. out gets initialized by java runtime environment at startup and it can be changed by developer during execution. Instead of standard output, in default cases when you run a program through command line, the output is printing in the same command window. We can change that behavior using
setOutmethod as below. In the following example, I have redirected the output to a text file in the same directory.
System.out.println vs loggers like Log4jLog4J has mulitple levels for logging. If we are writing a real short program, just for experimental/learning purposes SOPs are fine. When we are developing a production quality software project, we should be aware that a professional logger should be used and SOPs should be avoided. Why?
- Flexibility: a professional logger like log4j provides different levels for logging. We can seggregate the log message accordingly. For example, X messages should be printed only on PRODUCTION, Y messages should be printed on ERROR, etc.
- Configurability: in just one parameter change we can switch off all the logging statements.
- Maintainability: imagine if we have hundreds of SOPs littered all through the application, it would be difficult to maintain the program over a period.
- Granularity: In an application, every single class can have a different logger and controlled accordingly.
- Utility: Option for redirecting the message is limited in System.out, but in case of a logger you have appenders which provides numerous options. We can even create a custom ouput option and redirect it to that.
Having said all the above, we still use System.out.println for logging and debugging. Which should be strictly avoided. This is driven by (bad)habit. I want to share how a habit became a convention. In this case its a good habit. Its using ‘i’, ‘j’ as index in for-loop. In FORTRAN language, we need not declare integer variables. Variable names that start with i, j, k, l, m and n are integer variables. So, FORTRAN developers named for-loop index with i,j,k and that habit carried on to other languages. Just a habit and became a good convention!
System.out.println and PerformanceThere is a general notion that SOPs are bad in performance. When we analyze deeply, the sequence of calls are like println -> print -> write() + newLine(). This sequence flow is an implementation of Sun/Oracle JDK. Both write() and newLine() contains a
synchronizedblock. Synchronization has a little overhead, but more than that the cost of adding characters to the buffer and printing is high.
When we run a performance analysis, run multiple number of SOP and record the time, the execution duration increases proportionally. Performance degrades when we print more that 50 characters and print more than 50,000 lines.
It all depends on the scenario we use it. Whatever may be the case, do not use System.out.println for logging to stdout.
Static Import to Shorten SOPSomeone complained that System.out.println is a loooong statement to print something. static import may shorten it a bit but it is not recommended, because it results in poor readability. I am just using this situation to explain static import and avoid using it in the below scenario.
In Eclipse you have programmed shortcuts like ctrl + spac to help you out.
System.err and System.inAs a related section, I wish to discuss about ‘err’ and ‘in’. ‘in’ is associated with InputStream. Opposite to ‘out’, ‘in’ is used to get input from standard console generally keyboard.
‘err’ is associated with PrintStream and prints the argument to the standard error output stream. When you use eclipse kind of IDE you can see the differene in ouput between ‘out’ and ‘err’.