Using reflection and also from the src.zip available in the installed JDK by the installer purveyed by http://docs.oracle.com, I found the following fields of java.lang.System
,
in, out & err are declared as final, but they have respective (public) setter methods which in turn invoke their respective native couter-part.
For example, I could successfully re-direct console output to a file.
We can set final variables exactly once we have initialized it in the Java code.
My question is : is this rule of final not applicable to the native code?
Being final means it cannot be changed, so you can't do a setter method.
So, a setter is a method that updates the value of a variable. And a getter is a method that reads the value of a variable. Getter and setter are also known as accessor and mutator in Java.
When a field is defined as final , it has to be initialised when the object is constructed, i.e. you're allowed to assign value to it inside a constructor. A static field belongs to the class itself, i.e. one per class. A static final field is therefore not assignable in the constructor which is one per object.
It makes sense to make a getter final if the POJO aimed to be immutable. final modifier will disable sub classes to override that method. You should only use it if you want this design, but it depends.
My question is : is this rule of final not applicable to the native code?
Native code can break the rules on final
. It can also break the access rules and basic type safety, and various other things.
The point about final
fields not actually being immutable is actually recognized in the JLS: see JLS 17.5.3. The gist of this is that if you do change a final
(via reflection for example), certain guarantees no longer hold. And changing the value of a final
that represents a compile time constant is liable to have no effect at all.
But as @ignis points out, System.in/out/err
get special mention in the JLS as being "write-protected" (JLS 17.5.4) rather than having the normal final
semantics. Basically, this means that the final
guarantees do hold even if the variables are changed.
why have the variables to be final when there will be a setter anyways?
In this particular case it is 1) to prevent System.in/out/err
from being clobbered by an accidental assignment, and 2) so that changes can be controlled by the SecurityManager
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With