我的程序里面没有import任何类,用了System.out.println();正常运行。查了相关文档,说程序默认import java.lang.* ,而out是java.lang.System这个类下面的一个静态成员变量,被定义成PrintStream类型,而我的程序没有import java.io.PrintStream这个类,它怎么会正常运行java.io.PrintStream.println()这个方法的呢?JDK附带的System.java相关代码是:
public final static PrintStream out = nullPrintStream();  private static PrintStream nullPrintStream() throws NullPointerException {
if (currentTimeMillis() > 0)
    return null;
throw new NullPointerException();
    }
java.io.PrintStream.java里面:  public void println() {
newLine();
    }我不明白的是
nullPrintStream();只是返回一个null值。public final static PrintStream out = nullPrintStream();这里没有实例化PrintStream对象,怎么外部就可以直接调用PrintStream对象里面的println()方法呢?小弟愚,请指教,千万别骂我没好好看书,呵呵。

解决方案 »

  1.   

    /**
         * 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().
         */
    存在下列两个方法,是因为in,out,err必须初始化为null。然而不允许编译器直接存取它们,因为以后initializeSystemClass()给它们设置更sensible的值。    private static InputStream nullInputStream() throws NullPointerException {
    if (currentTimeMillis() > 0)
        return null;
    throw new NullPointerException();
        }    private static PrintStream nullPrintStream() throws NullPointerException {
    if (currentTimeMillis() > 0)
        return null;
    throw new NullPointerException();
        }     /**
         * Initialize the system class.  Called after thread initialization.
         */
    初始化System类。在线程初始化之后调用。    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));
             ......
    ......
        }
        
        private static native void setIn0(InputStream in);
        private static native void setOut0(PrintStream out);
        private static native void setErr0(PrintStream err);上面三个方法都是native的,应该是由虚拟机实现的。猜想这三个方法会将in,out,err设置成具体的、与操作系统有关的标准输入、标准输出、标准错误对象。我也不知道是不是这么回事,瞎猜吧。
      

  2.   

    我想它应该是实现了一个PrintStream对象,才有可能调用到那个println()方法,在哪实现我也不知道,也许是你那样的。如果有相关的资料说明是怎么实现的就好了。谢谢你。
      

  3.   

    而我的程序没有import java.io.PrintStream这个类,它怎么会正常运行java.io.PrintStream.println()这个方法的呢?
    --------------------------------------------------------------------
    System类中应该已经导入了PrintStream类
      

  4.   

    我查到的资料好像只说系统帮我们自动import java.lang.*;但没有说import java.io.*;
      

  5.   

    虽然在你的程序里没有import java.io.*;但是Systam.java里有:
    ......
    import java.io.*;
    import java.util.Properties;
    import java.util.PropertyPermission;
    import java.util.StringTokenizer;
    import java.security.AccessController;
    import java.security.PrivilegedAction;
    import java.security.AllPermission;
    import java.nio.channels.Channel;
    import java.nio.channels.spi.SelectorProvider;
    import sun.net.InetAddressCachePolicy;
    import sun.reflect.Reflection;
    import sun.security.util.SecurityConstants;
    import sun.reflect.annotation.AnnotationType;
    ......
    ......
      

  6.   

    你的意思是:我的程序自动import java.lang.*;而java.lang.System
    又import java.io.*;那我的程序也自然import java.io.*;是这个意思吗?
      

  7.   

    /*
    你的意思是:我的程序自动import java.lang.*;而java.lang.System
    又import java.io.*;那我的程序也自然import java.io.*;是这个意思吗?
    */
    晕,程序还分你的我的?
      

  8.   

    当然是你的程序自动import java.lang.*;而java.lang.System
    又import java.io.*;所以你就可以放心使用了,至于你使用到out对象,它是怎么调用别的类的,那是它的事情,你只要调用它就行了
    java的原则就是如此,否则的话你如果引入别的类的时候,还要把那个类引用的包导入,如此岂不是
    形成了循环,要导入无穷无尽的包,呵呵