gpt4 book ai didi

java: "final"System.out、System.in 和 System.err?

转载 作者:IT老高 更新时间:2023-10-28 11:49:45 27 4
gpt4 key购买 nike

System.out被声明为 public static final PrintStream out

但是您可以调用System.setOut()重新分配它。

嗯?如果是 final,这怎么可能?

(同一点适用于 System.inSystem.err)

更重要的是,如果您可以改变公共(public)静态最终字段,那么就 final 给您的保证(如果有)而言,这意味着什么? (我从未意识到也不期望 System.in/out/err 表现为 final 变量)

最佳答案

JLS 17.5.4 Write Protected Fields :

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.

The compiler needs to treat these fields differently from other final fields. For example, a read of an ordinary final field is "immune" to synchronization: the barrier involved in a lock or volatile read does not have to affect what value is read from a final field. Since the value of write-protected fields may be seen to change, synchronization events should have an effect on them. Therefore, the semantics dictate that these fields be treated as normal fields that cannot be changed by user code, unless that user code is in the System class.

顺便说一句,实际上你可以通过反射改变 final 字段,方法是调用 setAccessible(true) (或使用 Unsafe 方法) )。这种技术在反序列化过程中,被 Hibernate 和其他框架等使用,但它们有一个限制:在修改之前已经看到 final 字段值的代码不能保证在修改后看到新值。所讨论的字段的特别之处在于它们不受此限制,因为它们被编译器以特殊方式处理。

关于java: "final"System.out、System.in 和 System.err?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5951464/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com