您现在的位置是:首页 > 文章详情

System.out.println

日期:2019-08-09点击:456

from: https://javapapers.com/core-java/system-out-println/

System.out.println

This Java tutorial is to explain what System.out.println is and how it works. It is love at first type. How many times have we used System.out.println till now? It is one of the most number of times compiled statement in the history of java. We shortly call it SOP.

What is System.out.println

System.out.println is a Java statement that prints the argument passed, into the System.out which is generally stdout.

  • System - is a final class in java.lang package. As per javadoc, "...Among the facilities provided by the System class 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.
  • println - is a method of PrintStream class. 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 print method and adds a newline. print calls write() and the story goes on like that.

Structure of System.out.println

Following is the skeletal structure of System.out.println in the JDK source. Through this code snippet the essential parts are highlighted and its given for better understanding.

public final class System { public final static PrintStream out; public final static PrintStream err; public final static InputStream in; } public class PrintStream extends FilterOutputStream { public void println() { //TODO } }

Change out of System.out.println

'out' 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 printed in the same command window. We can change that behavior using setOut method as below. In the following example, I have redirected the output to a text file in the same directory.

public class ChangeOut { public static void main(String args[]) { try { System.setOut(new PrintStream(new FileOutputStream("log.txt"))); System.out.println("Now the output is redirected!"); } catch(Exception e) {} } }

System.out.println vs loggers like Log4j

Log4j has multiple 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, we should be aware that a logging component should be used and System.out.println should be avoided. Why?

  • Flexibility: a logger like log4j provides different levels for logging. We can separate the log messages accordingly. For example, X messages should be printed only on PRODUCTION, Y messages should be printed on ERROR, etc.
  • Reconfigurability: in just one parameter change we can switch off all the logging statements.
  • Maintainability: imagine if we have hundreds of System.out.println 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 output 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. 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.

System.out.println and Performance

There is a general notion that System.out.println are bad for 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 synchronized block. 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 System.out.println 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 System.out.println()

Sometimes we feel System.out.println is a long statement to print. 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.

import static java.lang.System.out; public class ShortSOP { public static void main(String[] args) { out.println("Hello, world"); } }

System.err and System.in

As 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 difference in ouput between 'out' and 'err'.

public class InOutErr { public static void main(String args[]) { try { BufferedReader reader = new BufferedReader(System.in); String filename = reader.readLine(); InputStream input = new FileInputStream(filename); System.out.println("File opened..."); } catch (IOException e){ System.err.println("Where is that file?"); } } }
原文链接:https://yq.aliyun.com/articles/713593
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章