System.out se declara como estático final e inicializado con nulo?

Cuando estaba pasando por System.class , encontré algo que me pareció extraño. Cuando System.in, System.out, System.err statement de System.in, System.out, System.err estas se clasifican como final static pero también se inicializan con null

 public final static InputStream in = null; public final static PrintStream out = null; public final static PrintStream err = null; 

Como final se puede inicializar una vez, ¿cómo se gestiona?
Cuando usamos System.out.print("..."); Es obvio que out no es null sino que es un final static ¿cómo no es null ?

Entonces, ¿alguien puede explicar cómo se inicializó que ya se declaró final?

Se inicializa con código nativo en un inicializador estático. En la parte superior de System.java tienes:

 /* register the natives via the static initializer. * * VM will invoke the initializeSystemClass method to complete * the initialization for this class separated from clinit. * Note that to use properties set by the VM, see the constraints * described in the initializeSystemClass method. */ private static native void registerNatives(); static { registerNatives(); } 

El método registerNatives() inicializará in / out / err, y lo hace en código nativo. El código nativo puede hacer prácticamente lo que quiera y no está limitado a todas las reglas del lenguaje java. (Aunque podría moverse configurando un campo final ya inicializado en Java a través de la reflexión también)

Como final, solo se puede inicializar una vez, ¿cómo se gestiona?

Si bien puede cambiar static final variable static final través de la reflexión, en este caso los campos se cambian a través de métodos nativos.

De java.lang.System

 public static void setIn(InputStream in) { checkIO(); setIn0(in); } // same for setOut(), setErr() private static native void setIn0(InputStream in); private static native void setOut0(PrintStream out); private static native void setErr0(PrintStream err); 

Cuando usamos System.out.print (“…”); Es obvio que out no es nulo, sino que es un static final, ¿cómo no es nulo?

Se establece antes de que tenga la oportunidad de usarlo.

¿Te preguntas por qué hace esto? La respuesta casi seguramente está relacionada con las clases de orden que se cargan. Muchas de las clases se inician en orden pero deben inicializarse en una orden que funcione.

Entonces, ¿alguien puede explicar cómo se inicializó que ya se declaró final?

Esto se debe a que el final no es tan definitivo como podrías pensar. Se ha sugerido que necesitamos una final final .