Real “Hello World” We all know how to write Hello World in java, but what should it be when we dive into implementation of System class?
System.out.println("Hello World!");The VM will invoke the initPhase1 method to complete the initialization of this class separate from clinit.
public final class System { private static native void registerNatives(); static { registerNatives(); }}We jump to initPhase1, it creates a PrintStream object, then triggers setOut0(PrintStream out) method.
private static void initPhase1() { /// ... FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); initialIn = new BufferedInputStream(fdIn); setIn0(initialIn); // stdout/err.encoding are set when the VM is associated with the terminal, // thus they are equivalent to Console.charset(), otherwise the encodings // of those properties default to native.encoding setOut0(newPrintStream(fdOut, props.getProperty("stdout.encoding"))); setErr0(newPrintStream(fdErr, props.getProperty("stderr.encoding"))); // ...}setOut0 is a native method, but newPrintStream returns a PrintStream, which has the println() method, so that’s clear enough for us to understand what happens.
private static PrintStream newPrintStream(OutputStream out, String enc) { if (enc != null) { return new PrintStream(new BufferedOutputStream(out, 128), true, Charset.forName(enc, UTF_8.INSTANCE)); } return new PrintStream(new BufferedOutputStream(out, 128), true);}println() prints to a new line, and it has multi-thread safety because of synchronized keyword.
public class PrintStream extends FilterOutputStream implements Appendable, Closeable {
public void println(boolean x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { synchronized (this) { print(x); newLine(); } } }}Finally, setOut0 puts the PrintStream to the class variable of System, which is System.out:
public static final PrintStream out = null;That’s it, we can make HelloWorld more complex by writing like:
public class HelloWorld { public static void main(String[] args) { FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); PrintStream out = new PrintStream(new BufferedOutputStream(fdOut, 128), true); out.println("Hello World!"); }}So cool~