Java Streams   «Prev  Next»

Lesson 4System.out
ObjectiveExplore why and how System.out is special.

System.out is a static member of the System class

In classic Java 1.1, System.out is a static member of the System class that represents the standard output stream. It is an instance of the PrintStream class, which is a subclass of OutputStream. By default, System.out is connected to the console or the standard output device, typically the terminal or command prompt. System.out is commonly used for printing text to the console for debugging or informational purposes. For example, to print a message to the console in Java, you would use the System.out.println() method:
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

In this example, System.out.println() is used to print the message "Hello, world!" followed by a newline character to the console. It is important to note that while System.out is useful for basic output and debugging purposes, it is not the most efficient or robust solution for logging in larger applications. For more advanced logging and output management, consider using dedicated logging frameworks like Log4j or SLF4J.

System.err Print Stream

System.err is also a print stream and instead of being hooked up to stdout, it is connected to stderr. Both stdout and stderr are Unixisms for the console (generally the terminal window in which the program was started) that crept into C, and through C into other platforms like DOS and the Mac. Most of the time System.err and System.out amount to the same thing. However it is possible to redirect one to a file or pipe without redirecting the other. You can also redirect both to the same or different locations.

Many common misconceptions about I/O occur because the first exposure to I/O by most programmers is through the console. The console is convenient for quick hacks and toy examples commonly found in textbooks, but it is really a very unusual source of input and destination for output, and good Java programs avoid it. It behaves almost, but not completely, unlike anything else you would want to read from or write to. While consoles make convenient examples in programming texts like this one, they are a horrible user interface and really have little place in modern programs. Users are more comfortable with a well-defined (GUI) graphical user interface. Furthermore, the console is unreliable across platforms. The Mac, for example, has no native console and Mac Runtime for Java 2 and earlier has a console window that works only for output, but not for input; that is, System.out works but System.in does not.

java.lang.System

System.out and System.err are public final static fields in the java.lang.System class. They refer to instances of the PrintStream class, which is normally connected to the console, though some operating systems allow you to redirect it to a file or pipe.
System.out is primarily used for simple, character-mode applications and for debugging. Its most important reason for existence is convenience, not robustness. Sun has made System.out very easy to use by allowing it to ignore many issues involved in internationalization and error checking. This makes System.out easy to use in quick and dirty hacks and simple examples while simultaneously making it unsuitable for production code.
The PrintStream class has print() and println() methods that handle each and every Java data type.

PrintStream methods

The PrintStream class has
  1. print() and
  2. println()
methods that handle each and every Java data type.

Predefined Streams

As you know, all Java programs automatically import the java.lang package. This package defines a class called System, which encapsulates several aspects of the runtime environment.
For example, using some of its methods, you can obtain the current time and the settings of various properties associated with the system. System also contains three predefined stream variables:
  1. in,
  2. out, and
  3. err.

These fields are declared as
  1. public,
  2. static, and
  3. final
within System

This means that they can be used by any other part of your program and without reference to a specific System object. System.out refers to the standard output stream. By default, this is the console. System.in refers to standard input, which is the keyboard by default. System.err refers to the standard error stream, which also is the console by default. However, these streams may be redirected to any compatible I/O device.
System.in is an object of type InputStream; System.out and System.err are objects of type PrintStream.
These are byte streams, even though they are typically used to read and write characters from and to the console. As you will see, you can wrap these within character-based streams, if desired. The preceding chapters have been using System.out in their examples. You can use System.err in much the same way. As explained in the next section, use of System.in is a little more complicated.

public void print()
public void println()

public void print(boolean b)
public void println(boolean b)

public void print(char c)
public void println(char c)

public void print(int i)
public void println(int i)

public void print(long l)
public void println(long l)

public void print(float f)
public void println(float f)

public void print(double d)
public void println(double d)

public void print(char[] c)
public void println(char[] c)

public void print(String s)
public void println(String s)

public void print(Object obj)
public void println(Object obj)



Anything at all can be passed to a print() method, and it is guaranteed to match at least one of these methods. Object types are converted to strings by invoking their toString() method. Primitive types are converted with the appropriate String.valueOf() method.

overloading + Sign | Combinations of Values

Combinations of values are converted to strings and concatenated.
One aspect of making System.out simple for quick jobs is not in the PrintStream class at all, but rather in the compiler. By overloading the + sign to allow for concatenation of strings with each other, with primitive data types, and with objects, you can pass anything at all to the print() and println() methods. Consider the following line:

System.out.println("As of " + (new Date()) +
  " and there have been over " + hits +
  " hits on the Web site." );

The compiler is responsible for rewriting this complicated expression in the following fashion:
StringBuffer sb = new StringBuffer();
sb.append("As of ");
Date d = new Date();
sb.append(d);
sb.append(" and there have been over ");
sb.append(hits);
sb.append(" hits on the Web site.")
String s = sb.toString();
System.out.println(s);
The StringBuffer append() method is overloaded in much the same way that the print() and println() methods are so it can handle any Java data type or constant.

StringBuffer append() method overloaded in Java

In Java, the StringBuffer class provides an append() method that is overloaded to accept various data types, allowing you to append different types of data to the StringBuffer. Here is a list of overloaded append() methods in the StringBuffer class:
  1. StringBuffer append(boolean b): Appends the string representation of the boolean argument.
  2. StringBuffer append(char c): Appends the specified character.
  3. StringBuffer append(char[] str): Appends the string representation of the character array argument.
  4. StringBuffer append(char[] str, int offset, int len): Appends the string representation of a subarray of the character array argument, starting at the given offset and spanning len characters.
  5. StringBuffer append(CharSequence s): Appends the specified character sequence.
  6. StringBuffer append(CharSequence s, int start, int end): Appends a subsequence of the specified character sequence, starting at the given start index and ending at the given end index.
  7. StringBuffer append(double d): Appends the string representation of the double argument.
  8. StringBuffer append(float f): Appends the string representation of the float argument.
  9. StringBuffer append(int i): Appends the string representation of the int argument.
  10. StringBuffer append(long lng): Appends the string representation of the long argument.
  11. StringBuffer append(Object obj): Appends the string representation of the Object argument.
  12. StringBuffer append(String str): Appends the specified string.

These overloaded append() methods allow you to append various data types to a StringBuffer object. The methods return the same StringBuffer instance, enabling you to chain multiple append() calls together:
StringBuffer sb = new StringBuffer();
sb.append("Hello, ").append("world!").append(' ').append(2022);
String result = sb.toString(); // "Hello, world! 2022"

Keep in mind that StringBuilder is an alternative to StringBuffer that provides similar functionality but is not synchronized, making it faster and more suitable for single-threaded scenarios.

The print() and println() methods differ only in that println() prints a platform-specific line terminator after printing its arguments and print() does not.
PrintStream methods never throw IOExceptions. Each method in the class catches IOExceptions. When an exception occurs an internal flag is set to true. You test this flag with the checkError() method.

System

The System class holds a collection of static methods and variables. The standard input, output, and error output of the Java run time are stored in the in, out, and err variables. Many of the methods throw a SecurityException if the operation is not permitted by the security manager.