I'm asking how can the value of a final field can be changed by native code.
It works the same way any other bit of native code changes a fields value. Modifications to a final
variable are detected at compile time, by the compiler. There are no runtime checks for it aside from explicit checks initiated by a call to Field.set()
. At no point is any runtime memory protection or anything else involved, and even if it was, it would be done by the JVM, not the operating system. Native code doesn't have to care about meta data on fields, it can just set bytes in memory. It's fully outside the scope of the Java compiler's compile time checks.
Native code modifications to final
fields may not even be visible throughout the entire program because of optimizations the compiler is allowed to perform on final
fields. That's what that nullPrintStream()
bit was about pre Java 7.