Setter methods for final fields

前端 未结 3 2047
悲哀的现实
悲哀的现实 2020-12-30 22:54

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.la

相关标签:
3条回答
  • 2020-12-30 23:24

    in the source code, they are not reassigning for example out variable in the setOut() method

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

    they send the passed stream to native code, and that code is responsible to set that stream for current use. So final variable is not being re-set and this variable is not used in native code, whatever stream it passes to native code , it uses that

    0 讨论(0)
  • 2020-12-30 23:25

    final makes Java Compiler ensure that no code tries to change the field except initialization. In java.lang.System it is different

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

    private static native void setOut0(PrintStream out);

    From the point of view of javac there is no violation.

    0 讨论(0)
  • 2020-12-30 23:27

    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.

    0 讨论(0)
提交回复
热议问题