2017-07-02 26 views
-1

我不明白我们如何能够,例如,重定向/调用System.setOut(PrintStream的输出)复位的System.out,当系统。出被宣布为最终?重定向标准流在Java中

放样(PrintStream的出)假想重新分配的System.out参数的值出,鉴于System.out的是最终应是不可能的。

关于这是怎么回事的任何解释?

+0

我只是希望那些对我的问题投了反对票的人发表评论,并告诉我为什么这样......只是为了帮助我避免将来的问题出现任何陷阱/误用。谢谢。 – Searcherer

回答

1

这怎么可能?

setOut被实现为

public static void setOut(PrintStream out) { 
    checkIO(); 
    setOut0(out); 
} 

setOut0是在天然系统(JVM)等能够改变系统的最后字段中实现的方法,包括:

private static native void setOut0(PrintStream out); 

注意:它是也可以通过反射来改变最后的字段 - 例如改变的值不变字符串字面值

+0

我不明白..你能解释一下吗?谢谢。 – Searcherer

+1

系统正在调用一个系统函数(本地库),这是一个在虚拟机中实现的函数 - 这可以做几乎任何事情(关于正在运行的java程序)。 –

3

输入/输出/错误字段不需要更改。

他们可能只是围绕另一个流。那些包装的流具有默认行为 - 并且在调用这些设置器方法时,只需替换该“interal”流即可。

像:System.out使用“internal.out” - 并使用setter你可以改变internal.out为user.out为例(只是把这些名字作为例子)。

+0

我想到了,但是这并不意味着它会继续无限期地继续,因为传递给setOut()的参数具有相同类型(PrintStream),因为每个PrintStream包装另一个PrintStream? – Searcherer

+1

也值得一提的是,'setOut'正在调用一个本地方法,因此它能够在场景后面执行很多* maigc *,包括更改最后一个(空)字段:'public final static PrintStream out = null;' –

+1

@Searcher我没有得到那个评论。用另一个流替换“内部”流。这里没有递归。你知道他们在那里的俄罗斯“木偶”里面总是有另一个更小的吗?在这里它是不同的:只有两个木偶......你可以更换内部,外部保持相同。 – GhostCat