不知道大家看了System类的源码没有,有个问题始终不懂,还望大家能提点下!public final static InputStream in = nullInputStream();
private static InputStream nullInputStream() throws NullPointerException {
if (currentTimeMillis() > 0) {
    return null;
}
throw new NullPointerException();
}当调用System的静态属性或方法时会初始化里面所有的属性,其中in对象是由静态方法nullInputStream()初始化的,可我不知道这个方法到底启什么作用?in对象到底是怎么初始化的,难道是通过调用native的方法获得的?

解决方案 »

  1.   

    是通过native方法初始化的。
    实际上,从java代码中可以跟踪出来,java代码是将System.in初始化为null了。因为in是final的,java语言级别是不能修改的,所以只能通过native方法重新绑定到系统输入。
      

  2.   

    《JAVA2核心技术》,小字内容对这个有介绍,2l大虾正解。
      

  3.   


    http://zhidao.baidu.com/question/38660871.html
    建议看下,应该就会明白了,谢谢楼主的问题哦
    System类里有大量的native方法,是调用本地代码的,这些代码很可能是由虚拟机来调用的.  
    System类的开头有一段:  
    static {  
    registerNatives();  
    }  
    这段代码会在虚拟机启动的时候就执行,它在虚拟机里注册System需要使用的一些本地代码  
    比如:  
    private static native Properties initProperties(Properties props);  
    private static native void setOut0(PrintStream out);  
    在windows下的话,它就告诉虚拟机到哪个dll文件里去找相应的实现  >然而,我知道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);  
    ~~~~~~~  
    这是个native函数,是前面registerNatives()的时候注册了的.这个函数应该是把实际连接到输入输出设备的句柄传给虚拟机并赋值给in,out,err