Skip to content

Real hello world in java

We all know how to write Hello World in java, but...

· 1 min ·

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.

java.lang.System
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~