>然而,我知道out是一个PrintStream的对象,但我查看了有关的原代码:public final static PrintStream out = nullPrintStream(); >public final static InputStream in = nullInputStream(); 在nullInputStream()方法里有注释解释为什么会设置为空:
/** * The following two methods exist because in, out, and err must be * initialized to null. The compiler, however, cannot be permitted to * inline access to them, since they are later set to more sensible values * by initializeSystemClass(). */ private static InputStream nullInputStream() throws NullPointerException { if (currentTimeMillis() > 0) return null; throw new NullPointerException(); } 也就说in, out, and err 初始化为null,然后会在后来由initializeSystemClass()方法类初始化成有意义的值 /** * Initialize the system class. Called after thread initialization. */ private static void initializeSystemClass() { props = new Properties(); initProperties(props); sun.misc.Version.init(); FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); setIn0(new BufferedInputStream(fdIn)); !!! setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); !!! setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); !!!
// Enough of the world is now in place that we can risk // initializing the logging configuration. try { java.util.logging.LogManager.getLogManager().readConfiguration(); } catch (Exception ex) { // System.err.println("Can′t read logging configuration:"); // ex.printStackTrace(); }
// Load the zip library now in order to keep java.util.zip.ZipFile // from trying to use itself to load this library later. loadLibrary("zip");
// Subsystems that are invoked during initialization can invoke // sun.misc.VM.isBooted() in order to avoid doing things that should // wait until the application class loader has been set up. sun.misc.VM.booted(); } in,out,err就是在以上方法以下三条语句里初始化的. setIn0(new BufferedInputStream(fdIn)); !!! setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); !!! setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); !!! 看 private static native void setIn0(InputStream in);