关于System.in(out、err)的一点疑问

来源:互联网 发布:淘宝哪些店铺女装好看 编辑:程序博客网 时间:2024/05/16 17:41

问题:

     System.in被定义如下:

     public final static InputStream in=nullInputStream();

     System中nullInputStream()代码如下:

     private static InputStream nullInputStream() throws NullPointerException

     {
          if (currentTimeMillis() > 0)

          {
                return null;
          }
          throw new NullPointerException();
     }

     要么返回错误,要么返回null,怎么能够使用InputStream类中的方法呢?何况read()是抽象方法。

     (out和err大致同上)

答:

     System类里有大量的native方法,是调用本地代码的,这些代码很可能是由虚拟机来调用的。

     System类的开头有一段:
     static

     {
          registerNatives();
     }

     这段代码会在虚拟机启动的时候就执行,它在虚拟机里注册System需要使用的一些本地代码。

     也就说in初始化为null,然后会在后来由initializeSystemClass()方法类初始化成有意义的值。

     private static void initializeSystemClass()

     {

          props = new Properties();

          initProperties(props);
          sun.misc.Version.init();

          // Workaround until DownloadManager initialization is revisited.
          // Make JavaLangAccess available early enough for internal
          // Shutdown hooks to be registered
          setJavaLangAccess();

          // Gets and removes system properties that configure the Integer
          // cache used to support the object identity semantics of autoboxing.
          // At this time, the size of the cache may be controlled by the
          // vm option -XX:AutoBoxCacheMax=<size>.
          Integer.getAndRemoveCacheProperties();

          // 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");

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

          // Setup Java signal handlers for HUP, TERM, and INT (where available).
          Terminator.setup();

          // Initialize any miscellenous operating system settings that need to be
          // set for the class libraries. Currently this is no-op everywhere except
          // for Windows where the process-wide error mode is set before the java.io
          // classes are used.
          sun.misc.VM.initializeOSEnvironment();

          // Set the maximum amount of direct memory.  This value is controlled
          // by the vm option -XX:MaxDirectMemorySize=<size>.  This method acts
          // as an initializer only if it is called before sun.misc.VM.booted().
          sun.misc.VM.maxDirectMemory();

          // Set a boolean to determine whether ClassLoader.loadClass accepts
          // array syntax.  This value is controlled by the system property
          // "sun.lang.ClassLoader.allowArraySyntax".  This method acts as
          // an initializer only if it is called before sun.misc.VM.booted().
          sun.misc.VM.allowArraySyntax();

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

          // The main thread is not added to its thread group in the same
          // way as other threads; we must do it ourselves here.
          Thread current = Thread.currentThread();
          current.getThreadGroup().add(current);

     }

     in就是在以上方法中下面语句里初始化的:

     setIn0(new BufferedInputStream(fdIn));
     System中有:

     private static native void setIn0(InputStream in);

     前面registerNatives()的时候注册了。这个函数是应该把实际连接到输入输出设备的句柄传给虚拟机并赋值给in。

     (out、err同上) 

原创粉丝点击