In the System.java source, the standard input, output and error streams are declared final and initialized null?

前端 未结 3 1654
梦毁少年i
梦毁少年i 2020-11-29 12:19
public final static InputStream in = null;
public final static PrintStream out = null;
public final static PrintStream err = null;

But as we very w

相关标签:
3条回答
  • 2020-11-29 12:45

    They are later on set by native methods SetIn0, SetOut0 and SetErr0

    private static native void setIn0(InputStream in);
    private static native void setOut0(PrintStream out);
    private static native void setErr0(PrintStream err);
    

    called from the initializeSystemClass method, which according to the JavaDoc is called after thread initialization.

    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));
    
    0 讨论(0)
  • 2020-11-29 12:45

    final fields are not necessarily constant. They can still be manipulated, it's just that manipulation is only prevented at compile-time, specifically by preventing you from using the assignment operator (=). See this question and JLS §17.5.3, specifically:

    final fields can be changed via reflection and other implementation-dependent means.

    This is necessary for things like deserialization. This can also cause some interesting caveats since compilers can optimize final fields on compile-time and run-time. The JLS linked above has an example of this.

    0 讨论(0)
  • 2020-11-29 12:46

    This is done in order to prevent "hacking". These fields can be changed only by appropriate setters that call native methods

    private static native void setIn0(InputStream in);
    private static native void setOut0(PrintStream out);
    private static native void setErr0(PrintStream err);
    

    Native methods can do everything including changing final fields.

    0 讨论(0)
提交回复
热议问题