static void test04() throws FileNotFoundException {
/* FileOutputStream(FileDescriptor fdObj)
创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。*/
//将系统的输出流设置为标准输出流 FileDescriptor.out 系统的输出流
//系统的println(是同步的方法)
System.setOut(new PrintStream(new FileOutputStream("d:/test/outout.txt"),false));
System.out.println("出去拉");
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out),false));
System.out.println("haha系统输出");
}
有几个问题
1、System类加载之后out对象是怎么设置为FileDescriptor.out的
2、为什么对于final对象 可以调用static void setOut(PrintStream out) 修改
native 底层是怎么样的
由于java是支持多线程的,所以标准的输入输出是共享,因此它们必须受到特别的处理,在系统初始化完成之前,线程严禁使用这几个特殊对象;又因为这些对象都是静态的,因此java的类加载机制会在System类加载的时候就会初始化,这就造成了一对矛盾;为解决这对矛盾,System在加载是将它们初始化为null,等加在完成后,通过native方法在对它们进行赋值:
在线程初始化完成后,系统会调用方法initializeSystemClass设置这几个特殊对象的值:
......
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
......