« Day of Mourning | Main | Don't trivialize rights »

Java 'final' trivia--the answer

In last week's episode, I asked which class has a static final member variable that you can change at will.

Give up?

(Spoiler follows...)

java.lang.System.

It actually has three of them. in, out, and err are all defined static final, yet you can change them at any time with the calls setIn(), setOut(), and setErr().

No, I haven't the foggiest idea why Sun did that. I found it in the paperwork for JSR 133: Java Memory Model. That spec redefines Java's memory model, and defines what a final variable is and how it's treated. It actually has to special-case those three variables. To quote it (ยง9.2 of the current draft 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.

Surely someone must have thought they had Good Reason for this. Any ideas?

Comments

Good reason for special-casing them? They didn't have a choice there -- code depends on the variables being changeable. As for good reason for making them static final in the first place, well, they probably screwed up and couldn't really change them after the fact. :)

Post a comment