如何更改System.out的值?

gpa*_*ani 1 java constants system.out

在查看java.lang.System类的实现时,我发现:

public final static PrintStream out = null;
Run Code Online (Sandbox Code Playgroud)

仅从这个定义,我可以说,价值System.out永远是null.但是,它在程序启动时初始化(使用System.initializeSystemClass()JVM自动调用的方法),并且我可以使用System.setOut执行安全检查的值来更改其值,然后将调用委托给setOut0方法,该native方法是更改​​值的方法的System.out.为什么我可以改变它的值,System.out即使它被声明了final

chr*_*ke- 6

这是API中的历史疣.JLS实际上是特殊情况System.{in,out,err},如果今天设计API,可能会有不同的声明.

这种奇怪的行为在实践中通过忽略Java的定义来实现System.System是核心类之一(沿Runtime,Object,该系统ClassLoader是一个Java程序的界面到JVM外面的环境,和其他几个人).为了执行它们的任务,它们必须由JRE提供(大部分)本机代码,在这种情况下,实际的C代码System只是忽略了Java API声明字段的事实final.

  • 基本上,`final`字段可以定义为"无法修改的字段(除非通过反射(除非安全管理器阻止它))(除了`System.in/out/err`,只能通过`System.setIn/setOut/setErr`).边缘情况通常被掩盖,因此定义变得更直观"无法修改的字段". (2认同)
  • @yshavit系统流的例外直到Java 7才在JLS中实现,所以在此之前,流设置器的存在在技术上违反了规范,而不是"final"定义中的异常! (2认同)