JLS 17.5.4 Schreibgeschützte Felder :
Normalerweise dürfen die endgültigen statischen Felder nicht geändert werden. Allerdings System.in
, System.out
und System.err
sind endgültig statische Felder, die für Legacy - Gründen erlaubt werden muss durch die Verfahren geändert werden System.setIn
, System.setOut
und System.setErr
. Wir bezeichnen diese Felder als schreibgeschützt , um sie von normalen Endfeldern zu unterscheiden.
Der Compiler muss diese Felder anders behandeln als andere endgültige Felder. Zum Beispiel ist ein Lesevorgang eines gewöhnlichen Endfelds "immun" gegen Synchronisation: Die Barriere, die an einer Sperre oder einem flüchtigen Lesevorgang beteiligt ist, muss keinen Einfluss darauf haben, welcher Wert aus einem Endfeld gelesen wird. Da sich der Wert schreibgeschützter Felder möglicherweise ändert, sollten sich Synchronisationsereignisse auf sie auswirken. Daher schreibt die Semantik vor, dass diese Felder als normale Felder behandelt werden, die nicht durch Benutzercode geändert werden können, es sei denn, dieser Benutzercode befindet sich in der System
Klasse.
Übrigens können Sie final
Felder durch Reflektion mutieren , indem Sie sie aufrufen setAccessible(true)
(oder Unsafe
Methoden verwenden). Solche Techniken werden während der Deserialisierung, von Hibernate und anderen Frameworks usw. verwendet, haben jedoch eine Einschränkung: Code, der den Wert des letzten Felds vor der Änderung gesehen hat, kann den neuen Wert nach der Änderung nicht garantiert sehen. Das Besondere an den betreffenden Feldern ist, dass sie von dieser Einschränkung frei sind, da sie vom Compiler auf besondere Weise behandelt werden.