Java Standard Streams: System.in, System.out and System.err - Quiz
Total: 5 questions
1. What are the standard streams in Java: System.in, System.out and System.err?
What are the standard streams in Java: System.in, System.out and System.err?
They are three ready-made streams that the JVM creates when the program starts and stores in the public static final fields of the java.lang.System class. The java.lang package is imported automatically, so the streams are available without import and without creating any objects.
System.inis standard input, of typeInputStream(a byte stream), OS descriptor 0, the keyboard by default.System.outis standard output, of typePrintStream, descriptor 1, the terminal screen by default.System.erris the standard error stream, also aPrintStream, descriptor 2, the terminal screen by default.
The link to the terminal is not fixed: the shell can redirect any of the streams to a file (<, >, 2>), and the program can replace them with System.setIn(), setOut() and setErr().
2. How does System.err differ from System.out, and when should you use it?
How does System.err differ from System.out, and when should you use it?
Both fields are PrintStream objects with the same methods (print(), println(), printf()). The difference is the OS channel: System.out writes to standard output (descriptor 1), System.err to the standard error stream (descriptor 2).
- Errors can be separated from useful output: with
java App > out.txtnormal output goes to the file, whileSystem.errmessages stay on the screen;2> err.txtsends errors to a separate file, and> all.txt 2>&1puts both streams into one file. - The no-argument
e.printStackTrace()writes toSystem.err, which is why stack traces are shown in red in an IDE. - Because these are two independent channels,
outanderrlines can come out in the wrong order in an IDE console; if the order matters, write to one stream.
Real applications use a logger (java.util.logging, SLF4J with Logback) instead of printing to System.err directly.
3. Why does System.in.read() return 53 when the user types 5, and how do you read a number from the console correctly?
Why does System.in.read() return 53 when the user types 5, and how do you read a number from the console correctly?
System.in is a byte stream (InputStream). The method read() returns one byte as an int from 0 to 255, or -1 at the end of input. 53 is the code of the character '5', and the next call returns 10 (the line break from Enter; on Windows 13 comes first). The call blocks the program until the user presses Enter.
To read a number, read a line and parse it:
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(console.readLine().trim());
InputStreamReaderturns bytes into characters,BufferedReaderaddsreadLine().- Non-numeric input throws
NumberFormatException; at the end of input (Ctrl+Don Linux/macOS,Ctrl+Zand Enter on Windows)readLine()returnsnull. - Do not close the wrapper around
System.in: closing it also closesSystem.initself, and it cannot be reopened.
4. How do you redirect the standard streams from inside a program with System.setIn(), System.setOut() and System.setErr()?
How do you redirect the standard streams from inside a program with System.setIn(), System.setOut() and System.setErr()?
The static methods System.setIn(InputStream), setOut(PrintStream) and setErr(PrintStream) replace the standard streams: after the call, all code that writes to System.out or reads from System.in works with the new stream, such as a file or an in-memory buffer.
setIn(new ByteArrayInputStream("42\n".getBytes()))feeds prepared input to code in a test.setOut(new PrintStream(buffer, true))with aByteArrayOutputStreamcaptures the output of a method that prints its result instead of returning it.setErr(...)collects error messages and stack traces in a log file.
The fields in, out and err are declared final, so System.out = ... does not compile; the setXxx() methods change them through native JVM code. Save the original stream and restore it in a finally block; otherwise all later output of the program and of other tests goes into a foreign stream.
5. Why does System.out.println() never throw IOException, and why can it slow a program down in big loops?
Why does System.out.println() never throw IOException, and why can it slow a program down in big loops?
The PrintStream methods (print(), println(), printf()) do not throw IOException: a write error only sets an internal flag. The only way to learn about a failure is to call checkError(), which flushes the buffer and returns true if an error occurred. That is why, for example, after System.out.close() all further output silently disappears.
The JVM creates System.out with automatic flushing (autoflush): text appears in the console right after println(), with no flush() call. The flip side is that every call goes to the OS, and the PrintStream methods are also synchronized, so a million println() calls can take seconds. For large output, collect the text in a StringBuilder and print it once, or write through new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))) with a single flush() at the end.