Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java System.setIn()重新指定final System.in_Java - Fatal编程技术网

Java System.setIn()重新指定final System.in

Java System.setIn()重新指定final System.in,java,Java,可能重复: 虽然我做了很多次都没有注意到,但我突然想到:System.setIn()正在重新分配static finalSystem.in 我错过什么了吗?如何重新分配最终字段。通常,最终静态字段不能修改。但是System.in、System.out和System.err是最终的静态字段,由于遗留原因,必须允许通过System.setIn、System.setOut和System.setErr方法更改这些字段。我们将这些字段称为写保护字段,以区别于普通的最终字段 编译器需要将这些字段与其他最终

可能重复:

虽然我做了很多次都没有注意到,但我突然想到:
System.setIn()
正在重新分配static final
System.in


我错过什么了吗?如何重新分配最终字段。

通常,最终静态字段不能修改。但是
System.in
System.out
System.err
最终的静态字段,由于遗留原因,必须允许通过
System.setIn
System.setOut
System.setErr
方法更改这些字段。我们将这些字段称为写保护字段,以区别于普通的最终字段

编译器需要将这些字段与其他最终字段区别对待。例如,对普通最终字段的读取对同步“免疫”:锁或易失性读取中涉及的屏障不必影响从最终字段读取的值。由于写保护字段的值可能会发生变化,因此同步事件应该会对其产生影响。因此,语义要求将这些字段视为不能由用户代码更改的普通字段,除非该用户代码位于系统类中


编辑:值得一提的是,您可以通过对最终字段调用setAccessible(true)(或使用不安全的方法)来“黑客”最终字段并设置其值。Hibernate和其他框架等在反序列化过程中使用了这些技术,但它们有一个限制:在修改之前看到final字段值的代码不能保证在修改之后看到新值这3个系统字段的特殊之处在于它们不受此限制,因为编译器以特殊方式对它们进行处理。setIn()和它的朋友setOut()和setErr()都委托给本机方法,没有强制执行Java访问控制规则的地方。

不管是谁做了这件事并浪费了JLS部分[1]来解释,都是愚蠢的

这些字段只需删除
final
修饰符即可。它不会破坏二进制兼容性。[2]

允许用户写入
System.out=x
不是问题;不管怎样,他都能做
系统。出发(x)
。编译器需要特殊处理才能将第一个赋值转换为第二个方法调用。这比当前的方式要好,它扭曲了
System.out
的读写语义

如果我们真的不想看到
System.out=x
,请将其设置为异常,这样编译器就不会编译它

这两种解决方案都是简单的语法材料;没有必要为了这个愚蠢的小东西而破坏Java内存模型

[1]


[2]

@david:老实说,我找了一会儿,但这个问题没有出现,可能是因为它指的是系统。out@dimitrisli-我已更新链接问题的标题,以便更容易找到。。。当这个问题以重复的形式结束时。嗯。。JVM出于遗留原因进行的特殊处理。如果要复制java语言规范的整个部分,那么值得注意的是setAccessible(true)将private/public修饰符更改为public。实际上,您必须进入“修改器”字段并更改修改器。您必须使用反射来获得修改器,然后使用反射来更改修改器,我记得。我已经有一段时间没做了——上一次我不得不破解最后一个字段是几个月前,我只是复制了它。