Skip to content

Java中真正的Hello World

我们都知道如何在Java中写Hello World,但是...

· 2 min ·

真正的”Hello World” 我们都知道如何在Java中写Hello World,但当我们深入探究 System类的实现时,它应该是怎样的呢?

System.out.println("Hello World!");

VM会调用initPhase1方法来完成此类的初始化,与clinit分离。

java.lang.System
public final class System {
private static native void registerNatives();
static {
registerNatives();
}
}

我们跳转到initPhase1,它创建一个PrintStream对象,然后触发setOut0(PrintStream out)方法。

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在VM与终端关联时设置,
// 因此它们等同于Console.charset(),否则这些属性的编码
// 默认为native.encoding
setOut0(newPrintStream(fdOut, props.getProperty("stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("stderr.encoding")));
// ...
}

setOut0是一个本地方法,但newPrintStream返回一个PrintStream,它有println()方法,这足以让我们理解发生了什么。

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()打印到新行,并且由于synchronized关键字具有多线程安全性。

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();
}
}
}
}

最后,setOut0PrintStream放入System的类变量中,即System.out

public static final PrintStream out = null;

就这样,我们可以通过这样写来让HelloWorld更复杂:

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!");
}
}

太酷了~