第一次在论坛提问.  
public static void main(String[] args) throws FileNotFoundException {
PrintStream out = new PrintStream("d:/d.txt");
System.setOut(out); //改变了标准输出流
System.out.println(System.out == out);  // 标记1   文件中打印true
System.out.println("某些数据.");  //这样的话会像上面的文件中写入数据
                    //  问题:   我怎么样才能改回标准输出流呢?   在setOut前没有保存引用.
//  疑惑:   System类的out字段是public static final 的, 为什么可以改变呢?
    //标记1那里居然打印的是true
}

解决方案 »

  1.   

    楼主的问题很有意思。
    问题:   我怎么样才能改回标准输出流呢?   在setOut前没有保存引用.
    那就保存一下就好了嘛!
    PrintStream out = new PrintStream("d:/d.txt");
    PrintStream systemOut = System.out;//先把System.out取出来保存下来
    System.setOut(out);
    System.out.println(System.out == out);
    System.out.println("某些数据.");
    System.setOut(systemOut);//然后再设置回去
    System.out.println("变回来了!");疑惑:System类的out字段是public static final 的, 为什么可以改变呢?
    看了一下System类的源码,估计是它里面的native方法的原因吧!
    具体原因,等高人指点。。
      

  2.   

    很明显, 我的意思就是不保存原来引用的前提下.改回标准输出流..  因为out是个final的属性,应该可以设置回去的,  但就是不可以.
      

  3.   

    在System里的initializeSystemClass方法可以看到如何赋予标准输出流
    你可以这样        FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
            System.setOut(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
            System.out.println("某些数据2.");
    至于为什么out in err这三个属性标记了final还能更改,给你copy java spec里的一段
    Normally, final static fields may not be modified. However System.in, System.out, and System.err are final static fields that, for legacy reasons, must be allowed to be changed by the methods System.setIn, System.setOut and System.setErr. We refer to these fields as being write-protected to distinguish them from ordinary final fields.The compiler needs to treat these fields differently from other final fields. For example, a read of an ordinary final field is "immune" to synchronization: the barrier involved in a lock or volatile read does not have to affect what value is read from a final field. Since the value of write-protected fields may be seen to change, synchronization events should have an effect on them. Therefore, the semantics dictate that these fields be treated as normal fields that cannot be changed by user code, unless that user code is in the System class