OK, notwithstanding the confusing English, it appears that the problem here is "how come System.out
, which is supposedly final
as per the Java sources, can be modified via .setOut()
".
Well, "all bets are out" here; If you look at the System
's .set{Out,In,Err}()
methods, at least in Oracle's JDK, you will see that ultimately they call these methods:
// emphases mine
private static **native** void setIn0(InputStream in);
private static **native** void setOut0(PrintStream out);
private static **native** void setErr0(PrintStream err);
Native code will do "whatever it wants" in order to achieve its goals; it won't care about such a "petty" thing that is "final" in the Java language. In this case, these methods have the special privilege of modifying std{in,out,err} under the scene without even the process running the JVM noticing.
Short story: magic. Long story: well, those methods work so just use them, and don't heed the final
; it is only there so that your code cannot reassign System.{out,in,err}
and you have to go through the dedicated methods instead.
Mind you, any calls to .set{In,Out,Err}()
will first entail a check against the current security manager, if any; this means you can prevent these methods from acting at all if the need arises.