对这个东西很感到奇怪,System是io包中的一个类,而in是它的一个静态字段,下面就不懂了,System.in是什么,是一个InputStream类?还是一个InputStream类的实例?如果是InputStream类的实例,那么System.in使用的抽象方法public abstract int read() throws IOException在System.in中重新定义了吗?如果定义了,在API文档中那里能找到?

解决方案 »

  1.   

    再问一下,一个类和一个字段(System.in)组合到一起怎么又能成为一个类或类的实例对象呢?
      

  2.   

    比如你的键盘输入  对吧? Java将它作为一个流读进去  这就是in
      

  3.   

    它实际使用的是BufferedInputStream类型,可以去看System类的源代码
      

  4.   

    我想知道的是public abstract int read() throws IOException作为抽象类InputStream的抽象方法,怎么就能用这个不知道是啥东西的System.in的调用。另外谢谢ZangXT的多次解答,但是Src中System的源代码好像也找不到答案呀,希望得到进一步的详细解答。
      

  5.   

    没进过任何包装的一个InputStream。
    建议多理解下JAVA I/O的“Decorator”模式
      

  6.   

    我觉得应该看下定义吧
    public static final InputStream in“标准”输入流。
    此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。System.in是 InputStream 的实例,而不是继承InputStream的类,为什么要重新定义呢?怎么重新定义啊?
      

  7.   

    我觉得应该看下定义吧
    public static final InputStream in“标准”输入流。
    此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。System.in是 InputStream 的实例,而不是继承InputStream的类,为什么要重新定义呢?怎么重新定义啊?
      

  8.   

    很多人知道System.out是什么
    却有的人不知道System.in是什么
      

  9.   

    public final static InputStream in = nullInputStream();
    这是in的定义.
    然后去看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 初始化为null了.
    然后实际运行时是通过initializeSystemClass()来初始化的.
    再看
     private static void initializeSystemClass() {
    的代码,里面有
    setIn0(new BufferedInputStream(fdIn));
    这个setIn0就是让
    in = new  BufferedInputStream(fdIn);
    不过这是有c语言来实现的,因为in是final的,你不能通过java来改变它.到这就应该清楚了,in变量实际指向了 BufferedInputStream类型的对象.具体的read方法就去 BufferedInputStream的代码里找吧.
      

  10.   

    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 
      

  11.   

    System.in是一个InputStream类型的变量,指向了BufferedInputStream类型的对象.
    BufferedInputStream继承FilterInputStream,FilterInputStream继承InputStream
      

  12.   

    System 类包含一些有用的类字段和方法。它不能被实例化。 在 System 类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。
    err “标准”错误输出流。
    in  “标准”输入流
    out “标准”输出流。
      

  13.   

    System.in.read;
     去理解一下这个东西!!